d394e1cd9b
* better workspace feature flag ops * user activity is correctly tracked * more fixes
99 lines
2.7 KiB
Vue
99 lines
2.7 KiB
Vue
<template>
|
|
<div
|
|
class="flex items-center rounded-xl bg-foundation border border-outline-3 shadow-md overflow-hidden h-10 p-[3px]"
|
|
:class="{ hidden: hideUi }"
|
|
>
|
|
<PresentationControlsButton
|
|
:icon="LucideChevronLeft"
|
|
:disabled="disablePrevious"
|
|
tooltip="Previous slide"
|
|
@click="onPrevious"
|
|
/>
|
|
<PresentationControlsButton
|
|
:icon="LucideRotateCcw"
|
|
:disabled="!hasViewChanged"
|
|
tooltip="Reset slide"
|
|
@click="resetView"
|
|
/>
|
|
<PresentationControlsButton
|
|
:icon="LucideChevronRight"
|
|
:disabled="disableNext"
|
|
tooltip="Next slide"
|
|
@click="onNext"
|
|
/>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import { LucideChevronLeft, LucideChevronRight, LucideRotateCcw } from 'lucide-vue-next'
|
|
import { useInjectedPresentationState } from '~/lib/presentations/composables/setup'
|
|
import { clamp } from 'lodash-es'
|
|
import { useEventListener } from '@vueuse/core'
|
|
import { useResetViewUtils } from '~/lib/presentations/composables/utils'
|
|
|
|
defineProps<{
|
|
hideUi?: boolean
|
|
}>()
|
|
|
|
const {
|
|
ui: { slideIdx: currentVisibleIndex, slideCount },
|
|
viewer: { hasViewChanged }
|
|
} = useInjectedPresentationState()
|
|
const { resetView } = useResetViewUtils()
|
|
|
|
const disablePrevious = computed(() => currentVisibleIndex.value === 0)
|
|
const disableNext = computed(() =>
|
|
slideCount.value ? currentVisibleIndex.value === slideCount.value - 1 : false
|
|
)
|
|
const onPrevious = () => {
|
|
currentVisibleIndex.value = clamp(currentVisibleIndex.value - 1, 0, slideCount.value)
|
|
}
|
|
const onNext = () => {
|
|
currentVisibleIndex.value = clamp(currentVisibleIndex.value + 1, 0, slideCount.value)
|
|
}
|
|
|
|
// Prevent viewer from moving when using arrow keys
|
|
useEventListener(
|
|
'keydown',
|
|
(event) => {
|
|
// Don't handle arrow keys if an input element is focused
|
|
if (
|
|
event.target instanceof HTMLInputElement ||
|
|
event.target instanceof HTMLTextAreaElement
|
|
)
|
|
return
|
|
|
|
// Don't handle arrow keys if a dialog is open
|
|
if (document.querySelector('[role="dialog"]')) {
|
|
event.preventDefault()
|
|
event.stopPropagation()
|
|
event.stopImmediatePropagation()
|
|
return
|
|
}
|
|
|
|
const targetKeys = ['ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown']
|
|
|
|
if (targetKeys.includes(event.key)) {
|
|
event.preventDefault()
|
|
event.stopPropagation()
|
|
event.stopImmediatePropagation()
|
|
|
|
// Remove focus from any currently focused element to prevent blue outline
|
|
if (document.activeElement instanceof HTMLElement) {
|
|
document.activeElement.blur()
|
|
}
|
|
}
|
|
if (event.key === 'ArrowLeft') {
|
|
if (disablePrevious.value) return
|
|
onPrevious()
|
|
}
|
|
|
|
if (event.key === 'ArrowRight') {
|
|
if (disableNext.value) return
|
|
onNext()
|
|
}
|
|
},
|
|
{ capture: true }
|
|
)
|
|
</script>
|