@slidev/client 0.47.4 → 0.48.0-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/builtin/CodeBlockWrapper.vue +38 -27
- package/builtin/KaTexBlockWrapper.vue +37 -26
- package/builtin/Mermaid.vue +18 -10
- package/builtin/SlidevVideo.vue +4 -7
- package/builtin/VClick.ts +16 -4
- package/builtin/VClickGap.vue +38 -0
- package/builtin/VClicks.ts +44 -47
- package/composables/useClicks.ts +83 -0
- package/composables/useContext.ts +2 -8
- package/composables/useNav.ts +5 -2
- package/constants.ts +2 -5
- package/internals/Editor.vue +1 -1
- package/internals/Presenter.vue +22 -27
- package/internals/PrintSlide.vue +10 -8
- package/internals/PrintSlideClick.vue +7 -16
- package/internals/SlideWrapper.ts +9 -42
- package/internals/SlidesOverview.vue +2 -1
- package/internals/SlidesShow.vue +3 -10
- package/logic/nav.ts +26 -28
- package/logic/note.ts +4 -0
- package/logic/utils.ts +18 -0
- package/modules/context.ts +5 -8
- package/modules/directives.ts +124 -167
- package/package.json +7 -7
- package/routes.ts +2 -1
- package/setup/codemirror.ts +3 -1
- package/setup/root.ts +5 -5
- package/composables/useNavClicks.ts +0 -38
package/modules/directives.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
|
+
import type { ResolvedClicksInfo } from '@slidev/types'
|
|
1
2
|
import type { App, DirectiveBinding, InjectionKey } from 'vue'
|
|
2
|
-
import {
|
|
3
|
-
import { remove } from '@antfu/utils'
|
|
4
|
-
import { isClicksDisabled } from '../logic/nav'
|
|
3
|
+
import { computed, watchEffect } from 'vue'
|
|
5
4
|
import {
|
|
6
5
|
CLASS_VCLICK_CURRENT,
|
|
7
6
|
CLASS_VCLICK_FADE,
|
|
@@ -9,10 +8,7 @@ import {
|
|
|
9
8
|
CLASS_VCLICK_HIDDEN_EXP,
|
|
10
9
|
CLASS_VCLICK_PRIOR,
|
|
11
10
|
CLASS_VCLICK_TARGET,
|
|
12
|
-
|
|
13
|
-
injectionClicksDisabled,
|
|
14
|
-
injectionClicksElements,
|
|
15
|
-
injectionOrderMap,
|
|
11
|
+
injectionClicksContext,
|
|
16
12
|
} from '../constants'
|
|
17
13
|
|
|
18
14
|
function dirInject<T = unknown>(dir: DirectiveBinding<any>, key: InjectionKey<T> | string, defaultValue?: T): T | undefined {
|
|
@@ -27,88 +23,36 @@ export default function createDirectives() {
|
|
|
27
23
|
name: 'v-click',
|
|
28
24
|
|
|
29
25
|
mounted(el: HTMLElement, dir) {
|
|
30
|
-
|
|
26
|
+
const resolved = resolveClick(el, dir)
|
|
27
|
+
if (resolved == null)
|
|
31
28
|
return
|
|
32
29
|
|
|
33
|
-
|
|
34
|
-
return
|
|
35
|
-
|
|
36
|
-
const elements = dirInject(dir, injectionClicksElements)
|
|
37
|
-
const clicks = dirInject(dir, injectionClicks)
|
|
38
|
-
const orderMap = dirInject(dir, injectionOrderMap)
|
|
39
|
-
|
|
40
|
-
const hide = dir.modifiers.hide !== false && dir.modifiers.hide != null
|
|
41
|
-
const fade = dir.modifiers.fade !== false && dir.modifiers.fade != null
|
|
42
|
-
|
|
43
|
-
const CLASS_HIDE = fade ? CLASS_VCLICK_FADE : CLASS_VCLICK_HIDDEN
|
|
44
|
-
|
|
45
|
-
if (elements && !elements?.value?.includes(el))
|
|
46
|
-
elements.value.push(el)
|
|
30
|
+
el.classList.toggle(CLASS_VCLICK_TARGET, true)
|
|
47
31
|
|
|
48
|
-
|
|
32
|
+
// Expose the resolved clicks info to the element to make it easier to understand and debug
|
|
33
|
+
const clicks = Array.isArray(resolved.clicks) ? resolved.clicks : [resolved.clicks, undefined]
|
|
34
|
+
el.dataset.slidevClicksStart = String(clicks[0])
|
|
35
|
+
if (clicks[1] != null)
|
|
36
|
+
el.dataset.slidevClicksEnd = String(clicks[1])
|
|
49
37
|
|
|
50
|
-
|
|
38
|
+
watchEffect(() => {
|
|
39
|
+
const active = resolved.isActive.value
|
|
40
|
+
const current = resolved.isCurrent.value
|
|
41
|
+
const prior = active && !current
|
|
51
42
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
if (!orderMap?.value.has(dir.value)) {
|
|
56
|
-
orderMap?.value.set(dir.value, [el])
|
|
57
|
-
}
|
|
58
|
-
else {
|
|
59
|
-
if (!orderMap?.value.get(dir.value)?.includes(el)) {
|
|
60
|
-
const afterClicks = orderMap?.value.get(dir.value) || []
|
|
61
|
-
orderMap?.value.set(dir.value, [el].concat(afterClicks))
|
|
43
|
+
if (resolved.flagHide) {
|
|
44
|
+
el.classList.toggle(resolved.flagFade ? CLASS_VCLICK_FADE : CLASS_VCLICK_HIDDEN, active)
|
|
45
|
+
el.classList.toggle(CLASS_VCLICK_HIDDEN_EXP, active)
|
|
62
46
|
}
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
() => {
|
|
71
|
-
const c = clicks?.value ?? 0
|
|
72
|
-
const show = dir.value != null
|
|
73
|
-
? Array.isArray(dir.value)
|
|
74
|
-
? c >= dir.value[0] && c < dir.value[1]
|
|
75
|
-
: c >= dir.value
|
|
76
|
-
: c > prev
|
|
77
|
-
|
|
78
|
-
if (!el.classList.contains(CLASS_VCLICK_HIDDEN_EXP))
|
|
79
|
-
el.classList.toggle(CLASS_HIDE, !show)
|
|
80
|
-
|
|
81
|
-
if (hide !== false && hide !== undefined)
|
|
82
|
-
el.classList.toggle(CLASS_HIDE, show)
|
|
83
|
-
|
|
84
|
-
// Reset CLASS_VCLICK_CURRENT to false.
|
|
85
|
-
el.classList.toggle(CLASS_VCLICK_CURRENT, false)
|
|
86
|
-
|
|
87
|
-
const currentElArray = orderMap?.value.get(c)
|
|
88
|
-
currentElArray?.forEach((cEl, idx) => {
|
|
89
|
-
// Reset CLASS_VCLICK_PRIOR to false
|
|
90
|
-
cEl.classList.toggle(CLASS_VCLICK_PRIOR, false)
|
|
91
|
-
// If the element is the last of order array, then set it as
|
|
92
|
-
// CLASS_VCLICK_CURRENT state, others set as CLASS_VCLICK_PRIOR state.
|
|
93
|
-
if (idx === currentElArray.length - 1)
|
|
94
|
-
cEl.classList.toggle(CLASS_VCLICK_CURRENT, true)
|
|
95
|
-
else
|
|
96
|
-
cEl.classList.toggle(CLASS_VCLICK_PRIOR, true)
|
|
97
|
-
})
|
|
98
|
-
|
|
99
|
-
if (!el.classList.contains(CLASS_VCLICK_CURRENT))
|
|
100
|
-
el.classList.toggle(CLASS_VCLICK_PRIOR, show)
|
|
101
|
-
},
|
|
102
|
-
{ immediate: true },
|
|
103
|
-
)
|
|
104
|
-
}
|
|
105
|
-
},
|
|
106
|
-
unmounted(el: HTMLElement, dir) {
|
|
107
|
-
el?.classList.toggle(CLASS_VCLICK_TARGET, false)
|
|
108
|
-
const elements = dirInject(dir, injectionClicksElements)!
|
|
109
|
-
if (elements?.value)
|
|
110
|
-
remove(elements.value, el)
|
|
47
|
+
else {
|
|
48
|
+
el.classList.toggle(resolved.flagFade ? CLASS_VCLICK_FADE : CLASS_VCLICK_HIDDEN, !active)
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
el.classList.toggle(CLASS_VCLICK_CURRENT, current)
|
|
52
|
+
el.classList.toggle(CLASS_VCLICK_PRIOR, prior)
|
|
53
|
+
})
|
|
111
54
|
},
|
|
55
|
+
unmounted,
|
|
112
56
|
})
|
|
113
57
|
|
|
114
58
|
app.directive('after', {
|
|
@@ -116,57 +60,30 @@ export default function createDirectives() {
|
|
|
116
60
|
name: 'v-after',
|
|
117
61
|
|
|
118
62
|
mounted(el: HTMLElement, dir) {
|
|
119
|
-
|
|
63
|
+
const resolved = resolveClick(el, dir, true)
|
|
64
|
+
if (resolved == null)
|
|
120
65
|
return
|
|
121
66
|
|
|
122
|
-
|
|
123
|
-
return
|
|
67
|
+
el.classList.toggle(CLASS_VCLICK_TARGET, true)
|
|
124
68
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
el?.classList.toggle(CLASS_VCLICK_TARGET, true)
|
|
142
|
-
|
|
143
|
-
if (clicks) {
|
|
144
|
-
watch(
|
|
145
|
-
clicks,
|
|
146
|
-
() => {
|
|
147
|
-
const c = (clicks.value ?? 0)
|
|
148
|
-
const show = dir.value != null
|
|
149
|
-
? Array.isArray(dir.value)
|
|
150
|
-
? c >= dir.value[0] && c < dir.value[1]
|
|
151
|
-
: c >= dir.value
|
|
152
|
-
: c >= prev
|
|
153
|
-
|
|
154
|
-
if (!el.classList.contains(CLASS_VCLICK_HIDDEN_EXP))
|
|
155
|
-
el.classList.toggle(CLASS_VCLICK_HIDDEN, !show)
|
|
156
|
-
|
|
157
|
-
// Reset CLASS_VCLICK_CURRENT to false.
|
|
158
|
-
el.classList.toggle(CLASS_VCLICK_CURRENT, false)
|
|
159
|
-
|
|
160
|
-
if (!el.classList.contains(CLASS_VCLICK_CURRENT))
|
|
161
|
-
el.classList.toggle(CLASS_VCLICK_PRIOR, show)
|
|
162
|
-
},
|
|
163
|
-
{ immediate: true },
|
|
164
|
-
)
|
|
165
|
-
}
|
|
166
|
-
},
|
|
167
|
-
unmounted(el: HTMLElement) {
|
|
168
|
-
el?.classList.toggle(CLASS_VCLICK_TARGET, true)
|
|
69
|
+
watchEffect(() => {
|
|
70
|
+
const active = resolved.isActive.value
|
|
71
|
+
const current = resolved.isCurrent.value
|
|
72
|
+
const prior = active && !current
|
|
73
|
+
|
|
74
|
+
if (resolved.flagHide) {
|
|
75
|
+
el.classList.toggle(resolved.flagFade ? CLASS_VCLICK_FADE : CLASS_VCLICK_HIDDEN, active)
|
|
76
|
+
el.classList.toggle(CLASS_VCLICK_HIDDEN_EXP, active)
|
|
77
|
+
}
|
|
78
|
+
else {
|
|
79
|
+
el.classList.toggle(resolved.flagFade ? CLASS_VCLICK_FADE : CLASS_VCLICK_HIDDEN, !active)
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
el.classList.toggle(CLASS_VCLICK_CURRENT, current)
|
|
83
|
+
el.classList.toggle(CLASS_VCLICK_PRIOR, prior)
|
|
84
|
+
})
|
|
169
85
|
},
|
|
86
|
+
unmounted,
|
|
170
87
|
})
|
|
171
88
|
|
|
172
89
|
app.directive('click-hide', {
|
|
@@ -174,50 +91,90 @@ export default function createDirectives() {
|
|
|
174
91
|
name: 'v-click-hide',
|
|
175
92
|
|
|
176
93
|
mounted(el: HTMLElement, dir) {
|
|
177
|
-
|
|
94
|
+
const resolved = resolveClick(el, dir, false, true)
|
|
95
|
+
if (resolved == null)
|
|
178
96
|
return
|
|
179
97
|
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
() => {
|
|
194
|
-
const c = clicks?.value ?? 0
|
|
195
|
-
const hide = dir.value != null
|
|
196
|
-
? c >= dir.value
|
|
197
|
-
: c > prev
|
|
198
|
-
el.classList.toggle(CLASS_VCLICK_HIDDEN, hide)
|
|
199
|
-
el.classList.toggle(CLASS_VCLICK_HIDDEN_EXP, hide)
|
|
200
|
-
},
|
|
201
|
-
{ immediate: true },
|
|
202
|
-
)
|
|
203
|
-
}
|
|
204
|
-
},
|
|
205
|
-
unmounted(el, dir) {
|
|
206
|
-
el?.classList.toggle(CLASS_VCLICK_TARGET, false)
|
|
207
|
-
const elements = dirInject(dir, injectionClicksElements)
|
|
208
|
-
if (elements?.value)
|
|
209
|
-
remove(elements.value, el)
|
|
98
|
+
el.classList.toggle(CLASS_VCLICK_TARGET, true)
|
|
99
|
+
|
|
100
|
+
watchEffect(() => {
|
|
101
|
+
const active = resolved.isActive.value
|
|
102
|
+
const current = resolved.isCurrent.value
|
|
103
|
+
const prior = active && !current
|
|
104
|
+
|
|
105
|
+
el.classList.toggle(resolved.flagFade ? CLASS_VCLICK_FADE : CLASS_VCLICK_HIDDEN, active)
|
|
106
|
+
el.classList.toggle(CLASS_VCLICK_HIDDEN_EXP, active)
|
|
107
|
+
|
|
108
|
+
el.classList.toggle(CLASS_VCLICK_CURRENT, current)
|
|
109
|
+
el.classList.toggle(CLASS_VCLICK_PRIOR, prior)
|
|
110
|
+
})
|
|
210
111
|
},
|
|
112
|
+
unmounted,
|
|
211
113
|
})
|
|
212
114
|
},
|
|
213
115
|
}
|
|
214
116
|
}
|
|
215
117
|
|
|
216
|
-
function
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
118
|
+
function isActive(thisClick: number | [number, number], clicks: number) {
|
|
119
|
+
return Array.isArray(thisClick)
|
|
120
|
+
? thisClick[0] <= clicks && clicks < thisClick[1]
|
|
121
|
+
: thisClick <= clicks
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
function isCurrent(thisClick: number | [number, number], clicks: number) {
|
|
125
|
+
return Array.isArray(thisClick)
|
|
126
|
+
? thisClick[0] === clicks
|
|
127
|
+
: thisClick === clicks
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
function resolveClick(el: Element, dir: DirectiveBinding<any>, clickAfter = false, flagHide = false): ResolvedClicksInfo | null {
|
|
131
|
+
const ctx = dirInject(dir, injectionClicksContext)?.value
|
|
132
|
+
|
|
133
|
+
if (!el || !ctx || ctx.disabled)
|
|
134
|
+
return null
|
|
135
|
+
|
|
136
|
+
let value = dir.value
|
|
137
|
+
|
|
138
|
+
if (value === false || value === 'false')
|
|
139
|
+
return null
|
|
140
|
+
|
|
141
|
+
flagHide ||= dir.modifiers.hide !== false && dir.modifiers.hide != null
|
|
142
|
+
const flagFade = dir.modifiers.fade !== false && dir.modifiers.fade != null
|
|
143
|
+
|
|
144
|
+
if (clickAfter)
|
|
145
|
+
value = '+0'
|
|
146
|
+
else if (value == null || value === true || value === 'true')
|
|
147
|
+
value = '+1'
|
|
148
|
+
|
|
149
|
+
let delta: number
|
|
150
|
+
let thisClick: number | [number, number]
|
|
151
|
+
let maxClick: number
|
|
152
|
+
if (Array.isArray(value)) {
|
|
153
|
+
// range (absolute)
|
|
154
|
+
delta = 0
|
|
155
|
+
thisClick = value as [number, number]
|
|
156
|
+
maxClick = value[1]
|
|
157
|
+
}
|
|
158
|
+
else {
|
|
159
|
+
({ start: thisClick, end: maxClick, delta } = ctx.resolve(value))
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
const resolved: ResolvedClicksInfo = {
|
|
163
|
+
max: maxClick,
|
|
164
|
+
clicks: thisClick,
|
|
165
|
+
delta,
|
|
166
|
+
isActive: computed(() => isActive(thisClick, ctx.current)),
|
|
167
|
+
isCurrent: computed(() => isCurrent(thisClick, ctx.current)),
|
|
168
|
+
isShown: computed(() => flagHide ? !isActive(thisClick, ctx.current) : isActive(thisClick, ctx.current)),
|
|
169
|
+
flagFade,
|
|
170
|
+
flagHide,
|
|
171
|
+
}
|
|
172
|
+
ctx.register(el, resolved)
|
|
173
|
+
return resolved
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
function unmounted(el: HTMLElement, dir: DirectiveBinding<any>) {
|
|
177
|
+
el.classList.toggle(CLASS_VCLICK_TARGET, false)
|
|
178
|
+
const ctx = dirInject(dir, injectionClicksContext)?.value
|
|
179
|
+
ctx?.unregister(el)
|
|
223
180
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@slidev/client",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.48.0-beta.0",
|
|
4
4
|
"description": "Presentation slides for developers",
|
|
5
5
|
"author": "antfu <anthonyfu117@hotmail.com>",
|
|
6
6
|
"license": "MIT",
|
|
@@ -20,9 +20,9 @@
|
|
|
20
20
|
},
|
|
21
21
|
"dependencies": {
|
|
22
22
|
"@antfu/utils": "^0.7.7",
|
|
23
|
-
"@iconify-json/carbon": "^1.1.
|
|
23
|
+
"@iconify-json/carbon": "^1.1.30",
|
|
24
24
|
"@iconify-json/ph": "^1.1.11",
|
|
25
|
-
"@shikijs/vitepress-twoslash": "^1.
|
|
25
|
+
"@shikijs/vitepress-twoslash": "^1.1.2",
|
|
26
26
|
"@unhead/vue": "^1.8.10",
|
|
27
27
|
"@unocss/reset": "^0.58.5",
|
|
28
28
|
"@vueuse/core": "^10.7.2",
|
|
@@ -44,12 +44,12 @@
|
|
|
44
44
|
"recordrtc": "^5.6.2",
|
|
45
45
|
"resolve": "^1.22.8",
|
|
46
46
|
"unocss": "^0.58.5",
|
|
47
|
-
"vue": "^3.4.
|
|
47
|
+
"vue": "^3.4.19",
|
|
48
48
|
"vue-router": "^4.2.5",
|
|
49
|
-
"@slidev/
|
|
50
|
-
"@slidev/
|
|
49
|
+
"@slidev/types": "0.48.0-beta.0",
|
|
50
|
+
"@slidev/parser": "0.48.0-beta.0"
|
|
51
51
|
},
|
|
52
52
|
"devDependencies": {
|
|
53
|
-
"vite": "^5.
|
|
53
|
+
"vite": "^5.1.1"
|
|
54
54
|
}
|
|
55
55
|
}
|
package/routes.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { RouteLocationNormalized, RouteRecordRaw } from 'vue-router'
|
|
2
2
|
import { createRouter, createWebHashHistory, createWebHistory } from 'vue-router'
|
|
3
3
|
import type { TransitionGroupProps } from 'vue'
|
|
4
|
+
import type { ClicksContext } from '@slidev/types'
|
|
4
5
|
import Play from './internals/Play.vue'
|
|
5
6
|
import Print from './internals/Print.vue'
|
|
6
7
|
|
|
@@ -101,7 +102,7 @@ declare module 'vue-router' {
|
|
|
101
102
|
}
|
|
102
103
|
|
|
103
104
|
// private fields
|
|
104
|
-
|
|
105
|
+
__clicksContext: null | ClicksContext
|
|
105
106
|
__preloaded?: boolean
|
|
106
107
|
}
|
|
107
108
|
}
|
package/setup/codemirror.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { Ref, WritableComputedRef } from 'vue'
|
|
2
2
|
import { watch } from 'vue'
|
|
3
|
-
import * as
|
|
3
|
+
import * as _CodeMirror from 'codemirror'
|
|
4
4
|
import 'codemirror/mode/javascript/javascript'
|
|
5
5
|
import 'codemirror/mode/css/css'
|
|
6
6
|
import 'codemirror/mode/markdown/markdown'
|
|
@@ -9,6 +9,8 @@ import 'codemirror/mode/htmlmixed/htmlmixed'
|
|
|
9
9
|
import 'codemirror/addon/display/placeholder'
|
|
10
10
|
import 'codemirror/lib/codemirror.css'
|
|
11
11
|
|
|
12
|
+
const CodeMirror = _CodeMirror.default ?? ('fromTextArea' in _CodeMirror ? _CodeMirror : globalThis.CodeMirror)
|
|
13
|
+
|
|
12
14
|
export async function useCodeMirror(
|
|
13
15
|
textarea: Ref<HTMLTextAreaElement | null | undefined>,
|
|
14
16
|
input: Ref<string> | WritableComputedRef<string>,
|
package/setup/root.ts
CHANGED
|
@@ -5,7 +5,7 @@ import { nanoid } from 'nanoid'
|
|
|
5
5
|
import { configs } from '../env'
|
|
6
6
|
import { initSharedState, onPatch, patch } from '../state/shared'
|
|
7
7
|
import { initDrawingState } from '../state/drawings'
|
|
8
|
-
import {
|
|
8
|
+
import { clicksContext, currentPage, getPath, isNotesViewer, isPresenter } from '../logic/nav'
|
|
9
9
|
import { router } from '../routes'
|
|
10
10
|
import { TRUST_ORIGINS } from '../constants'
|
|
11
11
|
import { skipTransition } from '../composables/hmr'
|
|
@@ -38,11 +38,11 @@ export default function setupRoot() {
|
|
|
38
38
|
|
|
39
39
|
if (isPresenter.value) {
|
|
40
40
|
patch('page', +currentPage.value)
|
|
41
|
-
patch('clicks',
|
|
41
|
+
patch('clicks', clicksContext.value.current)
|
|
42
42
|
}
|
|
43
43
|
else {
|
|
44
44
|
patch('viewerPage', +currentPage.value)
|
|
45
|
-
patch('viewerClicks',
|
|
45
|
+
patch('viewerClicks', clicksContext.value.current)
|
|
46
46
|
}
|
|
47
47
|
|
|
48
48
|
patch('lastUpdate', {
|
|
@@ -52,13 +52,13 @@ export default function setupRoot() {
|
|
|
52
52
|
})
|
|
53
53
|
}
|
|
54
54
|
router.afterEach(updateSharedState)
|
|
55
|
-
watch(
|
|
55
|
+
watch(clicksContext, updateSharedState)
|
|
56
56
|
|
|
57
57
|
onPatch((state) => {
|
|
58
58
|
const routePath = router.currentRoute.value.path
|
|
59
59
|
if (!routePath.match(/^\/(\d+|presenter)\/?/))
|
|
60
60
|
return
|
|
61
|
-
if (state.lastUpdate?.type === 'presenter' && (+state.page !== +currentPage.value || +
|
|
61
|
+
if (state.lastUpdate?.type === 'presenter' && (+state.page !== +currentPage.value || +clicksContext.value.current !== +state.clicks)) {
|
|
62
62
|
skipTransition.value = false
|
|
63
63
|
router.replace({
|
|
64
64
|
path: getPath(state.page),
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
import type { ComputedRef, WritableComputedRef } from 'vue'
|
|
2
|
-
import { computed, nextTick, ref } from 'vue'
|
|
3
|
-
import type { RouteRecordRaw } from 'vue-router'
|
|
4
|
-
import type { SlidevContextNavClicks } from '../modules/context'
|
|
5
|
-
import { rawRoutes, router } from '../routes'
|
|
6
|
-
|
|
7
|
-
export function useNavClicks(
|
|
8
|
-
clicks: WritableComputedRef<number>,
|
|
9
|
-
currentRoute: ComputedRef<RouteRecordRaw | undefined>,
|
|
10
|
-
currentPage: ComputedRef<number>,
|
|
11
|
-
): SlidevContextNavClicks {
|
|
12
|
-
// force update collected elements when the route is fully resolved
|
|
13
|
-
const routeForceRefresh = ref(0)
|
|
14
|
-
nextTick(() => {
|
|
15
|
-
router.afterEach(async () => {
|
|
16
|
-
await nextTick()
|
|
17
|
-
routeForceRefresh.value += 1
|
|
18
|
-
})
|
|
19
|
-
})
|
|
20
|
-
|
|
21
|
-
const clicksElements = computed<HTMLElement[]>(() => {
|
|
22
|
-
// eslint-disable-next-line no-unused-expressions
|
|
23
|
-
routeForceRefresh.value
|
|
24
|
-
return currentRoute.value?.meta?.__clicksElements || []
|
|
25
|
-
})
|
|
26
|
-
|
|
27
|
-
const clicksTotal = computed(() => +(currentRoute.value?.meta?.clicks ?? clicksElements.value.length))
|
|
28
|
-
|
|
29
|
-
const hasNext = computed(() => currentPage.value < rawRoutes.length - 1 || clicks.value < clicksTotal.value)
|
|
30
|
-
const hasPrev = computed(() => currentPage.value > 1 || clicks.value > 0)
|
|
31
|
-
return {
|
|
32
|
-
clicks,
|
|
33
|
-
clicksElements,
|
|
34
|
-
clicksTotal,
|
|
35
|
-
hasNext,
|
|
36
|
-
hasPrev,
|
|
37
|
-
}
|
|
38
|
-
}
|