Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: uniform client features enablement #1587

Draft
wants to merge 4 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion packages/client/composables/useDragElements.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { activeDragElement } from '../state'
import { directiveInject } from '../utils'
import { useSlideBounds } from './useSlideBounds'
import { useDynamicSlideInfo } from './useSlideInfo'
import { useFeatures } from './useFeatures'

export type DragElementDataSource = 'frontmatter' | 'prop' | 'directive'
/**
Expand All @@ -21,7 +22,8 @@ export type DragElementsUpdater = (id: string, posStr: string, type: DragElement
const map: Record<number, DragElementsUpdater> = {}

export function useDragElementsUpdater(no: number) {
if (!(__DEV__ && __SLIDEV_FEATURE_EDITOR__))
const features = useFeatures()
if (!features.editor)
return () => {}

if (map[no])
Expand Down
35 changes: 35 additions & 0 deletions packages/client/composables/useFeatures.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { createSharedComposable } from '@vueuse/core'
import { computed, reactive } from 'vue'
import { configs } from '../env'
import { useRouteQuery } from '../logic/route'
import { useNav } from './useNav'

function satisfiesMode(mode: boolean | string) {
return mode === true || mode === __MODE__
}

export const staticFeatures = {
record: satisfiesMode(configs.record),
presenter: satisfiesMode(configs.presenter),
contextMenu: configs.contextMenu === true || configs.contextMenu === undefined || configs.contextMenu === __MODE__,
}

export const useFeatures = createSharedComposable(() => {
const { isPresenter, isEmbedded } = useNav()

const password = useRouteQuery<string>('password')
const trusted = computed(() => !configs.remote || password.value === configs.remote)

const drawings = computed(() => satisfiesMode(configs.drawings.enabled) && !isEmbedded.value)
const allowToDraw = computed(() => drawings.value && trusted.value && (!configs.drawings.presenterOnly || isPresenter.value) && !isEmbedded.value)
const editor = computed(() => configs.editor && trusted.value && __MODE__ === 'dev')
const enterPresenter = computed(() => staticFeatures.presenter && !isPresenter.value && trusted.value)

return reactive({
...staticFeatures,
drawings,
allowToDraw,
editor,
enterPresenter,
})
})
4 changes: 0 additions & 4 deletions packages/client/composables/useNav.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import { getCurrentTransition } from '../logic/transition'
import { getSlide, getSlidePath } from '../logic/slides'
import { CLICKS_MAX } from '../constants'
import { skipTransition } from '../logic/hmr'
import { configs } from '../env'
import { useRouteQuery } from '../logic/route'
import { useTocTree } from './useTocTree'
import { createClicksContextBase } from './useClicks'
Expand Down Expand Up @@ -76,7 +75,6 @@ export interface SlidevContextNavState {
isPlaying: ComputedRef<boolean>
isPresenter: ComputedRef<boolean>
isNotesViewer: ComputedRef<boolean>
isPresenterAvailable: ComputedRef<boolean>
hasPrimarySlide: ComputedRef<boolean>
currentSlideNo: ComputedRef<number>
currentSlideRoute: ComputedRef<SlideRoute>
Expand Down Expand Up @@ -281,7 +279,6 @@ const useNavState = createSharedComposable((): SlidevContextNavState => {
const isPlaying = computed(() => currentRoute.value.name === 'play')
const isPresenter = computed(() => currentRoute.value.name === 'presenter')
const isNotesViewer = computed(() => currentRoute.value.name === 'notes')
const isPresenterAvailable = computed(() => !isPresenter.value && (!configs.remote || query.value.get('password') === configs.remote))
const hasPrimarySlide = logicOr(isPlaying, isPresenter)

const currentSlideNo = computed(() => hasPrimarySlide.value ? getSlide(currentRoute.value.params.no as string)?.no ?? 1 : 1)
Expand Down Expand Up @@ -351,7 +348,6 @@ const useNavState = createSharedComposable((): SlidevContextNavState => {
isPlaying,
isPresenter,
isNotesViewer,
isPresenterAvailable,
hasPrimarySlide,
currentSlideNo,
currentSlideRoute,
Expand Down
2 changes: 0 additions & 2 deletions packages/client/env.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@ import configs from '#slidev/configs'

export { configs }

export const mode = __DEV__ ? 'dev' : 'build'

export const slideAspect = ref(configs.aspectRatio ?? (16 / 9))
export const slideWidth = ref(configs.canvasWidth ?? 980)

Expand Down
6 changes: 4 additions & 2 deletions packages/client/internals/Controls.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,22 @@ import { shallowRef } from 'vue'
import { showInfoDialog, showRecordingDialog } from '../state'
import { configs } from '../env'
import { useNav } from '../composables/useNav'
import { useFeatures } from '../composables/useFeatures'
import QuickOverview from './QuickOverview.vue'
import InfoDialog from './InfoDialog.vue'
import Goto from './Goto.vue'
import ContextMenu from './ContextMenu.vue'

const { isEmbedded } = useNav()
const drawingEnabled = __SLIDEV_FEATURE_DRAWINGS__ && !configs.drawings.presenterOnly && !isEmbedded.value
const features = useFeatures()
const drawingEnabled = features.drawings && !configs.drawings.presenterOnly && !isEmbedded.value
const DrawingControls = shallowRef<any>()
if (drawingEnabled)
import('../internals/DrawingControls.vue').then(v => DrawingControls.value = v.default)

const WebCamera = shallowRef<any>()
const RecordingDialog = shallowRef<any>()
if (__SLIDEV_FEATURE_RECORD__) {
if (features.record) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The reason we use the flag and static replacement is for tree-shaking. When the feature is disabled, the corresponding module should not be shipped to user's client bundle at all because Rollup will remove if (false) {}

Is the new approach still behaviours like that?

import('./WebCamera.vue').then(v => WebCamera.value = v.default)
import('./RecordingDialog.vue').then(v => RecordingDialog.value = v.default)
}
Expand Down
11 changes: 6 additions & 5 deletions packages/client/internals/NavControls.vue
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { activeElement, breakpoints, fullscreen, presenterLayout, showEditor, sh
import { configs } from '../env'
import { useNav } from '../composables/useNav'
import { useDrawings } from '../composables/useDrawings'
import { useFeatures } from '../composables/useFeatures'
import Settings from './Settings.vue'
import MenuButton from './MenuButton.vue'
import VerticalDivider from './VerticalDivider.vue'
Expand All @@ -25,7 +26,6 @@ const {
hasPrev,
isEmbedded,
isPresenter,
isPresenterAvailable,
next,
prev,
total,
Expand All @@ -36,6 +36,7 @@ const {
brush,
drawingEnabled,
} = useDrawings()
const features = useFeatures()

const md = breakpoints.smaller('md')
const { isFullscreen, toggle: toggleFullscreen } = fullscreen
Expand All @@ -51,7 +52,7 @@ const barStyle = computed(() => props.persist
: 'rounded-md bg-main shadow dark:border dark:border-main')

const RecordingControls = shallowRef<any>()
if (__SLIDEV_FEATURE_RECORD__)
if (features.record)
import('./RecordingControls.vue').then(v => RecordingControls.value = v.default)
</script>

Expand Down Expand Up @@ -102,7 +103,7 @@ if (__SLIDEV_FEATURE_RECORD__)
</IconButton>
</template>

<template v-if="__SLIDEV_FEATURE_DRAWINGS__ && (!configs.drawings.presenterOnly || isPresenter) && !isEmbedded">
<template v-if="features.allowToDraw">
<IconButton class="relative" :title="drawingEnabled ? 'Hide drawing toolbar' : 'Show drawing toolbar'" @click="drawingEnabled = !drawingEnabled">
<carbon:pen />
<div
Expand All @@ -118,12 +119,12 @@ if (__SLIDEV_FEATURE_RECORD__)
<IconButton v-if="isPresenter" title="Play Mode" @click="exitPresenter">
<carbon:presentation-file />
</IconButton>
<IconButton v-if="__SLIDEV_FEATURE_PRESENTER__ && isPresenterAvailable" title="Presenter Mode" @click="enterPresenter">
<IconButton v-if="features.enterPresenter" title="Presenter Mode" @click="enterPresenter">
<carbon:user-speaker />
</IconButton>

<IconButton
v-if="__DEV__ && __SLIDEV_FEATURE_EDITOR__"
v-if="features.editor"
:title="showEditor ? 'Hide editor' : 'Show editor'"
class="lt-md:hidden"
@click="showEditor = !showEditor"
Expand Down
15 changes: 5 additions & 10 deletions packages/client/internals/PrintSlideClick.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { injectionSlidevContext } from '../constants'
import { configs, slideHeight, slideWidth } from '../env'
import { getSlideClass } from '../utils'
import type { SlidevContextNav } from '../composables/useNav'
import { useFeatures } from '../composables/useFeatures'
import SlideWrapper from './SlideWrapper.vue'

import GlobalTop from '#slidev/global-components/top'
Expand All @@ -21,8 +22,10 @@ const style = computed(() => ({
width: `${slideWidth.value}px`,
}))

const features = useFeatures()

const DrawingPreview = shallowRef<any>()
if (__SLIDEV_FEATURE_DRAWINGS__ || __SLIDEV_FEATURE_DRAWINGS_PERSIST__)
if (features.drawings)
import('./DrawingPreview.vue').then(v => (DrawingPreview.value = v.default))

const id = computed(() =>
Expand All @@ -46,15 +49,7 @@ provideLocal(injectionSlidevContext, reactive({
:class="getSlideClass(route)"
:route="route"
/>
<template
v-if="
(__SLIDEV_FEATURE_DRAWINGS__
|| __SLIDEV_FEATURE_DRAWINGS_PERSIST__)
&& DrawingPreview
"
>
<DrawingPreview :page="route.no" />
</template>
<DrawingPreview v-if="DrawingPreview" :page="route.no" />

<GlobalTop />
</div>
Expand Down
4 changes: 3 additions & 1 deletion packages/client/internals/QuickOverview.vue
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,14 @@ import { currentOverviewPage, overviewRowCount } from '../logic/overview'
import { createFixedClicks } from '../composables/useClicks'
import { CLICKS_MAX } from '../constants'
import { useNav } from '../composables/useNav'
import { useFeatures } from '../composables/useFeatures'
import SlideContainer from './SlideContainer.vue'
import SlideWrapper from './SlideWrapper.vue'
import DrawingPreview from './DrawingPreview.vue'
import IconButton from './IconButton.vue'

const { currentSlideNo, go: goSlide, slides } = useNav()
const features = useFeatures()

function close() {
showOverview.value = false
Expand Down Expand Up @@ -165,7 +167,7 @@ setTimeout(() => {
<carbon:close />
</IconButton>
<IconButton
v-if="__SLIDEV_FEATURE_PRESENTER__"
v-if="features.presenter"
as="a"
title="Slides Overview"
target="_blank"
Expand Down
9 changes: 5 additions & 4 deletions packages/client/internals/SlidesShow.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { skipTransition } from '../logic/hmr'
import { createFixedClicks } from '../composables/useClicks'
import { activeDragElement } from '../state'
import { CLICKS_MAX } from '../constants'
import { useFeatures } from '../composables/useFeatures'
import SlideWrapper from './SlideWrapper.vue'
import DragControl from './DragControl.vue'

Expand Down Expand Up @@ -38,8 +39,10 @@ watch(currentSlideRoute, () => {

const hasViewTransition = useViewTransition()

const features = useFeatures()

const DrawingLayer = shallowRef<any>()
if (__SLIDEV_FEATURE_DRAWINGS__ || __SLIDEV_FEATURE_DRAWINGS_PERSIST__)
if (features.drawings)
import('./DrawingLayer.vue').then(v => DrawingLayer.value = v.default)

const loadedRoutes = computed(() => slides.value.filter(r => r.meta?.__preloaded || r === currentSlideRoute.value))
Expand Down Expand Up @@ -86,9 +89,7 @@ function onAfterLeave() {
<!-- Global Top -->
<GlobalTop />

<template v-if="(__SLIDEV_FEATURE_DRAWINGS__ || __SLIDEV_FEATURE_DRAWINGS_PERSIST__) && DrawingLayer">
<DrawingLayer />
</template>
<DrawingLayer v-if="DrawingLayer" />
</template>

<style scoped>
Expand Down
8 changes: 5 additions & 3 deletions packages/client/logic/contextMenu.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ import type { ContextMenuItem } from '@slidev/types'
import type { ComputedRef } from 'vue'
import { shallowRef } from 'vue'
import setupContextMenu from '../setup/context-menu'
import { configs, mode } from '../env'
import { useNav } from '../composables/useNav'
import { useFeatures } from '../composables/useFeatures'

export const currentContextMenu = shallowRef<null | {
x: number
Expand All @@ -24,11 +24,13 @@ export function closeContextMenu() {
}

export function onContextMenu(ev: MouseEvent) {
if (configs.contextMenu !== true && configs.contextMenu !== undefined && configs.contextMenu !== mode)
return
if (ev.shiftKey || ev.defaultPrevented)
return

const features = useFeatures()
if (!features.contextMenu)
return

const { isEmbedded } = useNav()
if (isEmbedded.value)
return
Expand Down
4 changes: 3 additions & 1 deletion packages/client/pages/play.vue
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,12 @@ import PrintStyle from '../internals/PrintStyle.vue'
import { onContextMenu } from '../logic/contextMenu'
import { useNav } from '../composables/useNav'
import { useDrawings } from '../composables/useDrawings'
import { useFeatures } from '../composables/useFeatures'
import PresenterMouse from '../internals/PresenterMouse.vue'

const { next, prev, isPrintMode } = useNav()
const { isDrawing } = useDrawings()
const features = useFeatures()

const root = ref<HTMLDivElement>()
function onClick(e: MouseEvent) {
Expand All @@ -36,7 +38,7 @@ registerShortcuts()
const persistNav = computed(() => isScreenVertical.value || showEditor.value)

const SideEditor = shallowRef<any>()
if (__DEV__ && __SLIDEV_FEATURE_EDITOR__)
if (features.editor)
import('../internals/SideEditor.vue').then(v => SideEditor.value = v.default)
</script>

Expand Down
11 changes: 8 additions & 3 deletions packages/client/pages/presenter.vue
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,12 @@ import NoteEditable from '../internals/NoteEditable.vue'
import NoteStatic from '../internals/NoteStatic.vue'
import Goto from '../internals/Goto.vue'
import SlidesShow from '../internals/SlidesShow.vue'
import DrawingControls from '../internals/DrawingControls.vue'
import IconButton from '../internals/IconButton.vue'
import ClicksSlider from '../internals/ClicksSlider.vue'
import ContextMenu from '../internals/ContextMenu.vue'
import { useNav } from '../composables/useNav'
import { useDrawings } from '../composables/useDrawings'
import { useFeatures } from '../composables/useFeatures'

const main = ref<HTMLDivElement>()

Expand All @@ -42,6 +42,7 @@ const {
total,
} = useNav()
const { isDrawing } = useDrawings()
const features = useFeatures()

useHead({ title: `Presenter - ${slidesTitle}` })

Expand Down Expand Up @@ -73,9 +74,13 @@ watch(
)

const SideEditor = shallowRef<any>()
if (__DEV__ && __SLIDEV_FEATURE_EDITOR__)
if (features.editor)
import('../internals/SideEditor.vue').then(v => SideEditor.value = v.default)

const DrawingControls = shallowRef<any>()
if (features.allowToDraw)
import('../internals/DrawingControls.vue').then(v => DrawingControls.value = v.default)

// sync presenter cursor
onMounted(() => {
const slidesContainer = main.value!.querySelector('#slide-content')!
Expand Down Expand Up @@ -189,7 +194,7 @@ onMounted(() => {
{{ timer }}
</div>
</div>
<DrawingControls v-if="__SLIDEV_FEATURE_DRAWINGS__" />
<DrawingControls v-if="DrawingControls" />
</div>
<div class="progress-bar">
<div
Expand Down
Loading
Loading