返回 slidev
SyncControls.vue
根目录 / packages / client / internals / SyncControls.vue
1 <script setup lang="ts">
2 import { computed } from 'vue'
3 import { useNav } from '../composables/useNav'
4 import { syncDirections } from '../state'
5 import IconButton from './IconButton.vue'
6 import MenuButton from './MenuButton.vue'
7 import SelectList from './SelectList.vue'
8
9 const { isPresenter } = useNav()
10
11 const shouldReceive = computed({
12 get: () => isPresenter.value
13 ? syncDirections.value.presenterReceive
14 : syncDirections.value.viewerReceive,
15 set(v) {
16 if (isPresenter.value) {
17 syncDirections.value.presenterReceive = v
18 }
19 else {
20 syncDirections.value.viewerReceive = v
21 }
22 },
23 })
24
25 const shouldSend = computed({
26 get: () => isPresenter.value
27 ? syncDirections.value.presenterSend
28 : syncDirections.value.viewerSend,
29 set(v) {
30 if (isPresenter.value) {
31 syncDirections.value.presenterSend = v
32 }
33 else {
34 syncDirections.value.viewerSend = v
35 }
36 },
37 })
38
39 const state = computed({
40 get: () => {
41 if (shouldReceive.value && shouldSend.value) {
42 return 'bidirectional'
43 }
44 if (shouldReceive.value && !shouldSend.value) {
45 return 'receive-only'
46 }
47 if (!shouldReceive.value && shouldSend.value) {
48 return 'send-only'
49 }
50 return 'off'
51 },
52 set(v) {
53 switch (v) {
54 case 'bidirectional':
55 shouldReceive.value = true
56 shouldSend.value = true
57 break
58 case 'receive-only':
59 shouldReceive.value = true
60 shouldSend.value = false
61 break
62 case 'send-only':
63 shouldReceive.value = false
64 shouldSend.value = true
65 break
66 case 'off':
67 shouldReceive.value = false
68 shouldSend.value = false
69 break
70 }
71 },
72 })
73 </script>
74
75 <template>
76 <MenuButton>
77 <template #button>
78 <IconButton title="Change sync settings">
79 <div class="i-ph:arrow-up-bold mx--1.2 scale-x-80" :class="shouldSend ? 'text-green6 dark:text-green' : 'op30'" />
80 <div class="i-ph:arrow-down-bold mx--1.2 scale-x-80" :class="shouldReceive ? 'text-green6 dark:text-green' : 'op30'" />
81 </IconButton>
82 </template>
83 <template #menu>
84 <div text-sm flex="~ col gap-2">
85 <div px3 ws-nowrap>
86 <span op75>Slides navigation syncing for </span>
87 <span font-bold text-primary>{{ isPresenter ? 'presenter' : 'viewer' }}</span>
88 </div>
89 <div class="h-1px opacity-10 bg-current w-full" />
90 <SelectList
91 v-model="state"
92 title="Sync Mode"
93 :items="[
94 { value: 'bidirectional', display: 'Bidirectional Sync' },
95 { value: 'receive-only', display: 'Receive Only' },
96 { value: 'send-only', display: 'Send Only' },
97 { value: 'off', display: 'Disable' },
98 ]"
99 />
100 </div>
101 </template>
102 </MenuButton>
103 </template>
104
104 lines Plain Text