Добавить управление таймером организатору

This commit is contained in:
2026-09-21 18:24:38 +07:00
parent 70fa1b2f38
commit af6eb62a8e
+70
View File
@@ -97,11 +97,31 @@ const mapItems = ref<MapItem[]>([])
const mapSaving = ref(false)
const screenVolume = ref(100)
const screenPosition = ref(0)
const timerDurationMinutes = ref<number | null>(10)
const timerLabel = ref('Перерыв')
const timerFormInitialized = ref(false)
const currentScreenMode = computed<ScreenMode | undefined>(() => {
const modes = screens.value.map((screen) => screen.mode).filter(Boolean)
if (!modes.length || modes.some((mode) => mode !== modes[0])) return undefined
return modes[0] as ScreenMode
})
const timerScreen = computed(() => screens.value[0])
const timerStateLabel = computed(() => {
switch (timerScreen.value?.timerState) {
case 'SCREEN_TIMER_STATE_RUNNING':
return 'Идёт'
case 'SCREEN_TIMER_STATE_PAUSED':
return 'Пауза'
case 'SCREEN_TIMER_STATE_FINISHED':
return 'Завершён'
default:
return 'Остановлен'
}
})
const timerRemainingLabel = computed(() => {
const seconds = Math.max(0, timerScreen.value?.timerRemainingSeconds || 0)
return `${String(Math.floor(seconds / 60)).padStart(2, '0')}:${String(seconds % 60).padStart(2, '0')}`
})
const mapScale = ref(1)
const mapOffset = ref({ x: 0, y: 0 })
let dragState:
@@ -150,6 +170,11 @@ async function getGameScreens() {
return
}
screens.value = res.screens || []
if (!timerFormInitialized.value && screens.value[0]) {
timerDurationMinutes.value = Math.max(1, (screens.value[0].timerDurationSeconds || 600) / 60)
timerLabel.value = screens.value[0].timerLabel || 'Перерыв'
timerFormInitialized.value = true
}
}
getGameScreens()
@@ -276,6 +301,25 @@ async function setScreenMode(mode: ScreenMode) {
if (res.error != '') message.error(res.error || 'Не удалось изменить режим экранов')
}
async function configureScreenTimer() {
const durationMinutes = timerDurationMinutes.value
const label = timerLabel.value.trim()
if (!durationMinutes || durationMinutes <= 0 || !label) {
message.error('Укажите длительность и надпись таймера')
return
}
const res = await client.SetScreenTimer({
gameId: Number(gameId),
durationSeconds: Math.round(durationMinutes * 60),
label,
})
if (res.error != '') {
message.error(res.error || 'Не удалось настроить таймер')
return
}
await getGameScreens()
}
async function sendScreenCommand(command: ScreenCommand) {
if (command === 'SCREEN_COMMAND_PLAY' || command === 'SCREEN_COMMAND_REPLAY') {
if (!window.confirm('Запустить медиа на всех экранах?')) return
@@ -815,6 +859,32 @@ useSimplePolling(() => {
@click="setScreenMode('SCREEN_MODE_RESULTS')"
>Результаты</n-button
>
<n-button
:type="currentScreenMode === 'SCREEN_MODE_TIMER' ? 'primary' : 'default'"
@click="setScreenMode('SCREEN_MODE_TIMER')"
>Таймер</n-button
>
</n-space>
<n-space class="screen-mode-controls" align="center">
<n-input-number
v-model:value="timerDurationMinutes"
:min="1"
:max="1440"
:step="1"
size="small"
placeholder="Минуты"
/>
<n-input v-model:value="timerLabel" size="small" placeholder="Надпись таймера" />
<n-button size="small" @click="configureScreenTimer">Настроить таймер</n-button>
<n-tag type="info">{{ timerStateLabel }} · {{ timerRemainingLabel }}</n-tag>
</n-space>
<n-space class="screen-mode-controls">
<n-button size="small" @click="sendScreenCommand('SCREEN_COMMAND_TIMER_START')">Старт таймера</n-button>
<n-button size="small" @click="sendScreenCommand('SCREEN_COMMAND_TIMER_PAUSE')">Пауза таймера</n-button>
<n-button size="small" @click="sendScreenCommand('SCREEN_COMMAND_TIMER_RESUME')"
>Продолжить таймер</n-button
>
<n-button size="small" @click="sendScreenCommand('SCREEN_COMMAND_TIMER_RESET')">Сбросить таймер</n-button>
</n-space>
<n-space class="screen-mode-controls">
<n-button size="small" @click="sendScreenCommand('SCREEN_COMMAND_PLAY')">Запуск</n-button>