Skip to content

Commit c51f62e

Browse files
committed
feat(scroll in sync): made user tutorial for in sync scroll
1 parent 8577f01 commit c51f62e

File tree

4 files changed

+79
-19
lines changed

4 files changed

+79
-19
lines changed

helpers/isSkipScrollInSyncTutorial.ts

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
export default function () {
2+
const cookies = document.cookie.split(';')
3+
const cookieMap: {
4+
isSkipScrollInSyncTutorial?: string
5+
} = {
6+
isSkipScrollInSyncTutorial: 'false',
7+
}
8+
cookies.forEach((element) => {
9+
const [name, val] = element.split('=')
10+
const trimmedName = name.trim()
11+
if (trimmedName === 'isSkipScrollInSyncTutorial') {
12+
cookieMap[trimmedName] = val
13+
}
14+
})
15+
return cookieMap.isSkipScrollInSyncTutorial === 'true'
16+
}

pages/index.vue

+3-1
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,9 @@ export default Vue.extend({
8989
const driver = new Driver({
9090
closeBtnText: 'Skip',
9191
className: 'dark:filter dark:invert',
92-
stageBackground: this.isDarkMode ? 'hsl(221deg 30% 70%)' : '#ffffff',
92+
stageBackground: this.isDarkMode
93+
? 'hsl(221deg 50% 90% / 0.5)'
94+
: '#ffffff',
9395
onReset: () => {
9496
document.cookie = 'isSkipTutorial=true; max-age=31536000; path=/;'
9597
},

pages/v1/diff.vue

+54-18
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,6 @@
22
<div class="page-contents">
33
<Navbar :show-back-button="true">
44
<template #right>
5-
<div class="inline-flex items-center gap-1">
6-
<label for="toggleScrollInSync" class="select-none"
7-
>Scroll in sync</label
8-
>
9-
<input
10-
id="toggleScrollInSync"
11-
type="checkbox"
12-
:checked="scrollInSync"
13-
class="form-checkbox filter mix-blend-luminosity"
14-
@click="toggleInSyncScroll"
15-
/>
16-
</div>
175
<button
186
type="button"
197
class="inline-flex justify-center px-4 py-2 transition-transform transform rounded-md shadow outline-none copy-uri-button align-center focus:ring-4 active:scale-y-75"
@@ -62,6 +50,26 @@
6250
</template>
6351
</Navbar>
6452
<main>
53+
<section class="flex items-center gap-4 py-4">
54+
<div
55+
class="inline-flex items-center gap-1"
56+
id="toggleScrollInSyncSection"
57+
>
58+
<label
59+
for="toggleScrollInSync"
60+
class="text-gray-800 select-none dark:text-gray-50"
61+
>
62+
Scroll in sync
63+
</label>
64+
<input
65+
id="toggleScrollInSync"
66+
type="checkbox"
67+
:checked="isSrollInSyncEnabled"
68+
class="form-checkbox"
69+
@click="toggleInSyncScroll"
70+
/>
71+
</div>
72+
</section>
6573
<section
6674
class="flex items-stretch w-full gap-4 font-mono text-gray-800 dark:text-gray-50"
6775
>
@@ -72,7 +80,7 @@
7280
<div
7381
class="relative flex-1 px-4 py-2 border-2 rounded-md dark:border-gray-500 line-number-gutter min-h-80"
7482
:class="{
75-
'overflow-y-auto max-h-screen--nav': !scrollInSync,
83+
'overflow-y-auto max-h-screen--nav': !isSrollInSyncEnabled,
7684
}"
7785
>
7886
<RTStickyCopyButton
@@ -97,7 +105,7 @@
97105
<div
98106
class="relative flex-1 px-4 py-2 border-2 rounded-md dark:border-gray-500 line-number-gutter min-h-80"
99107
:class="{
100-
'overflow-y-auto max-h-screen--nav': !scrollInSync,
108+
'overflow-y-auto max-h-screen--nav': !isSrollInSyncEnabled,
101109
}"
102110
>
103111
<RTStickyCopyButton
@@ -133,17 +141,19 @@ export default {
133141
rhsLabel: this.rhsLabel,
134142
lhsLabel: this.lhsLabel,
135143
copied: false,
136-
scrollInSync: this.scrollInSync,
144+
isSrollInSyncEnabled: this.isSrollInSyncEnabled,
145+
isDarkMode: this.$isDarkMode,
146+
isSkipScrollInSyncTutorial: this.$isSkipScrollInSyncTutorial,
137147
}
138148
},
139-
mounted() {
149+
async mounted() {
140150
const _diff = this.$route.hash
141151
const gunzip = pako.ungzip(Buffer.from(undoUrlSafeBase64(_diff), 'base64'))
142152
const diffData = JSON.parse(Buffer.from(gunzip).toString('utf8'))
143153
const { diff, lhsLabel, rhsLabel } = diffData
144154
this.lhsLabel = lhsLabel
145155
this.rhsLabel = rhsLabel
146-
this.scrollInSync = true
156+
this.isSrollInSyncEnabled = true
147157
this.lhsDiff = diff
148158
.map((item) => {
149159
const hunkState = item[0]
@@ -182,6 +192,32 @@ export default {
182192
'--max-line-number-characher',
183193
`${`${maxLineCount}`.split('').length}ch`
184194
)
195+
const { default: Driver } = await import('driver.js')
196+
const driver = new Driver({
197+
// ...driverJSConfig(this.$isDarkMode),
198+
closeBtnText: 'Skip',
199+
className: 'dark:filter dark:invert',
200+
stageBackground: this.isDarkMode
201+
? 'hsl(221deg 50% 90% / 0.5)'
202+
: '#ffffff',
203+
onReset: () => {
204+
document.cookie =
205+
'isSkipScrollInSyncTutorial=true; max-age=31536000; path=/;'
206+
},
207+
})
208+
// Define the steps for introduction
209+
if (!this.isSkipScrollInSyncTutorial) {
210+
driver.defineSteps([
211+
{
212+
element: '#toggleScrollInSyncSection',
213+
popover: {
214+
title: 'Scroll In Sync',
215+
description: 'Now you can choose to scroll both sides in sync.',
216+
},
217+
},
218+
])
219+
driver.start()
220+
}
185221
},
186222
methods: {
187223
putToClipboard(textToPut, toastContent) {
@@ -224,7 +260,7 @@ export default {
224260
)
225261
},
226262
toggleInSyncScroll() {
227-
this.scrollInSync = !this.scrollInSync
263+
this.isSrollInSyncEnabled = !this.isSrollInSyncEnabled
228264
},
229265
},
230266
}

plugins/cookie-injector.client.ts

+6
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
import { Plugin } from '@nuxt/types'
22
import isDarkModeCookie from '~/helpers/isDarkModeCookie'
33
import isSkipTutorialCookie from '~/helpers/isSkipTutorialCookie'
4+
import isSkipScrollInSyncTutorial from '~/helpers/isSkipScrollInSyncTutorial'
45
declare module 'vue/types/vue' {
56
// this.$isDarkModeinside Vue components
67
interface Vue {
78
$isDarkMode: boolean
89
$isSkipTutorial: boolean
10+
$isSkipScrollInSyncTutorial: boolean
911
}
1012
}
1113

@@ -14,11 +16,13 @@ declare module '@nuxt/types' {
1416
interface NuxtAppOptions {
1517
$isDarkMode: boolean
1618
$isSkipTutorial: boolean
19+
$isSkipScrollInSyncTutorial: boolean
1720
}
1821
// nuxtContext.isDarkMode$
1922
interface Context {
2023
$isDarkMode: boolean
2124
$isSkipTutorial: boolean
25+
$isSkipScrollInSyncTutorial: boolean
2226
}
2327
}
2428

@@ -27,12 +31,14 @@ declare module 'vuex/types/index' {
2731
interface Store<S> {
2832
$isDarkMode: boolean | S
2933
$isSkipTutorial: boolean | S
34+
$isSkipScrollInSyncTutorial: boolean | S
3035
}
3136
}
3237

3338
const cookieInjectorPlugin: Plugin = (_context, inject) => {
3439
inject('isDarkMode', isDarkModeCookie())
3540
inject('isSkipTutorial', isSkipTutorialCookie())
41+
inject('isSkipScrollInSyncTutorial', isSkipScrollInSyncTutorial())
3642
}
3743

3844
export default cookieInjectorPlugin

0 commit comments

Comments
 (0)