Skip to content

Commit

Permalink
refactor: allow set current in ClicksContext
Browse files Browse the repository at this point in the history
  • Loading branch information
antfu committed Feb 25, 2024
1 parent 5d835b8 commit 914baf0
Show file tree
Hide file tree
Showing 12 changed files with 59 additions and 42 deletions.
29 changes: 18 additions & 11 deletions packages/client/composables/useClicks.ts
@@ -1,16 +1,13 @@
import { sum } from '@antfu/utils'
import type { ClicksContext } from '@slidev/types'
import type { Ref } from 'vue'
import { ref, shallowReactive } from 'vue'
import { computed, ref, shallowReactive } from 'vue'
import type { RouteRecordRaw } from 'vue-router'
import { currentRoute, isPrintMode, isPrintWithClicks, queryClicks, routeForceRefresh } from '../logic/nav'
import { normalizeAtProp } from '../logic/utils'
import { CLICKS_MAX } from '../constants'

/**
* @internal
*/
export function useClicksContextBase(getCurrent: () => number, clicksOverrides?: number): ClicksContext {
function useClicksContextBase(current: Ref<number>, clicksOverrides?: number): ClicksContext {
const relativeOffsets: ClicksContext['relativeOffsets'] = new Map()
const map: ClicksContext['map'] = shallowReactive(new Map())

Expand All @@ -19,7 +16,10 @@ export function useClicksContextBase(getCurrent: () => number, clicksOverrides?:
return isPrintMode.value && !isPrintWithClicks.value
},
get current() {
return getCurrent()
return current.value
},
set current(value) {
current.value = value
},
relativeOffsets,
map,
Expand Down Expand Up @@ -67,8 +67,8 @@ export function usePrimaryClicks(route: RouteRecordRaw | undefined): ClicksConte
if (route?.meta?.__clicksContext)
return route.meta.__clicksContext
const thisPath = +(route?.path ?? CLICKS_MAX)
const context = useClicksContextBase(
() => {
const current = computed({
get() {
const currentPath = +(currentRoute.value?.path ?? CLICKS_MAX)
if (currentPath === thisPath)
return queryClicks.value
Expand All @@ -77,14 +77,21 @@ export function usePrimaryClicks(route: RouteRecordRaw | undefined): ClicksConte
else
return 0
},
set(v) {
const currentPath = +(currentRoute.value?.path ?? CLICKS_MAX)
if (currentPath === thisPath)
queryClicks.value = v
},
})
const context = useClicksContextBase(
current,
route?.meta?.clicks,
)
if (route?.meta)
route.meta.__clicksContext = context
return context
}

export function useFixedClicks(route?: RouteRecordRaw | undefined, currentInit = 0): [Ref<number>, ClicksContext] {
const current = ref(currentInit)
return [current, useClicksContextBase(() => current.value, route?.meta?.clicks)]
export function useFixedClicks(route?: RouteRecordRaw | undefined, currentInit = 0): ClicksContext {
return useClicksContextBase(ref(currentInit), route?.meta?.clicks)
}
2 changes: 1 addition & 1 deletion packages/client/context.ts
Expand Up @@ -12,7 +12,7 @@ import {
injectionSlidevContext,
} from './constants'

const clicksContextFallback = shallowRef(useFixedClicks()[1])
const clicksContextFallback = shallowRef(useFixedClicks())

/**
* Get the current slide context, should be called inside the setup function of a component inside slide
Expand Down
13 changes: 7 additions & 6 deletions packages/client/internals/NoteDisplay.vue
@@ -1,25 +1,26 @@
<script setup lang="ts">
import { computed, nextTick, onMounted, ref, watch } from 'vue'
import type { ClicksContext } from '@slidev/types'
import { CLICKS_MAX } from '../constants'
const props = defineProps<{
class?: string
noteHtml?: string
note?: string
placeholder?: string
clicks?: number | string
clicksContext?: ClicksContext
}>()
defineEmits(['click'])
const withClicks = computed(() => props.clicks != null && props.noteHtml?.includes('slidev-note-click-mark'))
const withClicks = computed(() => props.clicksContext?.current != null && props.noteHtml?.includes('slidev-note-click-mark'))
const noteDisplay = ref<HTMLElement | null>(null)
function highlightNote() {
if (!noteDisplay.value || !withClicks.value || props.clicks == null)
if (!noteDisplay.value || !withClicks.value || props.clicksContext?.current == null)
return
const disabled = +props.clicks < 0 || +props.clicks >= CLICKS_MAX
const disabled = +props.clicksContext?.current < 0 || +props.clicksContext?.current >= CLICKS_MAX
if (disabled) {
Array.from(noteDisplay.value.querySelectorAll('*'))
.forEach(el => el.classList.remove('slidev-note-fade'))
Expand Down Expand Up @@ -71,13 +72,13 @@ function highlightNote() {
'slidev-note-fade',
nodeToIgnores.has(el)
? false
: +count !== +props.clicks!,
: +count !== +props.clicksContext!.current!,
))
}
}
watch(
() => [props.noteHtml, props.clicks],
() => [props.noteHtml, props.clicksContext?.current],
() => {
nextTick(() => {
highlightNote()
Expand Down
8 changes: 5 additions & 3 deletions packages/client/internals/NoteEditor.vue
@@ -1,6 +1,8 @@
<script setup lang="ts">
import type { PropType } from 'vue'
import { nextTick, ref, watch, watchEffect } from 'vue'
import { ignorableWatch, onClickOutside, useVModel } from '@vueuse/core'
import type { ClicksContext } from '@slidev/types'
import { useDynamicSlideInfo } from '../logic/note'
import NoteDisplay from './NoteDisplay.vue'
Expand All @@ -20,8 +22,8 @@ const props = defineProps({
placeholder: {
default: 'No notes for this slide',
},
clicks: {
type: [Number, String],
clicksContext: {
type: Object as PropType<ClicksContext>,
},
autoHeight: {
default: false,
Expand Down Expand Up @@ -103,7 +105,7 @@ watch(
:style="props.style"
:note="note || placeholder"
:note-html="info?.noteHTML"
:clicks="props.clicks"
:clicks-context="clicksContext"
/>
<textarea
v-else
Expand Down
5 changes: 3 additions & 2 deletions packages/client/internals/NoteStatic.vue
@@ -1,11 +1,12 @@
<script setup lang="ts">
import type { ClicksContext } from 'packages/types'
import { useSlideInfo } from '../logic/note'
import NoteDisplay from './NoteDisplay.vue'
const props = defineProps<{
no?: number
class?: string
clicks?: number | string
clicksContext?: ClicksContext
}>()
const { info } = useSlideInfo(props.no)
Expand All @@ -16,6 +17,6 @@ const { info } = useSlideInfo(props.no)
:class="props.class"
:note="info?.note"
:note-html="info?.noteHTML"
:clicks="props.clicks"
:clicks-context="clicksContext"
/>
</template>
9 changes: 4 additions & 5 deletions packages/client/internals/OverviewClicksSlider.vue
@@ -1,21 +1,20 @@
<script setup lang="ts">
import type { ClicksContext } from '@slidev/types'
import type { Ref } from 'vue'
import { computed } from 'vue'
import { CLICKS_MAX } from '../constants'
const props = defineProps<{
clickContext: [Ref<number>, ClicksContext]
clicksContext: ClicksContext
}>()
const total = computed(() => props.clickContext[1].total)
const total = computed(() => props.clicksContext.total)
const current = computed({
get() {
return props.clickContext[0].value > total.value ? -1 : props.clickContext[0].value
return props.clicksContext.current > total.value ? -1 : props.clicksContext.current
},
set(value: number) {
// eslint-disable-next-line vue/no-mutating-props
props.clickContext[0].value = value
props.clicksContext.current = value
},
})
Expand Down
10 changes: 8 additions & 2 deletions packages/client/internals/PrintSlide.vue
Expand Up @@ -9,7 +9,7 @@ const props = defineProps<{ route: RouteRecordRaw }>()
const route = computed(() => props.route)
const nav = useNav(route)
const clicks0 = useFixedClicks(route.value, 0)[1]
const clicks0 = useFixedClicks(route.value, 0)
</script>

<template>
Expand All @@ -19,6 +19,12 @@ const clicks0 = useFixedClicks(route.value, 0)[1]
:route="route"
/>
<template v-if="!clicks0.disabled">
<PrintSlideClick v-for="i of clicks0.total" :key="i" :clicks-context="useFixedClicks(route, i)[1]" :nav="nav" :route="route" />
<PrintSlideClick
v-for="i of clicks0.total"
:key="i"
:clicks-context="useFixedClicks(route, i)"
:nav="nav"
:route="route"
/>
</template>
</template>
2 changes: 1 addition & 1 deletion packages/client/internals/SlidesOverview.vue
Expand Up @@ -140,7 +140,7 @@ watchEffect(() => {
<SlideWrapper
:is="route.component"
v-if="route?.component"
:clicks-context="useFixedClicks(route, CLICKS_MAX)[1]"
:clicks-context="useFixedClicks(route, CLICKS_MAX)"
:class="getSlideClass(route)"
:route="route"
render-context="overview"
Expand Down
13 changes: 6 additions & 7 deletions packages/client/pages/overview.vue
@@ -1,5 +1,4 @@
<script setup lang="ts">
import type { Ref } from 'vue'
import { computed, nextTick, onMounted, reactive, ref } from 'vue'
import { useHead } from '@unhead/vue'
import type { RouteRecordRaw } from 'vue-router'
Expand Down Expand Up @@ -30,16 +29,16 @@ const wordCounts = computed(() => rawRoutes.map(route => wordCount(route.meta?.s
const totalWords = computed(() => wordCounts.value.reduce((a, b) => a + b, 0))
const totalClicks = computed(() => rawRoutes.map(route => getSlideClicks(route)).reduce((a, b) => a + b, 0))
const clicksContextMap = new WeakMap<RouteRecordRaw, [Ref<number>, ClicksContext]>()
function getClickContext(route: RouteRecordRaw) {
const clicksContextMap = new WeakMap<RouteRecordRaw, ClicksContext>()
function getClicksContext(route: RouteRecordRaw) {
// We create a local clicks context to calculate the total clicks of the slide
if (!clicksContextMap.has(route))
clicksContextMap.set(route, useFixedClicks(route, CLICKS_MAX))
return clicksContextMap.get(route)!
}
function getSlideClicks(route: RouteRecordRaw) {
return route.meta?.clicks || getClickContext(route)?.[1]?.total
return route.meta?.clicks || getClicksContext(route)?.total
}
function wordCount(str: string) {
Expand Down Expand Up @@ -152,7 +151,7 @@ onMounted(() => {
<SlideWrapper
:is="route.component"
v-if="route?.component"
:clicks-context="getClickContext(route)[1]"
:clicks-context="getClicksContext(route)"
:class="getSlideClass(route)"
:route="route"
render-context="overview"
Expand All @@ -163,7 +162,7 @@ onMounted(() => {
<OverviewClicksSlider
v-if="getSlideClicks(route)"
mt-2
:click-context="getClickContext(route)"
:clicks-context="getClicksContext(route)"
class="w-full"
/>
</div>
Expand All @@ -182,7 +181,7 @@ onMounted(() => {
class="max-w-250 w-250 text-lg rounded p3"
:auto-height="true"
:editing="edittingNote === idx"
:clicks="getClickContext(route)[0].value"
:clicks="getClicksContext(route).current"
@dblclick="edittingNote !== idx ? edittingNote = idx : null"
@update:editing="edittingNote = null"
/>
Expand Down
4 changes: 2 additions & 2 deletions packages/client/pages/presenter.vue
Expand Up @@ -49,7 +49,7 @@ const nextFrameClicksCtx = computed(() => {
return nextFrame.value && clicksCtxMap[+nextFrame.value[0].path - 1]
})
watch([currentRoute, queryClicks], () => {
nextFrameClicksCtx.value && (nextFrameClicksCtx.value[0].value = nextFrame.value![1])
nextFrameClicksCtx.value && (nextFrameClicksCtx.value.current = nextFrame.value![1])
}, { immediate: true })
const Editor = shallowRef<any>()
Expand Down Expand Up @@ -123,7 +123,7 @@ onMounted(() => {
<SlideWrapper
:is="nextFrame[0].component as any"
:key="nextFrame[0].path"
:clicks-context="nextFrameClicksCtx[1]"
:clicks-context="nextFrameClicksCtx"
:class="getSlideClass(nextFrame[0])"
:route="nextFrame[0]"
render-context="previewNext"
Expand Down
4 changes: 3 additions & 1 deletion packages/slidev/node/cli.ts
Expand Up @@ -569,13 +569,15 @@ function printInfo(
const query = remote ? `?password=${remote}` : ''
const presenterPath = `${options.data.config.routerMode === 'hash' ? '/#/' : '/'}presenter/${query}`
const entryPath = `${options.data.config.routerMode === 'hash' ? '/#/' : '/'}entry${query}/`
const overviewPath = `${options.data.config.routerMode === 'hash' ? '/#/' : '/'}overview${query}/`
console.log()
console.log(`${dim(' public slide show ')} > ${cyan(`http://localhost:${bold(port)}/`)}`)
if (query)
console.log(`${dim(' private slide show ')} > ${cyan(`http://localhost:${bold(port)}/${query}`)}`)
console.log(`${dim(' presenter mode ')} > ${blue(`http://localhost:${bold(port)}${presenterPath}`)}`)
console.log(`${dim(' slides overview ')} > ${blue(`http://localhost:${bold(port)}${overviewPath}`)}`)
if (options.inspect)
console.log(`${dim(' inspector')} > ${yellow(`http://localhost:${bold(port)}/__inspect/`)}`)
console.log(`${dim(' vite inspector')} > ${yellow(`http://localhost:${bold(port)}/__inspect/`)}`)

let lastRemoteUrl = ''

Expand Down
2 changes: 1 addition & 1 deletion packages/types/src/types.ts
Expand Up @@ -143,8 +143,8 @@ export type ResolvedClicksInfo = Required<ClicksInfo>
export type ClicksMap = Map<ClicksElement, ClicksInfo>

export interface ClicksContext {
current: number
readonly disabled: boolean
readonly current: number
readonly relativeOffsets: ClicksRelativeEls
readonly map: ClicksMap
resolve: (at: string | number, size?: number) => {
Expand Down

0 comments on commit 914baf0

Please sign in to comment.