generated from VLADIMIR/template_frontend
up
This commit is contained in:
+203
-159
@@ -15,6 +15,7 @@ import type {
|
||||
TeamResult,
|
||||
} from '@/api/generated/crabs/evening_detective_server'
|
||||
import ScreenPreview from '@/components/ScreenPreview.vue'
|
||||
import UiBlock from '@/components/UiBlock.vue'
|
||||
|
||||
const props = defineProps<{
|
||||
mapItems: MapItem[]
|
||||
@@ -154,8 +155,8 @@ onBeforeUnmount(() => {
|
||||
|
||||
<template>
|
||||
<div class="map-preview-layout">
|
||||
<div class="map-block">
|
||||
<n-flex align="center" justify="space-between">
|
||||
<UiBlock>
|
||||
<n-flex align="center" justify="space-between" class="screen-header">
|
||||
<p class="screens-title">Карта помещения</p>
|
||||
<n-space>
|
||||
<n-button size="small" @click="changeMapScale(-0.1)">−</n-button>
|
||||
@@ -234,8 +235,8 @@ onBeforeUnmount(() => {
|
||||
Добавить {{ item.label }}
|
||||
</n-button>
|
||||
</n-space>
|
||||
</div>
|
||||
<aside class="screen-preview-panel">
|
||||
</UiBlock>
|
||||
<UiBlock tag="aside" class="screen-preview-panel">
|
||||
<p class="screens-title">Превью экрана</p>
|
||||
<ScreenPreview
|
||||
v-if="previewScreen?.status === 'connected'"
|
||||
@@ -245,7 +246,7 @@ onBeforeUnmount(() => {
|
||||
/>
|
||||
<div v-else class="screen-preview-placeholder">Экран не подключён</div>
|
||||
<div class="screen-plan">
|
||||
<n-flex align="center" justify="space-between">
|
||||
<n-flex align="center" justify="space-between" class="screen-header">
|
||||
<p class="screens-title">План экранов</p>
|
||||
<n-space>
|
||||
<n-button
|
||||
@@ -282,66 +283,77 @@ onBeforeUnmount(() => {
|
||||
План экранов ещё не создан.
|
||||
</p>
|
||||
<template v-else-if="screenPlanMode === 'edit'">
|
||||
<n-space v-for="(step, index) in screenPlanDraft" :key="index" align="center" wrap>
|
||||
<n-text>{{ index + 1 }}</n-text>
|
||||
<n-select
|
||||
v-model:value="step.mode"
|
||||
:options="screenPlanModeOptions"
|
||||
:disabled="screenPlanSaving"
|
||||
size="small"
|
||||
style="width: 180px"
|
||||
@update:value="emit('dirty')"
|
||||
/>
|
||||
<n-input
|
||||
v-if="step.mode === 'SCREEN_MODE_TEXT'"
|
||||
v-model:value="step.text"
|
||||
:disabled="screenPlanSaving"
|
||||
size="small"
|
||||
placeholder="Текст экрана"
|
||||
style="min-width: 240px"
|
||||
@update:value="emit('dirty')"
|
||||
/>
|
||||
<template v-if="step.mode === 'SCREEN_MODE_TIMER'">
|
||||
<n-space
|
||||
v-for="(step, index) in screenPlanDraft"
|
||||
:key="index"
|
||||
class="screen-plan-step"
|
||||
align="center"
|
||||
justify="space-between"
|
||||
wrap
|
||||
>
|
||||
<n-space align="center" wrap>
|
||||
<n-text>{{ index + 1 }}</n-text>
|
||||
<n-select
|
||||
v-model:value="step.mode"
|
||||
:options="screenPlanModeOptions"
|
||||
:disabled="screenPlanSaving"
|
||||
size="small"
|
||||
style="width: 180px"
|
||||
@update:value="emit('dirty')"
|
||||
/>
|
||||
<n-input
|
||||
v-model:value="step.timerLabel"
|
||||
v-if="step.mode === 'SCREEN_MODE_TEXT'"
|
||||
v-model:value="step.text"
|
||||
:disabled="screenPlanSaving"
|
||||
size="small"
|
||||
placeholder="Надпись таймера"
|
||||
placeholder="Текст экрана"
|
||||
style="min-width: 240px"
|
||||
@update:value="emit('dirty')"
|
||||
/>
|
||||
<n-input-number
|
||||
v-model:value="step.timerDurationSeconds"
|
||||
:min="1"
|
||||
:max="86400"
|
||||
:disabled="screenPlanSaving"
|
||||
<template v-if="step.mode === 'SCREEN_MODE_TIMER'">
|
||||
<n-input
|
||||
v-model:value="step.timerLabel"
|
||||
:disabled="screenPlanSaving"
|
||||
size="small"
|
||||
placeholder="Надпись таймера"
|
||||
@update:value="emit('dirty')"
|
||||
/>
|
||||
<n-input-number
|
||||
v-model:value="step.timerDurationSeconds"
|
||||
:min="1"
|
||||
:max="86400"
|
||||
:disabled="screenPlanSaving"
|
||||
size="small"
|
||||
placeholder="Секунды"
|
||||
@update:value="emit('dirty')"
|
||||
/>
|
||||
</template>
|
||||
</n-space>
|
||||
<n-space class="screen-plan-actions">
|
||||
<n-button
|
||||
size="small"
|
||||
placeholder="Секунды"
|
||||
@update:value="emit('dirty')"
|
||||
/>
|
||||
</template>
|
||||
<n-button
|
||||
size="small"
|
||||
:disabled="screenPlanSaving || index === 0"
|
||||
@click="emit('moveStep', index, -1)"
|
||||
>
|
||||
↑
|
||||
</n-button>
|
||||
<n-button
|
||||
size="small"
|
||||
:disabled="screenPlanSaving || index === screenPlanDraft.length - 1"
|
||||
@click="emit('moveStep', index, 1)"
|
||||
>
|
||||
↓
|
||||
</n-button>
|
||||
<n-button
|
||||
size="small"
|
||||
type="error"
|
||||
ghost
|
||||
:disabled="screenPlanSaving"
|
||||
@click="emit('removeStep', index)"
|
||||
>
|
||||
Удалить
|
||||
</n-button>
|
||||
:disabled="screenPlanSaving || index === 0"
|
||||
@click="emit('moveStep', index, -1)"
|
||||
>
|
||||
↑
|
||||
</n-button>
|
||||
<n-button
|
||||
size="small"
|
||||
:disabled="screenPlanSaving || index === screenPlanDraft.length - 1"
|
||||
@click="emit('moveStep', index, 1)"
|
||||
>
|
||||
↓
|
||||
</n-button>
|
||||
<n-button
|
||||
size="small"
|
||||
type="error"
|
||||
ghost
|
||||
:disabled="screenPlanSaving"
|
||||
@click="emit('removeStep', index)"
|
||||
>
|
||||
Удалить
|
||||
</n-button>
|
||||
</n-space>
|
||||
</n-space>
|
||||
<n-space>
|
||||
<n-button size="small" :disabled="screenPlanSaving" @click="emit('addStep')">
|
||||
@@ -358,119 +370,138 @@ onBeforeUnmount(() => {
|
||||
</n-space>
|
||||
</template>
|
||||
<template v-else-if="screenPlan">
|
||||
<n-space v-for="(step, index) in screenPlan.steps || []" :key="index" align="center" wrap>
|
||||
<n-text>{{ index + 1 }}</n-text>
|
||||
<n-text>
|
||||
{{ screenPlanModeOptions.find((option) => option.value === step.mode)?.label }}
|
||||
<template v-if="step.mode === 'SCREEN_MODE_TEXT'">: {{ step.text }}</template>
|
||||
<template v-else-if="step.mode === 'SCREEN_MODE_TIMER'">
|
||||
: {{ step.timerLabel }} ({{ step.timerDurationSeconds }} с)
|
||||
</template>
|
||||
</n-text>
|
||||
<n-button
|
||||
size="small"
|
||||
:type="screenPlan.currentStep === index ? 'primary' : 'default'"
|
||||
:disabled="screenPlan.currentStep === index"
|
||||
@click="emit('setStep', index)"
|
||||
>
|
||||
Показать
|
||||
</n-button>
|
||||
<template v-if="screenPlan.currentStep === index">
|
||||
<template v-if="step.mode === 'SCREEN_MODE_TIMER'">
|
||||
<n-button
|
||||
size="small"
|
||||
@click="emit('command', step.mode, 'SCREEN_COMMAND_TIMER_START')"
|
||||
>
|
||||
Старт
|
||||
</n-button>
|
||||
<n-button
|
||||
size="small"
|
||||
@click="emit('command', step.mode, 'SCREEN_COMMAND_TIMER_PAUSE')"
|
||||
>
|
||||
Пауза
|
||||
</n-button>
|
||||
<n-button
|
||||
size="small"
|
||||
@click="emit('command', step.mode, 'SCREEN_COMMAND_TIMER_RESUME')"
|
||||
>
|
||||
Продолжить
|
||||
</n-button>
|
||||
<n-button
|
||||
size="small"
|
||||
@click="emit('command', step.mode, 'SCREEN_COMMAND_TIMER_RESET')"
|
||||
>
|
||||
Сбросить
|
||||
</n-button>
|
||||
</template>
|
||||
<template
|
||||
v-else-if="
|
||||
step.mode === 'SCREEN_MODE_INTRO' || step.mode === 'SCREEN_MODE_CONCLUSION'
|
||||
"
|
||||
<n-space
|
||||
v-for="(step, index) in screenPlan.steps || []"
|
||||
:key="index"
|
||||
class="screen-plan-step"
|
||||
align="center"
|
||||
justify="space-between"
|
||||
wrap
|
||||
>
|
||||
<n-space align="center">
|
||||
<n-text>{{ index + 1 }}</n-text>
|
||||
<n-text>
|
||||
{{ screenPlanModeOptions.find((option) => option.value === step.mode)?.label }}
|
||||
<template v-if="step.mode === 'SCREEN_MODE_TEXT'">: {{ step.text }}</template>
|
||||
<template v-else-if="step.mode === 'SCREEN_MODE_TIMER'">
|
||||
: {{ step.timerLabel }} ({{ step.timerDurationSeconds }} с)
|
||||
</template>
|
||||
</n-text>
|
||||
</n-space>
|
||||
<n-space class="screen-plan-actions">
|
||||
<n-button
|
||||
size="small"
|
||||
:type="screenPlan.currentStep === index ? 'primary' : 'default'"
|
||||
:disabled="screenPlan.currentStep === index"
|
||||
@click="emit('setStep', index)"
|
||||
>
|
||||
<n-button size="small" @click="emit('command', step.mode, 'SCREEN_COMMAND_PLAY')">
|
||||
Запуск
|
||||
</n-button>
|
||||
<n-button size="small" @click="emit('command', step.mode, 'SCREEN_COMMAND_PAUSE')">
|
||||
Пауза
|
||||
</n-button>
|
||||
<n-button size="small" @click="emit('command', step.mode, 'SCREEN_COMMAND_RESUME')">
|
||||
Продолжить
|
||||
</n-button>
|
||||
<n-button size="small" @click="emit('command', step.mode, 'SCREEN_COMMAND_STOP')">
|
||||
Стоп
|
||||
</n-button>
|
||||
<n-button size="small" @click="emit('command', step.mode, 'SCREEN_COMMAND_REPLAY')">
|
||||
Повтор
|
||||
</n-button>
|
||||
<n-input-number
|
||||
:value="screenVolume"
|
||||
:min="0"
|
||||
:max="100"
|
||||
:step="5"
|
||||
size="small"
|
||||
@update:value="emit('update:screenVolume', $event)"
|
||||
/>
|
||||
<n-button size="small" @click="emit('command', step.mode, 'SCREEN_COMMAND_VOLUME')">
|
||||
Громкость
|
||||
</n-button>
|
||||
<n-input-number
|
||||
:value="screenPosition"
|
||||
:min="0"
|
||||
:step="5"
|
||||
size="small"
|
||||
@update:value="emit('update:screenPosition', $event)"
|
||||
/>
|
||||
<n-button size="small" @click="emit('command', step.mode, 'SCREEN_COMMAND_SEEK')">
|
||||
Перемотать
|
||||
</n-button>
|
||||
Показать
|
||||
</n-button>
|
||||
<template v-if="screenPlan.currentStep === index">
|
||||
<template v-if="step.mode === 'SCREEN_MODE_TIMER'">
|
||||
<n-button
|
||||
size="small"
|
||||
@click="emit('command', step.mode, 'SCREEN_COMMAND_TIMER_START')"
|
||||
>
|
||||
Старт
|
||||
</n-button>
|
||||
<n-button
|
||||
size="small"
|
||||
@click="emit('command', step.mode, 'SCREEN_COMMAND_TIMER_PAUSE')"
|
||||
>
|
||||
Пауза
|
||||
</n-button>
|
||||
<n-button
|
||||
size="small"
|
||||
@click="emit('command', step.mode, 'SCREEN_COMMAND_TIMER_RESUME')"
|
||||
>
|
||||
Продолжить
|
||||
</n-button>
|
||||
<n-button
|
||||
size="small"
|
||||
@click="emit('command', step.mode, 'SCREEN_COMMAND_TIMER_RESET')"
|
||||
>
|
||||
Сбросить
|
||||
</n-button>
|
||||
</template>
|
||||
<template
|
||||
v-else-if="
|
||||
step.mode === 'SCREEN_MODE_INTRO' || step.mode === 'SCREEN_MODE_CONCLUSION'
|
||||
"
|
||||
>
|
||||
<n-button size="small" @click="emit('command', step.mode, 'SCREEN_COMMAND_PLAY')">
|
||||
Запуск
|
||||
</n-button>
|
||||
<n-button
|
||||
size="small"
|
||||
@click="emit('command', step.mode, 'SCREEN_COMMAND_PAUSE')"
|
||||
>
|
||||
Пауза
|
||||
</n-button>
|
||||
<n-button
|
||||
size="small"
|
||||
@click="emit('command', step.mode, 'SCREEN_COMMAND_RESUME')"
|
||||
>
|
||||
Продолжить
|
||||
</n-button>
|
||||
<n-button size="small" @click="emit('command', step.mode, 'SCREEN_COMMAND_STOP')">
|
||||
Стоп
|
||||
</n-button>
|
||||
<n-button
|
||||
size="small"
|
||||
@click="emit('command', step.mode, 'SCREEN_COMMAND_REPLAY')"
|
||||
>
|
||||
Повтор
|
||||
</n-button>
|
||||
<n-input-number
|
||||
:value="screenVolume"
|
||||
:min="0"
|
||||
:max="100"
|
||||
:step="5"
|
||||
size="small"
|
||||
@update:value="emit('update:screenVolume', $event)"
|
||||
/>
|
||||
<n-button
|
||||
size="small"
|
||||
@click="emit('command', step.mode, 'SCREEN_COMMAND_VOLUME')"
|
||||
>
|
||||
Громкость
|
||||
</n-button>
|
||||
<n-input-number
|
||||
:value="screenPosition"
|
||||
:min="0"
|
||||
:step="5"
|
||||
size="small"
|
||||
@update:value="emit('update:screenPosition', $event)"
|
||||
/>
|
||||
<n-button size="small" @click="emit('command', step.mode, 'SCREEN_COMMAND_SEEK')">
|
||||
Перемотать
|
||||
</n-button>
|
||||
</template>
|
||||
</template>
|
||||
</template>
|
||||
</n-space>
|
||||
</n-space>
|
||||
</template>
|
||||
</div>
|
||||
</aside>
|
||||
</UiBlock>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.map-preview-layout {
|
||||
display: grid;
|
||||
gap: 12px;
|
||||
gap: 8px;
|
||||
grid-template-columns: minmax(0, 1fr) minmax(280px, 420px);
|
||||
}
|
||||
|
||||
.map-block,
|
||||
.screen-preview-panel {
|
||||
background-color: #222;
|
||||
border-radius: 10px;
|
||||
margin: 12px 0;
|
||||
padding: 16px;
|
||||
}
|
||||
|
||||
.screens-title {
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
margin-bottom: 12px;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.screen-header {
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.screen-preview-placeholder {
|
||||
@@ -483,6 +514,19 @@ onBeforeUnmount(() => {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.screen-preview-panel > .screens-title {
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.screen-plan {
|
||||
margin-top: 16px;
|
||||
}
|
||||
|
||||
.screen-plan-step {
|
||||
border-top: 1px solid rgb(255 255 255 / 10%);
|
||||
padding: 8px 0;
|
||||
}
|
||||
|
||||
.map-field {
|
||||
aspect-ratio: 1;
|
||||
background-color: #151515;
|
||||
@@ -515,7 +559,7 @@ onBeforeUnmount(() => {
|
||||
border-radius: 6px;
|
||||
cursor: grab;
|
||||
min-width: 90px;
|
||||
padding: 8px 24px 8px 10px;
|
||||
padding: 8px 24px 8px 8px;
|
||||
position: absolute;
|
||||
user-select: none;
|
||||
}
|
||||
@@ -545,8 +589,8 @@ onBeforeUnmount(() => {
|
||||
background-color: #48633a;
|
||||
border-radius: 6px 6px 0 0;
|
||||
cursor: grab;
|
||||
margin: -8px -24px 8px -10px;
|
||||
padding: 8px 24px 8px 10px;
|
||||
margin: -8px -24px 8px -8px;
|
||||
padding: 8px 24px 8px 8px;
|
||||
}
|
||||
|
||||
.map-team-handle:active {
|
||||
@@ -584,7 +628,7 @@ onBeforeUnmount(() => {
|
||||
}
|
||||
|
||||
.map-hidden-items {
|
||||
margin-top: 10px;
|
||||
margin-top: 16px;
|
||||
}
|
||||
|
||||
@media (width < 1024px) {
|
||||
|
||||
Reference in New Issue
Block a user