diff --git a/packages/client/composables/useTimer.ts b/packages/client/composables/useTimer.ts new file mode 100644 index 0000000000..1d04c89ad5 --- /dev/null +++ b/packages/client/composables/useTimer.ts @@ -0,0 +1,20 @@ +import { useInterval } from '@vueuse/core' +import { computed } from 'vue' + +export function useTimer() { + const { counter, isActive, reset, pause, resume } = useInterval(1000, { controls: true }) + + const timer = computed(() => { + const passed = counter.value + const sec = Math.floor(passed % 60).toString().padStart(2, '0') + const min = Math.floor(passed / 60).toString().padStart(2, '0') + return `${min}:${sec}` + }) + + return { + timer, + isTimerAvctive: isActive, + resetTimer: reset, + toggleTimer: () => (isActive.value ? pause() : resume()), + } +} diff --git a/packages/client/logic/utils.ts b/packages/client/logic/utils.ts index c5228b1e5d..313833dc0d 100644 --- a/packages/client/logic/utils.ts +++ b/packages/client/logic/utils.ts @@ -1,27 +1,4 @@ import { parseRangeString } from '@slidev/parser/core' -import { useTimestamp } from '@vueuse/core' -import { computed, ref } from 'vue' - -export function useTimer() { - const tsStart = ref(Date.now()) - const now = useTimestamp({ - interval: 1000, - }) - const timer = computed(() => { - const passed = (now.value - tsStart.value) / 1000 - const sec = Math.floor(passed % 60).toString().padStart(2, '0') - const min = Math.floor(passed / 60).toString().padStart(2, '0') - return `${min}:${sec}` - }) - function resetTimer() { - tsStart.value = now.value - } - - return { - timer, - resetTimer, - } -} export function makeId(length = 5) { const result = [] diff --git a/packages/client/pages/presenter.vue b/packages/client/pages/presenter.vue index 466236e2ce..52c4b14417 100644 --- a/packages/client/pages/presenter.vue +++ b/packages/client/pages/presenter.vue @@ -6,6 +6,7 @@ import { createFixedClicks } from '../composables/useClicks' import { useDrawings } from '../composables/useDrawings' import { useNav } from '../composables/useNav' import { useSwipeControls } from '../composables/useSwipeControls' +import { useTimer } from '../composables/useTimer' import { useWakeLock } from '../composables/useWakeLock' import { slidesTitle } from '../env' import ClicksSlider from '../internals/ClicksSlider.vue' @@ -22,7 +23,6 @@ import SlidesShow from '../internals/SlidesShow.vue' import SlideWrapper from '../internals/SlideWrapper.vue' import { onContextMenu } from '../logic/contextMenu' import { registerShortcuts } from '../logic/shortcuts' -import { useTimer } from '../logic/utils' import { decreasePresenterFontSize, increasePresenterFontSize, presenterLayout, presenterNotesFontSize, showEditor, showPresenterCursor } from '../state' import { sharedState } from '../state/shared' @@ -49,7 +49,7 @@ useHead({ title: `Presenter - ${slidesTitle}` }) const notesEditing = ref(false) -const { timer, resetTimer } = useTimer() +const { timer, isTimerAvctive, resetTimer, toggleTimer } = useTimer() const clicksCtxMap = computed(() => slides.value.map(route => createFixedClicks(route))) const nextFrame = computed(() => { @@ -184,16 +184,22 @@ onMounted(() => {
-
- - -
-
- {{ timer }} +
+
+ +
+
+ + +
+
+ +
+
+
+
+ {{ timer }} +
@@ -215,13 +221,6 @@ onMounted(() => { --slidev-controls-foreground: current; } -.timer-btn:hover > :first-child { - opacity: 0; -} -.timer-btn:hover > :last-child { - opacity: 1; -} - .grid-container { --uno: bg-gray/20; height: 100%;