@slidev/client 0.48.0-beta.14 → 0.48.0-beta.15
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/Arrow.vue +2 -4
- package/builtin/Mermaid.vue +2 -2
- package/builtin/Monaco.vue +8 -8
- package/builtin/ShikiMagicMove.vue +6 -4
- package/internals/NoteDisplay.vue +31 -24
- package/internals/{NoteEditor.vue → NoteEditable.vue} +27 -21
- package/modules/mermaid.ts +6 -7
- package/package.json +4 -5
- package/pages/overview.vue +12 -2
- package/pages/presenter.vue +2 -2
- package/setup/root.ts +2 -2
package/builtin/Arrow.vue
CHANGED
|
@@ -9,7 +9,7 @@ Simple Arrow
|
|
|
9
9
|
-->
|
|
10
10
|
|
|
11
11
|
<script setup lang="ts">
|
|
12
|
-
import {
|
|
12
|
+
import { makeId } from '../logic/utils'
|
|
13
13
|
|
|
14
14
|
defineProps<{
|
|
15
15
|
x1: number | string
|
|
@@ -20,9 +20,7 @@ defineProps<{
|
|
|
20
20
|
color?: string
|
|
21
21
|
}>()
|
|
22
22
|
|
|
23
|
-
const
|
|
24
|
-
|
|
25
|
-
const id = nanoid()
|
|
23
|
+
const id = makeId()
|
|
26
24
|
</script>
|
|
27
25
|
|
|
28
26
|
<template>
|
package/builtin/Mermaid.vue
CHANGED
|
@@ -19,7 +19,7 @@ import ShadowRoot from '../internals/ShadowRoot.vue'
|
|
|
19
19
|
import { isDark } from '../logic/dark'
|
|
20
20
|
|
|
21
21
|
const props = defineProps<{
|
|
22
|
-
|
|
22
|
+
codeLz: string
|
|
23
23
|
scale?: number
|
|
24
24
|
theme?: string
|
|
25
25
|
}>()
|
|
@@ -37,7 +37,7 @@ watchEffect(async (onCleanup) => {
|
|
|
37
37
|
error.value = null
|
|
38
38
|
try {
|
|
39
39
|
const svg = await renderMermaid(
|
|
40
|
-
props.
|
|
40
|
+
props.codeLz || '',
|
|
41
41
|
{
|
|
42
42
|
theme: props.theme || (isDark.value ? 'dark' : undefined),
|
|
43
43
|
...vm!.attrs,
|
package/builtin/Monaco.vue
CHANGED
|
@@ -14,30 +14,30 @@ Learn more: https://sli.dev/guide/syntax.html#monaco-editor
|
|
|
14
14
|
<script setup lang="ts">
|
|
15
15
|
import { computed, onMounted, ref } from 'vue'
|
|
16
16
|
import { useEventListener } from '@vueuse/core'
|
|
17
|
-
import { decode } from 'js-base64'
|
|
18
|
-
import { nanoid } from 'nanoid'
|
|
19
17
|
import type * as monaco from 'monaco-editor'
|
|
18
|
+
import { decompressFromBase64 } from 'lz-string'
|
|
20
19
|
import { isDark } from '../logic/dark'
|
|
20
|
+
import { makeId } from '../logic/utils'
|
|
21
21
|
|
|
22
22
|
const props = withDefaults(defineProps<{
|
|
23
|
-
|
|
24
|
-
|
|
23
|
+
codeLz: string
|
|
24
|
+
diffLz?: string
|
|
25
25
|
lang?: string
|
|
26
26
|
readonly?: boolean
|
|
27
27
|
lineNumbers?: 'on' | 'off' | 'relative' | 'interval'
|
|
28
28
|
height?: number | string
|
|
29
29
|
editorOptions?: monaco.editor.IEditorOptions
|
|
30
30
|
}>(), {
|
|
31
|
-
|
|
31
|
+
codeLz: '',
|
|
32
32
|
lang: 'typescript',
|
|
33
33
|
readonly: false,
|
|
34
34
|
lineNumbers: 'off',
|
|
35
35
|
height: 'auto',
|
|
36
36
|
})
|
|
37
37
|
|
|
38
|
-
const id =
|
|
39
|
-
const code = ref(
|
|
40
|
-
const diff = ref(props.
|
|
38
|
+
const id = makeId()
|
|
39
|
+
const code = ref(decompressFromBase64(props.codeLz))
|
|
40
|
+
const diff = ref(props.diffLz ? decompressFromBase64(props.diffLz) : null)
|
|
41
41
|
const lineHeight = +(getComputedStyle(document.body).getPropertyValue('--slidev-code-line-height') || '18').replace('px', '') || 18
|
|
42
42
|
const editorHeight = ref(0)
|
|
43
43
|
const calculatedHeight = computed(() => code.value.split(/\r?\n/g).length * lineHeight)
|
|
@@ -2,16 +2,18 @@
|
|
|
2
2
|
import { ShikiMagicMovePrecompiled } from 'shiki-magic-move/vue'
|
|
3
3
|
import type { KeyedTokensInfo } from 'shiki-magic-move/types'
|
|
4
4
|
import { onMounted, onUnmounted, ref, watchEffect } from 'vue'
|
|
5
|
+
import { decompressFromBase64 } from 'lz-string'
|
|
5
6
|
import { useSlideContext } from '../context'
|
|
6
7
|
import { makeId } from '../logic/utils'
|
|
7
8
|
|
|
8
9
|
import 'shiki-magic-move/style.css'
|
|
9
10
|
|
|
10
11
|
const props = defineProps<{
|
|
11
|
-
|
|
12
|
+
stepsLz: string
|
|
12
13
|
at?: string | number
|
|
13
14
|
}>()
|
|
14
15
|
|
|
16
|
+
const steps = JSON.parse(decompressFromBase64(props.stepsLz)) as KeyedTokensInfo[]
|
|
15
17
|
const { $clicksContext: clicks, $scale: scale } = useSlideContext()
|
|
16
18
|
const id = makeId()
|
|
17
19
|
const index = ref(0)
|
|
@@ -24,14 +26,14 @@ onMounted(() => {
|
|
|
24
26
|
if (!clicks || clicks.disabled)
|
|
25
27
|
return
|
|
26
28
|
|
|
27
|
-
const { start, end, delta } = clicks.resolve(props.at || '+1',
|
|
29
|
+
const { start, end, delta } = clicks.resolve(props.at || '+1', steps.length - 1)
|
|
28
30
|
clicks.register(id, { max: end, delta })
|
|
29
31
|
|
|
30
32
|
watchEffect(() => {
|
|
31
33
|
if (clicks.disabled)
|
|
32
|
-
index.value =
|
|
34
|
+
index.value = steps.length - 1
|
|
33
35
|
else
|
|
34
|
-
index.value = Math.min(Math.max(0, clicks.current - start + 1),
|
|
36
|
+
index.value = Math.min(Math.max(0, clicks.current - start + 1), steps.length - 1)
|
|
35
37
|
})
|
|
36
38
|
})
|
|
37
39
|
</script>
|
|
@@ -12,7 +12,10 @@ const props = defineProps<{
|
|
|
12
12
|
autoScroll?: boolean
|
|
13
13
|
}>()
|
|
14
14
|
|
|
15
|
-
defineEmits
|
|
15
|
+
const emit = defineEmits<{
|
|
16
|
+
(type: 'markerDblclick', e: MouseEvent, clicks: number): void
|
|
17
|
+
(type: 'markerClick', e: MouseEvent, clicks: number): void
|
|
18
|
+
}>()
|
|
16
19
|
|
|
17
20
|
const withClicks = computed(() => props.clicksContext?.current != null && props.noteHtml?.includes('slidev-note-click-mark'))
|
|
18
21
|
const noteDisplay = ref<HTMLElement | null>(null)
|
|
@@ -21,16 +24,13 @@ const CLASS_FADE = 'slidev-note-fade'
|
|
|
21
24
|
const CLASS_MARKER = 'slidev-note-click-mark'
|
|
22
25
|
|
|
23
26
|
function highlightNote() {
|
|
24
|
-
if (!noteDisplay.value || !withClicks.value
|
|
27
|
+
if (!noteDisplay.value || !withClicks.value)
|
|
25
28
|
return
|
|
26
29
|
|
|
27
|
-
const
|
|
30
|
+
const markers = Array.from(noteDisplay.value.querySelectorAll(`.${CLASS_MARKER}`)) as HTMLElement[]
|
|
31
|
+
|
|
32
|
+
const current = +(props.clicksContext?.current ?? CLICKS_MAX)
|
|
28
33
|
const disabled = current < 0 || current >= CLICKS_MAX
|
|
29
|
-
if (disabled) {
|
|
30
|
-
Array.from(noteDisplay.value.querySelectorAll('*'))
|
|
31
|
-
.forEach(el => el.classList.remove(CLASS_FADE))
|
|
32
|
-
return
|
|
33
|
-
}
|
|
34
34
|
|
|
35
35
|
const nodeToIgnores = new Set<Element>()
|
|
36
36
|
function ignoreParent(node: Element) {
|
|
@@ -41,7 +41,6 @@ function highlightNote() {
|
|
|
41
41
|
ignoreParent(node.parentElement)
|
|
42
42
|
}
|
|
43
43
|
|
|
44
|
-
const markers = Array.from(noteDisplay.value.querySelectorAll(`.${CLASS_MARKER}`)) as HTMLElement[]
|
|
45
44
|
const markersMap = new Map<number, HTMLElement>()
|
|
46
45
|
|
|
47
46
|
// Convert all sibling text nodes to spans, so we attach classes to them
|
|
@@ -78,25 +77,36 @@ function highlightNote() {
|
|
|
78
77
|
|
|
79
78
|
// Apply
|
|
80
79
|
for (const [count, els] of segments) {
|
|
81
|
-
|
|
82
|
-
CLASS_FADE
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
80
|
+
if (disabled) {
|
|
81
|
+
els.forEach(el => el.classList.remove(CLASS_FADE))
|
|
82
|
+
}
|
|
83
|
+
else {
|
|
84
|
+
els.forEach(el => el.classList.toggle(
|
|
85
|
+
CLASS_FADE,
|
|
86
|
+
nodeToIgnores.has(el)
|
|
87
|
+
? false
|
|
88
|
+
: count !== current,
|
|
89
|
+
))
|
|
90
|
+
}
|
|
87
91
|
}
|
|
88
92
|
|
|
89
93
|
for (const [clicks, marker] of markersMap) {
|
|
90
94
|
marker.classList.remove(CLASS_FADE)
|
|
91
|
-
marker.classList.toggle(`${CLASS_MARKER}-past`, clicks < current)
|
|
92
|
-
marker.classList.toggle(`${CLASS_MARKER}-active`, clicks === current)
|
|
93
|
-
marker.classList.toggle(`${CLASS_MARKER}-next`, clicks === current + 1)
|
|
94
|
-
marker.classList.toggle(`${CLASS_MARKER}-future`, clicks > current + 1)
|
|
95
|
-
marker.
|
|
95
|
+
marker.classList.toggle(`${CLASS_MARKER}-past`, disabled ? false : clicks < current)
|
|
96
|
+
marker.classList.toggle(`${CLASS_MARKER}-active`, disabled ? false : clicks === current)
|
|
97
|
+
marker.classList.toggle(`${CLASS_MARKER}-next`, disabled ? false : clicks === current + 1)
|
|
98
|
+
marker.classList.toggle(`${CLASS_MARKER}-future`, disabled ? false : clicks > current + 1)
|
|
99
|
+
marker.ondblclick = (e) => {
|
|
100
|
+
emit('markerDblclick', e, clicks)
|
|
101
|
+
if (e.defaultPrevented)
|
|
102
|
+
return
|
|
96
103
|
props.clicksContext!.current = clicks
|
|
97
104
|
e.stopPropagation()
|
|
98
105
|
e.stopImmediatePropagation()
|
|
99
|
-
}
|
|
106
|
+
}
|
|
107
|
+
marker.onclick = (e) => {
|
|
108
|
+
emit('markerClick', e, clicks)
|
|
109
|
+
}
|
|
100
110
|
|
|
101
111
|
if (props.autoScroll && clicks === current)
|
|
102
112
|
marker.scrollIntoView({ block: 'center', behavior: 'smooth' })
|
|
@@ -124,14 +134,12 @@ onMounted(() => {
|
|
|
124
134
|
ref="noteDisplay"
|
|
125
135
|
class="prose overflow-auto outline-none slidev-note"
|
|
126
136
|
:class="[props.class, withClicks ? 'slidev-note-with-clicks' : '']"
|
|
127
|
-
@click="$emit('click')"
|
|
128
137
|
v-html="noteHtml"
|
|
129
138
|
/>
|
|
130
139
|
<div
|
|
131
140
|
v-else-if="note"
|
|
132
141
|
class="prose overflow-auto outline-none slidev-note"
|
|
133
142
|
:class="props.class"
|
|
134
|
-
@click="$emit('click')"
|
|
135
143
|
>
|
|
136
144
|
<p v-text="note" />
|
|
137
145
|
</div>
|
|
@@ -139,7 +147,6 @@ onMounted(() => {
|
|
|
139
147
|
v-else
|
|
140
148
|
class="prose overflow-auto outline-none opacity-50 italic select-none slidev-note"
|
|
141
149
|
:class="props.class"
|
|
142
|
-
@click="$emit('click')"
|
|
143
150
|
>
|
|
144
151
|
<p v-text="props.placeholder || 'No notes.'" />
|
|
145
152
|
</div>
|
|
@@ -30,9 +30,12 @@ const props = defineProps({
|
|
|
30
30
|
},
|
|
31
31
|
})
|
|
32
32
|
|
|
33
|
-
const emit = defineEmits
|
|
34
|
-
'update:editing',
|
|
35
|
-
|
|
33
|
+
const emit = defineEmits<{
|
|
34
|
+
(type: 'update:editing', value: boolean): void
|
|
35
|
+
(type: 'markerDblclick', e: MouseEvent, clicks: number): void
|
|
36
|
+
(type: 'markerClick', e: MouseEvent, clicks: number): void
|
|
37
|
+
}>()
|
|
38
|
+
|
|
36
39
|
const editing = useVModel(props, 'editing', emit, { passive: true })
|
|
37
40
|
|
|
38
41
|
const { info, update } = useDynamicSlideInfo(props.no)
|
|
@@ -40,9 +43,12 @@ const { info, update } = useDynamicSlideInfo(props.no)
|
|
|
40
43
|
const note = ref('')
|
|
41
44
|
let timer: any
|
|
42
45
|
|
|
46
|
+
// Send back the note on changes
|
|
43
47
|
const { ignoreUpdates } = ignorableWatch(
|
|
44
48
|
note,
|
|
45
49
|
(v) => {
|
|
50
|
+
if (!editing.value)
|
|
51
|
+
return
|
|
46
52
|
const id = props.no
|
|
47
53
|
clearTimeout(timer)
|
|
48
54
|
timer = setTimeout(() => {
|
|
@@ -51,46 +57,44 @@ const { ignoreUpdates } = ignorableWatch(
|
|
|
51
57
|
},
|
|
52
58
|
)
|
|
53
59
|
|
|
60
|
+
// Update note value when info changes
|
|
54
61
|
watch(
|
|
55
|
-
info,
|
|
56
|
-
(
|
|
62
|
+
() => info.value?.note,
|
|
63
|
+
(value = '') => {
|
|
57
64
|
if (editing.value)
|
|
58
65
|
return
|
|
59
66
|
clearTimeout(timer)
|
|
60
67
|
ignoreUpdates(() => {
|
|
61
|
-
note.value =
|
|
68
|
+
note.value = value
|
|
62
69
|
})
|
|
63
70
|
},
|
|
64
71
|
{ immediate: true, flush: 'sync' },
|
|
65
72
|
)
|
|
66
73
|
|
|
67
|
-
const
|
|
74
|
+
const inputEl = ref<HTMLTextAreaElement>()
|
|
75
|
+
const inputHeight = ref<number | null>()
|
|
68
76
|
|
|
69
77
|
watchEffect(() => {
|
|
70
78
|
if (editing.value)
|
|
71
|
-
|
|
79
|
+
inputEl.value?.focus()
|
|
72
80
|
})
|
|
73
81
|
|
|
74
|
-
onClickOutside(
|
|
82
|
+
onClickOutside(inputEl, () => {
|
|
75
83
|
editing.value = false
|
|
76
84
|
})
|
|
77
85
|
|
|
78
|
-
function
|
|
79
|
-
if (!props.autoHeight || !
|
|
86
|
+
function calculateEditorHeight() {
|
|
87
|
+
if (!props.autoHeight || !inputEl.value || !editing.value)
|
|
80
88
|
return
|
|
81
|
-
if (
|
|
82
|
-
|
|
89
|
+
if (inputEl.value.scrollHeight > inputEl.value.clientHeight)
|
|
90
|
+
inputEl.value.style.height = `${inputEl.value.scrollHeight}px`
|
|
83
91
|
}
|
|
84
92
|
|
|
85
|
-
const inputHeight = ref<number | null>()
|
|
86
|
-
|
|
87
93
|
watch(
|
|
88
94
|
note,
|
|
89
|
-
() => {
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
})
|
|
93
|
-
},
|
|
95
|
+
() => nextTick(() => {
|
|
96
|
+
calculateEditorHeight()
|
|
97
|
+
}),
|
|
94
98
|
{ flush: 'post', immediate: true },
|
|
95
99
|
)
|
|
96
100
|
</script>
|
|
@@ -105,10 +109,12 @@ watch(
|
|
|
105
109
|
:note-html="info?.noteHTML"
|
|
106
110
|
:clicks-context="clicksContext"
|
|
107
111
|
:auto-scroll="!autoHeight"
|
|
112
|
+
@marker-click="(e, clicks) => emit('markerClick', e, clicks)"
|
|
113
|
+
@marker-dblclick="(e, clicks) => emit('markerDblclick', e, clicks)"
|
|
108
114
|
/>
|
|
109
115
|
<textarea
|
|
110
116
|
v-else
|
|
111
|
-
ref="
|
|
117
|
+
ref="inputEl"
|
|
112
118
|
v-model="note"
|
|
113
119
|
class="prose resize-none overflow-auto outline-none bg-transparent block border-primary border-2"
|
|
114
120
|
style="line-height: 1.75;"
|
package/modules/mermaid.ts
CHANGED
|
@@ -1,17 +1,16 @@
|
|
|
1
1
|
import mermaid from 'mermaid/dist/mermaid.esm.mjs'
|
|
2
|
-
import {
|
|
3
|
-
import { decode } from 'js-base64'
|
|
2
|
+
import { decompressFromBase64 } from 'lz-string'
|
|
4
3
|
import { clearUndefined } from '@antfu/utils'
|
|
5
4
|
import setupMermaid from '../setup/mermaid'
|
|
5
|
+
import { makeId } from '../logic/utils'
|
|
6
6
|
|
|
7
7
|
mermaid.startOnLoad = false
|
|
8
8
|
mermaid.initialize({ startOnLoad: false })
|
|
9
9
|
|
|
10
|
-
const nanoid = customAlphabet('abcedfghicklmn', 10)
|
|
11
10
|
const cache = new Map<string, string>()
|
|
12
11
|
|
|
13
|
-
export async function renderMermaid(
|
|
14
|
-
const key =
|
|
12
|
+
export async function renderMermaid(lzEncoded: string, options: any) {
|
|
13
|
+
const key = lzEncoded + JSON.stringify(options)
|
|
15
14
|
const _cache = cache.get(key)
|
|
16
15
|
if (_cache)
|
|
17
16
|
return _cache
|
|
@@ -21,8 +20,8 @@ export async function renderMermaid(encoded: string, options: any) {
|
|
|
21
20
|
...clearUndefined(setupMermaid() || {}),
|
|
22
21
|
...clearUndefined(options),
|
|
23
22
|
})
|
|
24
|
-
const code =
|
|
25
|
-
const id =
|
|
23
|
+
const code = decompressFromBase64(lzEncoded)
|
|
24
|
+
const id = makeId()
|
|
26
25
|
const { svg } = await mermaid.render(id, code)
|
|
27
26
|
cache.set(key, svg)
|
|
28
27
|
return svg
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@slidev/client",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.48.0-beta.
|
|
4
|
+
"version": "0.48.0-beta.15",
|
|
5
5
|
"description": "Presentation slides for developers",
|
|
6
6
|
"author": "antfu <anthonyfu117@hotmail.com>",
|
|
7
7
|
"license": "MIT",
|
|
@@ -42,12 +42,11 @@
|
|
|
42
42
|
"file-saver": "^2.0.5",
|
|
43
43
|
"floating-vue": "^5.2.2",
|
|
44
44
|
"fuse.js": "^7.0.0",
|
|
45
|
-
"js-base64": "^3.7.7",
|
|
46
45
|
"js-yaml": "^4.1.0",
|
|
47
46
|
"katex": "^0.16.9",
|
|
47
|
+
"lz-string": "^1.5.0",
|
|
48
48
|
"mermaid": "^10.8.0",
|
|
49
49
|
"monaco-editor": "^0.37.1",
|
|
50
|
-
"nanoid": "^5.0.6",
|
|
51
50
|
"prettier": "^3.2.5",
|
|
52
51
|
"recordrtc": "^5.6.2",
|
|
53
52
|
"resolve": "^1.22.8",
|
|
@@ -55,8 +54,8 @@
|
|
|
55
54
|
"unocss": "^0.58.5",
|
|
56
55
|
"vue": "^3.4.20",
|
|
57
56
|
"vue-router": "^4.3.0",
|
|
58
|
-
"@slidev/types": "0.48.0-beta.
|
|
59
|
-
"@slidev/parser": "0.48.0-beta.
|
|
57
|
+
"@slidev/types": "0.48.0-beta.15",
|
|
58
|
+
"@slidev/parser": "0.48.0-beta.15"
|
|
60
59
|
},
|
|
61
60
|
"devDependencies": {
|
|
62
61
|
"vite": "^5.1.4"
|
package/pages/overview.vue
CHANGED
|
@@ -12,7 +12,7 @@ import SlideContainer from '../internals/SlideContainer.vue'
|
|
|
12
12
|
import SlideWrapper from '../internals/SlideWrapper'
|
|
13
13
|
import DrawingPreview from '../internals/DrawingPreview.vue'
|
|
14
14
|
import IconButton from '../internals/IconButton.vue'
|
|
15
|
-
import
|
|
15
|
+
import NoteEditable from '../internals/NoteEditable.vue'
|
|
16
16
|
import OverviewClicksSlider from '../internals/OverviewClicksSlider.vue'
|
|
17
17
|
import { CLICKS_MAX } from '../constants'
|
|
18
18
|
|
|
@@ -80,6 +80,15 @@ function scrollToSlide(idx: number) {
|
|
|
80
80
|
el.scrollIntoView({ behavior: 'smooth', block: 'start' })
|
|
81
81
|
}
|
|
82
82
|
|
|
83
|
+
function onMarkerClick(e: MouseEvent, clicks: number, route: RouteRecordRaw) {
|
|
84
|
+
const ctx = getClicksContext(route)
|
|
85
|
+
if (ctx.current === clicks)
|
|
86
|
+
ctx.current = CLICKS_MAX
|
|
87
|
+
else
|
|
88
|
+
ctx.current = clicks
|
|
89
|
+
e.preventDefault()
|
|
90
|
+
}
|
|
91
|
+
|
|
83
92
|
onMounted(() => {
|
|
84
93
|
nextTick(() => {
|
|
85
94
|
checkActiveBlocks()
|
|
@@ -192,7 +201,7 @@ onMounted(() => {
|
|
|
192
201
|
<carbon:pen />
|
|
193
202
|
</IconButton>
|
|
194
203
|
</div>
|
|
195
|
-
<
|
|
204
|
+
<NoteEditable
|
|
196
205
|
:no="idx"
|
|
197
206
|
class="max-w-250 w-250 text-lg rounded p3"
|
|
198
207
|
:auto-height="true"
|
|
@@ -200,6 +209,7 @@ onMounted(() => {
|
|
|
200
209
|
:clicks-context="getClicksContext(route)"
|
|
201
210
|
@dblclick="edittingNote !== idx ? edittingNote = idx : null"
|
|
202
211
|
@update:editing="edittingNote = null"
|
|
212
|
+
@marker-click="(e, clicks) => onMarkerClick(e, clicks, route)"
|
|
203
213
|
/>
|
|
204
214
|
<div
|
|
205
215
|
v-if="wordCounts[idx] > 0"
|
package/pages/presenter.vue
CHANGED
|
@@ -15,7 +15,7 @@ import SlideWrapper from '../internals/SlideWrapper'
|
|
|
15
15
|
import SlideContainer from '../internals/SlideContainer.vue'
|
|
16
16
|
import NavControls from '../internals/NavControls.vue'
|
|
17
17
|
import QuickOverview from '../internals/QuickOverview.vue'
|
|
18
|
-
import
|
|
18
|
+
import NoteEditable from '../internals/NoteEditable.vue'
|
|
19
19
|
import NoteStatic from '../internals/NoteStatic.vue'
|
|
20
20
|
import Goto from '../internals/Goto.vue'
|
|
21
21
|
import SlidesShow from '../internals/SlidesShow.vue'
|
|
@@ -130,7 +130,7 @@ onMounted(() => {
|
|
|
130
130
|
<SideEditor />
|
|
131
131
|
</div>
|
|
132
132
|
<div v-else class="grid-section note grid grid-rows-[1fr_min-content] overflow-hidden">
|
|
133
|
-
<
|
|
133
|
+
<NoteEditable
|
|
134
134
|
v-if="__DEV__"
|
|
135
135
|
:key="`edit-${currentSlideId}`"
|
|
136
136
|
v-model:editing="notesEditing"
|
package/setup/root.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
/* __imports__ */
|
|
2
2
|
import { watch } from 'vue'
|
|
3
3
|
import { useHead } from '@unhead/vue'
|
|
4
|
-
import { nanoid } from 'nanoid'
|
|
5
4
|
import { configs } from '../env'
|
|
6
5
|
import { initSharedState, onPatch, patch } from '../state/shared'
|
|
7
6
|
import { initDrawingState } from '../state/drawings'
|
|
@@ -9,6 +8,7 @@ import { clicksContext, currentPage, getPath, isNotesViewer, isPresenter } from
|
|
|
9
8
|
import { router } from '../routes'
|
|
10
9
|
import { TRUST_ORIGINS } from '../constants'
|
|
11
10
|
import { skipTransition } from '../composables/hmr'
|
|
11
|
+
import { makeId } from '../logic/utils'
|
|
12
12
|
|
|
13
13
|
export default function setupRoot() {
|
|
14
14
|
// @ts-expect-error injected in runtime
|
|
@@ -25,7 +25,7 @@ export default function setupRoot() {
|
|
|
25
25
|
initSharedState(`${title} - shared`)
|
|
26
26
|
initDrawingState(`${title} - drawings`)
|
|
27
27
|
|
|
28
|
-
const id = `${location.origin}_${
|
|
28
|
+
const id = `${location.origin}_${makeId()}`
|
|
29
29
|
|
|
30
30
|
// update shared state
|
|
31
31
|
function updateSharedState() {
|