@slidev/client 0.48.0-beta.24 → 0.48.0-beta.26

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.
Files changed (50) hide show
  1. package/builtin/Link.vue +3 -1
  2. package/builtin/TocList.vue +2 -2
  3. package/composables/useClicks.ts +13 -50
  4. package/composables/useDarkMode.ts +9 -0
  5. package/composables/useDrawings.ts +181 -0
  6. package/composables/useNav.ts +167 -7
  7. package/composables/useSwipeControls.ts +5 -2
  8. package/composables/useTocTree.ts +25 -7
  9. package/composables/useViewTransition.ts +1 -1
  10. package/context.ts +5 -0
  11. package/index.ts +12 -0
  12. package/internals/CodeRunner.vue +4 -1
  13. package/internals/DrawingControls.vue +11 -10
  14. package/internals/DrawingLayer.vue +4 -2
  15. package/internals/DrawingPreview.vue +4 -2
  16. package/internals/Goto.vue +4 -2
  17. package/internals/NavControls.vue +21 -3
  18. package/internals/PrintContainer.vue +3 -1
  19. package/internals/PrintSlide.vue +3 -3
  20. package/internals/QuickOverview.vue +5 -4
  21. package/internals/SideEditor.vue +4 -2
  22. package/internals/SlideContainer.vue +3 -1
  23. package/internals/SlidesShow.vue +16 -4
  24. package/logic/overview.ts +1 -1
  25. package/logic/route.ts +6 -9
  26. package/logic/slides.ts +5 -4
  27. package/main.ts +1 -16
  28. package/modules/context.ts +0 -40
  29. package/package.json +5 -3
  30. package/pages/notes.vue +3 -1
  31. package/pages/overview.vue +6 -3
  32. package/pages/play.vue +6 -3
  33. package/pages/presenter/print.vue +3 -1
  34. package/pages/presenter.vue +19 -6
  35. package/pages/print.vue +3 -1
  36. package/routes.ts +0 -8
  37. package/setup/code-runners.ts +6 -11
  38. package/setup/main.ts +39 -9
  39. package/setup/mermaid.ts +5 -6
  40. package/setup/monaco.ts +7 -9
  41. package/setup/root.ts +56 -11
  42. package/setup/shortcuts.ts +14 -12
  43. package/styles/shiki-twoslash.css +1 -1
  44. package/composables/useContext.ts +0 -12
  45. package/logic/drawings.ts +0 -161
  46. package/logic/nav-state.ts +0 -20
  47. package/logic/nav.ts +0 -71
  48. package/setup/prettier.ts +0 -43
  49. /package/{composables → logic}/hmr.ts +0 -0
  50. /package/{setup → modules}/codemirror.ts +0 -0
package/pages/print.vue CHANGED
@@ -1,9 +1,11 @@
1
1
  <script setup lang="ts">
2
2
  import { watchEffect } from 'vue'
3
3
  import { windowSize } from '../state'
4
- import { isPrintMode } from '../logic/nav'
5
4
  import PrintContainer from '../internals/PrintContainer.vue'
6
5
  import PrintStyle from '../internals/PrintStyle.vue'
6
+ import { useNav } from '../composables/useNav'
7
+
8
+ const { isPrintMode } = useNav()
7
9
 
8
10
  watchEffect(() => {
9
11
  if (isPrintMode)
package/routes.ts CHANGED
@@ -1,5 +1,4 @@
1
1
  import type { RouteLocationNormalized, RouteRecordRaw } from 'vue-router'
2
- import { createRouter, createWebHashHistory, createWebHistory } from 'vue-router'
3
2
  import configs from '#slidev/configs'
4
3
 
5
4
  export const routes: RouteRecordRaw[] = [
@@ -67,10 +66,3 @@ routes.push({
67
66
  path: '/:no',
68
67
  component: () => import('./pages/play.vue'),
69
68
  })
70
-
71
- export const router = createRouter({
72
- history: __SLIDEV_HASH_ROUTE__
73
- ? createWebHashHistory(import.meta.env.BASE_URL)
74
- : createWebHistory(import.meta.env.BASE_URL),
75
- routes,
76
- })
@@ -1,8 +1,8 @@
1
- /* __imports__ */
2
1
  import { createSingletonPromise } from '@antfu/utils'
3
- import type { CodeRunner, CodeRunnerContext, CodeRunnerOutput, CodeRunnerOutputText, CodeRunnerOutputs, CodeRunnerProviders } from '@slidev/types'
2
+ import type { CodeRunner, CodeRunnerContext, CodeRunnerOutput, CodeRunnerOutputText, CodeRunnerOutputs } from '@slidev/types'
4
3
  import type { CodeToHastOptions } from 'shiki'
5
4
  import { isDark } from '../logic/dark'
5
+ import setups from '#slidev/setups/code-runners'
6
6
 
7
7
  export default createSingletonPromise(async () => {
8
8
  const runners: Record<string, CodeRunner> = {
@@ -48,15 +48,10 @@ export default createSingletonPromise(async () => {
48
48
  }
49
49
  }
50
50
 
51
- // @ts-expect-error injected in runtime
52
- // eslint-disable-next-line unused-imports/no-unused-vars
53
- const injection_arg = runners
54
- // eslint-disable-next-line prefer-const
55
- let injection_return: CodeRunnerProviders = {}
56
-
57
- /* __async_injections__ */
58
-
59
- Object.assign(runners, injection_return)
51
+ for (const setup of setups) {
52
+ const result = await setup(runners)
53
+ Object.assign(runners, result)
54
+ }
60
55
 
61
56
  return {
62
57
  highlight,
package/setup/main.ts CHANGED
@@ -1,10 +1,20 @@
1
- /* __imports__ */
2
-
3
1
  import type { AppContext } from '@slidev/types'
4
2
  import { MotionPlugin } from '@vueuse/motion'
5
3
  import TwoSlashFloatingVue from '@shikijs/vitepress-twoslash/client'
4
+ import type { App } from 'vue'
5
+ import { nextTick } from 'vue'
6
+ import { createRouter, createWebHashHistory, createWebHistory } from 'vue-router'
7
+ import { createHead } from '@unhead/vue'
8
+ import { routeForceRefresh } from '../logic/route'
9
+ import { createVClickDirectives } from '../modules/v-click'
10
+ import { createVMarkDirective } from '../modules/v-mark'
11
+ import { routes } from '../routes'
12
+ import setups from '#slidev/setups/main'
13
+
14
+ import '#slidev/styles'
15
+ import 'shiki-magic-move/style.css'
6
16
 
7
- export default function setupMain(context: AppContext) {
17
+ export default async function setupMain(app: App) {
8
18
  function setMaxHeight() {
9
19
  // disable the mobile navbar scroll
10
20
  // see https://css-tricks.com/the-trick-to-viewport-units-on-mobile/
@@ -13,12 +23,32 @@ export default function setupMain(context: AppContext) {
13
23
  setMaxHeight()
14
24
  window.addEventListener('resize', setMaxHeight)
15
25
 
16
- context.app.use(MotionPlugin)
17
- context.app.use(TwoSlashFloatingVue as any)
26
+ const router = createRouter({
27
+ history: __SLIDEV_HASH_ROUTE__
28
+ ? createWebHashHistory(import.meta.env.BASE_URL)
29
+ : createWebHistory(import.meta.env.BASE_URL),
30
+ routes,
31
+ })
32
+
33
+ app.use(router)
34
+ app.use(createHead())
35
+ app.use(createVClickDirectives())
36
+ app.use(createVMarkDirective())
37
+ app.use(MotionPlugin)
38
+ app.use(TwoSlashFloatingVue as any, { container: '#slideshow' })
39
+
40
+ const context: AppContext = {
41
+ app,
42
+ router,
43
+ }
18
44
 
19
- // @ts-expect-error inject in runtime
20
- // eslint-disable-next-line unused-imports/no-unused-vars
21
- const injection_arg = context
45
+ nextTick(() => {
46
+ router.afterEach(async () => {
47
+ await nextTick()
48
+ routeForceRefresh.value += 1
49
+ })
50
+ })
22
51
 
23
- /* __injections__ */
52
+ for (const setup of setups)
53
+ await setup(context)
24
54
  }
package/setup/mermaid.ts CHANGED
@@ -1,15 +1,14 @@
1
- /* __imports__ */
2
-
3
1
  import type { MermaidOptions } from '@slidev/types'
4
2
  import { defineMermaidSetup } from '@slidev/types'
3
+ import setups from '#slidev/setups/mermaid'
5
4
 
6
5
  export default defineMermaidSetup(() => {
7
- // eslint-disable-next-line prefer-const
8
- let injection_return: MermaidOptions = {
6
+ const setupReturn: MermaidOptions = {
9
7
  theme: 'default',
10
8
  }
11
9
 
12
- /* __injections__ */
10
+ for (const setup of setups)
11
+ Object.assign(setupReturn, setup())
13
12
 
14
- return injection_return
13
+ return setupReturn
15
14
  })
package/setup/monaco.ts CHANGED
@@ -22,8 +22,8 @@ import { StandaloneServices } from 'monaco-editor/esm/vs/editor/standalone/brows
22
22
 
23
23
  import { isDark } from '../logic/dark'
24
24
  import configs from '#slidev/configs'
25
+ import setups from '#slidev/setups/monaco'
25
26
 
26
- /* __imports__ */
27
27
  window.MonacoEnvironment = {
28
28
  getWorker(_, label) {
29
29
  if (label === 'json')
@@ -98,13 +98,11 @@ const setup = createSingletonPromise(async () => {
98
98
  const { shiki, themes, shikiToMonaco } = await import('#slidev/shiki')
99
99
  const highlighter = await shiki
100
100
 
101
- // @ts-expect-error injected in runtime
102
- // eslint-disable-next-line unused-imports/no-unused-vars
103
- const injection_arg = monaco
104
- // eslint-disable-next-line prefer-const
105
- let injection_return: MonacoSetupReturn = {}
106
-
107
- /* __async_injections__ */
101
+ const setupReturn: MonacoSetupReturn = {}
102
+ for (const setup of setups) {
103
+ const result = await setup(monaco)
104
+ Object.assign(setupReturn, result)
105
+ }
108
106
 
109
107
  // Use Shiki to highlight Monaco
110
108
  shikiToMonaco(highlighter, monaco)
@@ -122,7 +120,7 @@ const setup = createSingletonPromise(async () => {
122
120
  return {
123
121
  monaco,
124
122
  ata,
125
- ...injection_return,
123
+ ...setupReturn,
126
124
  }
127
125
  })
128
126
 
package/setup/root.ts CHANGED
@@ -1,27 +1,71 @@
1
- /* __imports__ */
2
- import { watch } from 'vue'
1
+ import { computed, getCurrentInstance, reactive, ref, shallowRef, watch } from 'vue'
3
2
  import { useHead } from '@unhead/vue'
3
+ import { useRouter } from 'vue-router'
4
4
  import { configs } from '../env'
5
5
  import { initSharedState, onPatch, patch } from '../state/shared'
6
6
  import { initDrawingState } from '../state/drawings'
7
- import { clicksContext, currentSlideNo, getSlidePath, hasPrimarySlide, isNotesViewer, isPresenter } from '../logic/nav'
8
- import { router } from '../routes'
9
- import { TRUST_ORIGINS } from '../constants'
10
- import { skipTransition } from '../composables/hmr'
7
+ import { TRUST_ORIGINS, injectionClicksContext, injectionCurrentPage, injectionRenderContext, injectionSlidevContext } from '../constants'
8
+ import { skipTransition } from '../logic/hmr'
11
9
  import { makeId } from '../logic/utils'
10
+ import { getSlidePath } from '../logic/slides'
11
+ import { createFixedClicks } from '../composables/useClicks'
12
+ import { isDark } from '../logic/dark'
13
+ import { useNav } from '../composables/useNav'
14
+ import setups from '#slidev/setups/root'
12
15
 
13
16
  export default function setupRoot() {
14
- // @ts-expect-error injected in runtime
15
- // eslint-disable-next-line unused-imports/no-unused-vars
16
- const injection_arg = undefined
17
+ const app = getCurrentInstance()!.appContext.app
17
18
 
18
- /* __injections__ */
19
+ const context = reactive({
20
+ nav: useNav(),
21
+ configs,
22
+ themeConfigs: computed(() => configs.themeConfig),
23
+ })
24
+ app.provide(injectionRenderContext, ref('none'))
25
+ app.provide(injectionSlidevContext, context)
26
+ app.provide(injectionCurrentPage, computed(() => context.nav.currentSlideNo))
27
+ app.provide(injectionClicksContext, shallowRef(createFixedClicks()))
28
+
29
+ // allows controls from postMessages
30
+ if (__DEV__) {
31
+ // @ts-expect-error expose global
32
+ window.__slidev__ = context
33
+ window.addEventListener('message', ({ data }) => {
34
+ if (data && data.target === 'slidev') {
35
+ if (data.type === 'navigate') {
36
+ context.nav.go(+data.no, +data.clicks || 0)
37
+ }
38
+ else if (data.type === 'css-vars') {
39
+ const root = document.documentElement
40
+ for (const [key, value] of Object.entries(data.vars || {}))
41
+ root.style.setProperty(key, value as any)
42
+ }
43
+ else if (data.type === 'color-schema') {
44
+ isDark.value = data.color === 'dark'
45
+ }
46
+ }
47
+ })
48
+ }
49
+
50
+ // User Setups
51
+ for (const setup of setups)
52
+ setup()
19
53
 
20
54
  const title = configs.titleTemplate.replace('%s', configs.title || 'Slidev')
55
+
56
+ const {
57
+ clicksContext,
58
+ currentSlideNo,
59
+ hasPrimarySlide,
60
+ isNotesViewer,
61
+ isPresenter,
62
+ } = useNav()
63
+
21
64
  useHead({
22
65
  title,
23
66
  htmlAttrs: configs.htmlAttrs,
24
67
  })
68
+
25
69
  initSharedState(`${title} - shared`)
26
70
  initDrawingState(`${title} - drawings`)
27
71
 
@@ -51,6 +95,7 @@ export default function setupRoot() {
51
95
  time: new Date().getTime(),
52
96
  })
53
97
  }
98
+ const router = useRouter()
54
99
  router.afterEach(updateSharedState)
55
100
  watch(clicksContext, updateSharedState)
56
101
 
@@ -60,7 +105,7 @@ export default function setupRoot() {
60
105
  if (state.lastUpdate?.type === 'presenter' && (+state.page !== +currentSlideNo.value || +clicksContext.value.current !== +state.clicks)) {
61
106
  skipTransition.value = false
62
107
  router.replace({
63
- path: getSlidePath(state.page),
108
+ path: getSlidePath(state.page, isPresenter.value),
64
109
  query: {
65
110
  ...router.currentRoute.value.query,
66
111
  clicks: state.clicks || 0,
@@ -1,19 +1,19 @@
1
- /* __imports__ */
2
1
  import { and, not, or } from '@vueuse/math'
3
2
  import type { NavOperations, ShortcutOptions } from '@slidev/types'
4
3
  import { downloadPDF } from '../utils'
5
- import { go, goFirst, goLast, next, nextSlide, prev, prevSlide } from '../logic/nav'
6
4
  import { toggleDark } from '../logic/dark'
7
5
  import { magicKeys, showGotoDialog, showOverview, toggleOverview } from '../state'
8
- import { drawingEnabled } from '../logic/drawings'
6
+ import { useNav } from '../composables/useNav'
7
+ import { useDrawings } from '../composables/useDrawings'
9
8
  import { currentOverviewPage, downOverviewPage, nextOverviewPage, prevOverviewPage, upOverviewPage } from './../logic/overview'
9
+ import setups from '#slidev/setups/shortcuts'
10
10
 
11
11
  export default function setupShortcuts() {
12
+ const { go, goFirst, goLast, next, nextSlide, prev, prevSlide } = useNav()
13
+ const { drawingEnabled } = useDrawings()
12
14
  const { escape, space, shift, left, right, up, down, enter, d, g, o, '`': backtick } = magicKeys
13
15
 
14
- // @ts-expect-error injected in runtime
15
- // eslint-disable-next-line unused-imports/no-unused-vars
16
- const injection_arg: NavOperations = {
16
+ const context: NavOperations = {
17
17
  next,
18
18
  prev,
19
19
  nextSlide,
@@ -29,8 +29,7 @@ export default function setupShortcuts() {
29
29
  showGotoDialog: () => showGotoDialog.value = !showGotoDialog.value,
30
30
  }
31
31
 
32
- // eslint-disable-next-line prefer-const
33
- let injection_return: ShortcutOptions[] = [
32
+ let shortcuts: ShortcutOptions[] = [
34
33
  { name: 'next_space', key: and(space, not(shift)), fn: next, autoRepeat: true },
35
34
  { name: 'prev_space', key: and(space, shift), fn: prev, autoRepeat: true },
36
35
  { name: 'next_right', key: and(right, not(shift), not(showOverview)), fn: next, autoRepeat: true },
@@ -59,11 +58,14 @@ export default function setupShortcuts() {
59
58
  },
60
59
  ]
61
60
 
62
- const baseShortcutNames = new Set(injection_return.map(s => s.name))
61
+ const baseShortcutNames = new Set(shortcuts.map(s => s.name))
63
62
 
64
- /* __chained_injections__ */
63
+ for (const setup of setups) {
64
+ const result = setup(context, shortcuts)
65
+ shortcuts = shortcuts.concat(result)
66
+ }
65
67
 
66
- const remainingBaseShortcutNames = injection_return.filter(s => s.name && baseShortcutNames.has(s.name))
68
+ const remainingBaseShortcutNames = shortcuts.filter(s => s.name && baseShortcutNames.has(s.name))
67
69
  if (remainingBaseShortcutNames.length === 0) {
68
70
  const message = [
69
71
  '========== WARNING ==========',
@@ -77,5 +79,5 @@ export default function setupShortcuts() {
77
79
  console.warn(message)
78
80
  }
79
81
 
80
- return injection_return
82
+ return shortcuts
81
83
  }
@@ -11,7 +11,7 @@
11
11
  }
12
12
 
13
13
  .twoslash-popup-container {
14
- font-size: calc(13px * var(--slidev-slide-scale, 1));
14
+ font-size: 13px;
15
15
  }
16
16
 
17
17
  .twoslash-popup-container .twoslash-popup-code {
@@ -1,12 +0,0 @@
1
- import { computed } from 'vue'
2
- import { configs } from '../env'
3
- import type { SlidevContext } from '../modules/context'
4
- import * as nav from '../logic/nav'
5
-
6
- export function useContext(): SlidevContext {
7
- return {
8
- nav: { ...nav }, // Convert the module to a plain object
9
- configs,
10
- themeConfigs: computed(() => configs.themeConfig),
11
- }
12
- }
package/logic/drawings.ts DELETED
@@ -1,161 +0,0 @@
1
- import { computed, markRaw, nextTick, reactive, ref, watch } from 'vue'
2
- import type { Brush, Options as DrauuOptions, DrawingMode } from 'drauu'
3
- import { createDrauu } from 'drauu'
4
- import { toReactive, useLocalStorage } from '@vueuse/core'
5
- import { drawingState, onPatch, patch } from '../state/drawings'
6
- import { configs } from '../env'
7
- import { isInputting } from '../state'
8
- import { currentSlideNo, isPresenter } from './nav'
9
-
10
- export const brushColors = [
11
- '#ff595e',
12
- '#ffca3a',
13
- '#8ac926',
14
- '#1982c4',
15
- '#6a4c93',
16
- '#ffffff',
17
- '#000000',
18
- ]
19
-
20
- export const drawingEnabled = useLocalStorage('slidev-drawing-enabled', false)
21
- export const drawingPinned = useLocalStorage('slidev-drawing-pinned', false)
22
- export const canUndo = ref(false)
23
- export const canRedo = ref(false)
24
- export const canClear = ref(false)
25
- export const isDrawing = ref(false)
26
-
27
- export const brush = toReactive(useLocalStorage<Brush>('slidev-drawing-brush', {
28
- color: brushColors[0],
29
- size: 4,
30
- mode: 'stylus',
31
- }))
32
-
33
- const _mode = ref<DrawingMode | 'arrow'>('stylus')
34
- const syncUp = computed(() => configs.drawings.syncAll || isPresenter.value)
35
- let disableDump = false
36
-
37
- export const drawingMode = computed({
38
- get() {
39
- return _mode.value
40
- },
41
- set(v: DrawingMode | 'arrow') {
42
- _mode.value = v
43
- if (v === 'arrow') {
44
- // eslint-disable-next-line ts/no-use-before-define
45
- drauu.mode = 'line'
46
- brush.arrowEnd = true
47
- }
48
- else {
49
- // eslint-disable-next-line ts/no-use-before-define
50
- drauu.mode = v
51
- brush.arrowEnd = false
52
- }
53
- },
54
- })
55
-
56
- export const drauuOptions: DrauuOptions = reactive({
57
- brush,
58
- acceptsInputTypes: computed(() => (drawingEnabled.value && (!configs.drawings.presenterOnly || isPresenter.value)) ? undefined : ['pen' as const]),
59
- coordinateTransform: false,
60
- })
61
- export const drauu = markRaw(createDrauu(drauuOptions))
62
-
63
- export function clearDrauu() {
64
- drauu.clear()
65
- if (syncUp.value)
66
- patch(currentSlideNo.value, '')
67
- }
68
-
69
- export function updateState() {
70
- canRedo.value = drauu.canRedo()
71
- canUndo.value = drauu.canUndo()
72
- canClear.value = !!drauu.el?.children.length
73
- }
74
-
75
- export function loadCanvas(page?: number) {
76
- disableDump = true
77
- const data = drawingState[page || currentSlideNo.value]
78
- if (data != null)
79
- drauu.load(data)
80
- else
81
- drauu.clear()
82
- updateState()
83
- disableDump = false
84
- }
85
-
86
- drauu.on('changed', () => {
87
- updateState()
88
- if (!disableDump) {
89
- const dump = drauu.dump()
90
- const key = currentSlideNo.value
91
- if ((drawingState[key] || '') !== dump && syncUp.value)
92
- patch(key, drauu.dump())
93
- }
94
- })
95
-
96
- onPatch((state) => {
97
- disableDump = true
98
- if (state[currentSlideNo.value] != null)
99
- drauu.load(state[currentSlideNo.value] || '')
100
- disableDump = false
101
- updateState()
102
- })
103
-
104
- nextTick(() => {
105
- watch(currentSlideNo, () => {
106
- if (!drauu.mounted)
107
- return
108
- loadCanvas()
109
- }, { immediate: true })
110
- })
111
-
112
- drauu.on('start', () => isDrawing.value = true)
113
- drauu.on('end', () => isDrawing.value = false)
114
-
115
- window.addEventListener('keydown', (e) => {
116
- if (!drawingEnabled.value || isInputting.value)
117
- return
118
-
119
- const noModifier = !e.ctrlKey && !e.altKey && !e.shiftKey && !e.metaKey
120
- let handled = true
121
- if (e.code === 'KeyZ' && (e.ctrlKey || e.metaKey)) {
122
- if (e.shiftKey)
123
- drauu.redo()
124
- else
125
- drauu.undo()
126
- }
127
- else if (e.code === 'Escape') {
128
- drawingEnabled.value = false
129
- }
130
- else if (e.code === 'KeyL' && noModifier) {
131
- drawingMode.value = 'line'
132
- }
133
- else if (e.code === 'KeyA' && noModifier) {
134
- drawingMode.value = 'arrow'
135
- }
136
- else if (e.code === 'KeyS' && noModifier) {
137
- drawingMode.value = 'stylus'
138
- }
139
- else if (e.code === 'KeyR' && noModifier) {
140
- drawingMode.value = 'rectangle'
141
- }
142
- else if (e.code === 'KeyE' && noModifier) {
143
- drawingMode.value = 'ellipse'
144
- }
145
- else if (e.code === 'KeyC' && noModifier) {
146
- clearDrauu()
147
- }
148
- else if (e.code.startsWith('Digit') && noModifier && +e.code[5] <= brushColors.length) {
149
- brush.color = brushColors[+e.code[5] - 1]
150
- }
151
- else {
152
- handled = false
153
- }
154
-
155
- if (handled) {
156
- e.preventDefault()
157
- e.stopPropagation()
158
- }
159
- }, false)
160
-
161
- export { drawingState }
@@ -1,20 +0,0 @@
1
- import { computed } from 'vue'
2
- import { logicOr } from '@vueuse/math'
3
- import { configs } from '../env'
4
- import { router } from '../routes'
5
- import { getSlide, slides } from './slides'
6
-
7
- export const currentRoute = computed(() => router.currentRoute.value)
8
-
9
- export const isPrintMode = computed(() => currentRoute.value.query.print !== undefined)
10
- export const isPrintWithClicks = computed(() => currentRoute.value.query.print === 'clicks')
11
- export const isEmbedded = computed(() => currentRoute.value.query.embedded !== undefined)
12
- export const isPlaying = computed(() => currentRoute.value.name === 'play')
13
- export const isPresenter = computed(() => currentRoute.value.name === 'presenter')
14
- export const isNotesViewer = computed(() => currentRoute.value.name === 'notes')
15
- export const isPresenterAvailable = computed(() => !isPresenter.value && (!configs.remote || currentRoute.value.query.password === configs.remote))
16
-
17
- export const hasPrimarySlide = logicOr(isPlaying, isPresenter)
18
-
19
- export const currentSlideNo = computed(() => hasPrimarySlide.value ? getSlide(currentRoute.value.params.no as string)?.no ?? 1 : 1)
20
- export const currentSlideRoute = computed(() => slides.value[currentSlideNo.value - 1])
package/logic/nav.ts DELETED
@@ -1,71 +0,0 @@
1
- import { computed, watch } from 'vue'
2
- import { router } from '../routes'
3
- import { usePrimaryClicks } from '../composables/useClicks'
4
- import { CLICKS_MAX } from '../constants'
5
- import { useNavBase } from '../composables/useNav'
6
- import { useRouteQuery } from './route'
7
- import { currentRoute, currentSlideRoute, hasPrimarySlide } from './nav-state'
8
- import { getSlide } from './slides'
9
-
10
- export * from './slides'
11
- export * from './nav-state'
12
-
13
- export const clicksContext = computed(() => usePrimaryClicks(currentSlideRoute.value))
14
-
15
- const queryClicksRaw = useRouteQuery('clicks', '0')
16
- export const queryClicks = computed({
17
- get() {
18
- if (clicksContext.value.disabled)
19
- return CLICKS_MAX
20
- let v = +(queryClicksRaw.value || 0)
21
- if (Number.isNaN(v))
22
- v = 0
23
- return v
24
- },
25
- set(v) {
26
- queryClicksRaw.value = v.toString()
27
- },
28
- })
29
-
30
- export const {
31
- slides,
32
- total,
33
- currentPath,
34
- currentSlideNo,
35
- currentPage,
36
- currentLayout,
37
- currentTransition,
38
- clicksDirection,
39
- nextRoute,
40
- prevRoute,
41
- clicks,
42
- clicksTotal,
43
- hasNext,
44
- hasPrev,
45
- tocTree,
46
- navDirection,
47
- openInEditor,
48
- next,
49
- prev,
50
- go,
51
- goLast,
52
- goFirst,
53
- nextSlide,
54
- prevSlide,
55
- } = useNavBase(
56
- currentSlideRoute,
57
- clicksContext,
58
- queryClicks,
59
- router,
60
- )
61
-
62
- watch(
63
- [total, currentRoute],
64
- async () => {
65
- if (hasPrimarySlide.value && !getSlide(currentRoute.value.params.no as string)) {
66
- // The current slide may has been removed. Redirect to the last slide.
67
- await goLast()
68
- }
69
- },
70
- { flush: 'pre', immediate: true },
71
- )
package/setup/prettier.ts DELETED
@@ -1,43 +0,0 @@
1
- import { format } from 'prettier'
2
-
3
- export async function formatCode(code: string, lang: string) {
4
- try {
5
- let parser = 'babel'
6
- let plugins: any[] = []
7
-
8
- switch (lang) {
9
- case 'ts':
10
- case 'typescript':
11
- parser = 'typescript'
12
- plugins = [
13
- (await import('prettier/plugins/babel')).default,
14
- (await import('prettier/plugins/typescript')).default,
15
- ]
16
- break
17
- case 'html':
18
- parser = 'html'
19
- plugins = [
20
- (await import('prettier/plugins/html')).default,
21
- ]
22
- break
23
- default:
24
- parser = 'babel'
25
- plugins = [
26
- (await import('prettier/plugins/babel')).default,
27
- ]
28
- }
29
-
30
- return format(code, {
31
- semi: false,
32
- singleQuote: true,
33
- tabWidth: 2,
34
- useTabs: false,
35
- parser,
36
- plugins,
37
- })
38
- }
39
- catch (e) {
40
- console.error(e)
41
- return code
42
- }
43
- }
File without changes
File without changes