Files
prod/frontend/dist/assets/ScreenView-D2knQLxw.js
T
2026-10-11 02:25:16 +07:00

1 line
11 KiB
JavaScript

import{Ct as e,Dt as t,In as n,Jt as r,Kt as i,Ln as a,Ot as o,Rt as s,St as c,Ut as l,Wt as ee,an as u,bt as d,hn as f,ht as p,in as m,kt as h,l as te,nn as g,t as ne,wt as _,xt as v,yn as y}from"./client-Cr-cm5gA.js";import{t as b}from"./Card-BXfpL_-k.js";import{n as re}from"./es-BgZM4SOf.js";import{t as x}from"./Button-htLGEUWP.js";import{t as ie}from"./Select-CSZYOCW8.js";import{t as S}from"./_plugin-vue_export-helper-D-vCjaLb.js";import{t as ae}from"./QrCode-DCMU89nB.js";import{at as C,n as oe}from"./index-BDx9g-XU.js";import{t as se}from"./HeaderMenu-B9QH_cmH.js";import{r as w}from"./application-BJsoYEct.js";import{t as ce}from"./datetime-BJNH0M1T.js";import{t as le}from"./useSimplePolling-BMeRWyaB.js";var ue={key:0,class:`screen-center`},de={key:1,class:`screen-page`},fe={key:0,class:`screen-center`},pe={key:0,class:`screen-center`},me={key:0,class:`screen-qr`},he={key:0,class:`media-error`},ge={key:1,class:`screen-media`},_e=[`src`,`muted`],ve=[`src`,`muted`],ye={key:3,class:`conclusion-screen`},be=[`src`,`muted`],xe={key:4,class:`screen-message`},Se={key:5,class:`screen-message`},Ce={key:6,class:`screen-message`},we={key:7,class:`screen-message`},Te={key:8,class:`timer-screen`},Ee={class:`timer-label`},De={class:`timer-value`},Oe={key:10,class:`screen-cover`},ke=[`src`],Ae={key:1,class:`cover-controls`},T=`evening-detective-screen-session`,E=S(h({__name:`ScreenPage`,setup(h){let S=ne(),E=oe(),D=re(),O=te(),k=f(``),A=f(``),j=f(),M=f([]),N=f([]),P=f(),F,I=!1,L=f([]),R=f(null),z=f(!1),B=f(``),V=f(!0),H=f(!1),U=f(!1),W=f(Date.now()),G=f(0),K=f(Date.now()),je=f(),Me=f(!1),q=f(),J=f(),Y=f(),Ne=0,X=null,Z=d(()=>!!(O.query.screenID&&O.query.accessToken)),Pe=d(()=>{if(!k.value||!A.value)return``;let e=new URL(`/screen`,window.location.origin);return e.searchParams.set(`screenId`,k.value),e.searchParams.set(`accessToken`,A.value),e.toString()}),Fe=d(()=>L.value.map(e=>({label:`${ce(e.startAt).split(`,`)[0]||`дата не указана`} — ${e.name||`Игра ${e.ID}`}`,value:e.ID}))),Q=d(()=>j.value?.mode||`SCREEN_MODE_COVER`),Ie=d(()=>j.value?.timerState===`SCREEN_TIMER_STATE_RUNNING`?Math.max(0,G.value-(W.value-K.value)/1e3):G.value),Le=d(()=>{let e=Math.floor(Ie.value/60),t=Math.floor(Ie.value%60);return`${String(e).padStart(2,`0`)}:${String(t).padStart(2,`0`)}`}),Re=d(()=>w(j.value?.introAudio)),ze=d(()=>w(j.value?.conclusionVideo)),Be=d(()=>w((j.value?.music?.playlist?.tracks||[])[j.value?.music?.trackIndex||0]?.filename)),Ve=d(()=>[j.value?.music?.playlist?.ID,j.value?.music?.trackIndex,j.value?.music?.playback]),He=d(()=>{let e=j.value?.backgroundImage||j.value?.coverImage;return e?{backgroundImage:`linear-gradient(rgb(0 0 0 / 55%), rgb(0 0 0 / 55%)), url("${e}")`}:{}});function Ue(){sessionStorage.setItem(T,JSON.stringify({screenID:k.value,accessToken:A.value}))}function We(e){let t=Math.max(0,Number(e?.timerRemainingSeconds||0));if(e?.timerState===`SCREEN_TIMER_STATE_RUNNING`&&je.value===e.timerState){let e=Math.max(0,G.value-(Date.now()-K.value)/1e3);if(Math.abs(t-e)<=.5)return}G.value=t,K.value=Date.now(),je.value=e?.timerState}function Ge(){try{let e=JSON.parse(sessionStorage.getItem(T)||`{}`);k.value=e.screenId||``,A.value=e.accessToken||``}catch{sessionStorage.removeItem(T)}}async function Ke(){let e=await S.CreateScreenSession({});if(!e.screenID||!e.accessToken)throw Error(`Не удалось создать сессию экрана`);k.value=e.screenID,A.value=e.accessToken,Ue()}async function $(e=!0){if(!(!k.value||!A.value))try{let e=await S.GetScreenState({screenID:k.value,accessToken:A.value});j.value=e.state,We(j.value),j.value?.gameID&&j.value.mode===`SCREEN_MODE_RESULTS`&&await qe()}catch(t){if(e&&t instanceof Error&&t.message===`unauthorized`){sessionStorage.removeItem(T),k.value=``,A.value=``,await Ke(),await $(!1);return}D.error(t instanceof Error?t.message:`Не удалось получить состояние экрана`)}}async function qe(){if(!k.value||!A.value)return;let e=await S.GetScreenResults({screenID:k.value,accessToken:A.value});if(N.value=e.questions||[],M.value=e.teams||[],!I){I=!0,await s();let e=P.value;e&&(e.scrollTop=e.scrollHeight,F=window.setInterval(()=>{e.scrollTop=Math.max(0,e.scrollTop-32),e.scrollTop===0&&F!=null&&(window.clearInterval(F),F=void 0)},1e3))}}async function Je(){try{let e=await E.GetGames({});L.value=e.games||[]}catch(e){D.error(e instanceof Error?e.message:`Не удалось загрузить игры`)}}le(()=>{Me.value&&$()},1e3),g(j,async e=>{if(!e||!e.command||e.stateVersion===Ne)return;Ne=e.stateVersion||0,await s();let t=Q.value===`SCREEN_MODE_CONCLUSION`?Y.value:q.value;t&&(t.currentTime=(e.positionMs||0)/1e3,t.volume=Math.max(0,Math.min(1,(e.volume??100)/100)),e.command!==`SCREEN_COMMAND_SEEK`&&e.command!==`SCREEN_COMMAND_VOLUME`&&(e.command===`SCREEN_COMMAND_PLAY`||e.command===`SCREEN_COMMAND_RESUME`||e.command===`SCREEN_COMMAND_REPLAY`?(e.command===`SCREEN_COMMAND_REPLAY`&&(t.currentTime=0),t.play().catch(()=>{B.value=`Браузер заблокировал воспроизведение. Нажмите «Подготовить экран» на этом устройстве.`})):(e.command===`SCREEN_COMMAND_PAUSE`||e.command===`SCREEN_COMMAND_STOP`)&&t.pause()))});function Ye(e){return e.readyState>=HTMLMediaElement.HAVE_METADATA?Promise.resolve():new Promise(t=>{let n=()=>{e.removeEventListener(`loadedmetadata`,n),e.removeEventListener(`error`,n),t()};e.addEventListener(`loadedmetadata`,n,{once:!0}),e.addEventListener(`error`,n,{once:!0})})}g(Ve,async(e,t)=>{let n=j.value?.music;if(!n||!n.playlist?.tracks?.length)return;await s();let r=J.value;if(!r)return;let i=!t||e[0]!==t[0]||e[1]!==t[1],a=!t||e[2]!==t[2];!i&&!a||(await Ye(r),r.currentTime=i?0:(n.positionMs||0)/1e3,n.playback===`MUSIC_PLAYBACK_PLAYING`?r.play().catch(()=>{B.value=`Браузер заблокировал воспроизведение музыки. Нажмите «Подготовить экран».`}):r.pause())},{immediate:!0}),g(()=>[j.value?.music?.volume,j.value?.soundEnabled],([e,t])=>{let n=J.value;n&&(n.volume=Math.max(0,Math.min(1,(e??100)/100)),n.muted=!t)},{immediate:!0});async function Xe(){if(!(!k.value||!A.value))try{await S.AdvanceScreenMusic({screenID:k.value,accessToken:A.value})}catch{B.value=`Не удалось синхронизировать музыку. Повторная попытка выполняется автоматически.`}}async function Ze(){if(!(!R.value||!O.query.screenID||!O.query.accessToken)){H.value=!0;try{await E.BindScreen({screenID:String(O.query.screenID),accessToken:String(O.query.accessToken),gameID:R.value}),U.value=!0}catch(e){D.error(e instanceof Error?e.message:`Не удалось привязать экран`)}finally{H.value=!1}}}async function Qe(){try{await document.documentElement.requestFullscreen?.()}catch{D.warning(`Полноэкранный режим недоступен в этом браузере`)}z.value=!0,await s();for(let e of[q.value,Y.value,J.value])if(e){e.muted=!0;try{await e.play(),e.pause(),e.currentTime=0,e.muted=!j.value?.soundEnabled}catch{B.value=`Браузер не разрешил подготовить воспроизведение на этом устройстве.`}}}return l(async()=>{if(Z.value){await Je(),V.value=!1;return}Ge();try{(!k.value||!A.value)&&await Ke(),await $(),Me.value=!0,X=window.setInterval(()=>{W.value=Date.now()},250)}catch(e){D.error(e instanceof Error?e.message:`Не удалось подготовить экран`)}finally{V.value=!1}}),ee(()=>{X!=null&&window.clearInterval(X),F!=null&&window.clearInterval(F)}),(s,l)=>(i(),_(p,null,[Z.value?(i(),_(`div`,ue,[o(y(b),{class:`binding-card`,title:`Привязка экрана`},{default:m(()=>[U.value?(i(),_(p,{key:0},[l[1]||=v(`p`,null,`Экран привязан к игре.`,-1),l[2]||=v(`p`,null,`Можно закрыть эту страницу.`,-1)],64)):(i(),_(p,{key:1},[l[4]||=v(`p`,null,`Выберите игру, к которой привязать экран.`,-1),o(y(ie),{value:R.value,"onUpdate:value":l[0]||=e=>R.value=e,options:Fe.value,placeholder:`Игра`},null,8,[`value`,`options`]),o(y(x),{type:`primary`,loading:H.value,disabled:R.value==null,onClick:Ze},{default:m(()=>[...l[3]||=[t(` Привязать `,-1)]]),_:1},8,[`loading`,`disabled`])],64))]),_:1})])):(i(),_(`div`,de,[V.value?(i(),_(`div`,fe,`Подготовка экрана…`)):(i(),_(p,{key:1},[j.value?.gameID?(i(),_(`div`,{key:1,class:`screen-content`,style:n(He.value)},[B.value?(i(),_(`p`,he,a(B.value),1)):e(``,!0),j.value.introAudio?u((i(),_(`div`,ge,[v(`audio`,{ref_key:`introAudioElement`,ref:q,src:Re.value,muted:!j.value.soundEnabled,controls:``},null,8,_e)],512)),[[C,Q.value===`SCREEN_MODE_INTRO`]]):e(``,!0),j.value.music?.playlist?.tracks?.length?(i(),_(`audio`,{key:2,ref_key:`musicAudioElement`,ref:J,src:Be.value,muted:!j.value.soundEnabled,onEnded:Xe},null,40,ve)):e(``,!0),j.value.conclusionVideo?u((i(),_(`div`,ye,[v(`video`,{ref_key:`conclusionVideoElement`,ref:Y,src:ze.value,muted:!j.value.soundEnabled,playsinline:``},null,8,be)],512)),[[C,Q.value===`SCREEN_MODE_CONCLUSION`]]):e(``,!0),Q.value===`SCREEN_MODE_CONCLUSION`&&!j.value.conclusionVideo?(i(),_(`div`,xe,`Видео закрывашки не задано`)):e(``,!0),Q.value===`SCREEN_MODE_INTRO_DONE`?(i(),_(`div`,Se,`Успехов`)):e(``,!0),Q.value===`SCREEN_MODE_CONCLUSION_DONE`?(i(),_(`div`,Ce,`Спасибо за игру!`)):e(``,!0),Q.value===`SCREEN_MODE_TEXT`?(i(),_(`div`,we,a(j.value.text),1)):e(``,!0),Q.value===`SCREEN_MODE_TIMER`?(i(),_(`div`,Te,[v(`h1`,Ee,a(j.value.timerLabel||`Перерыв`),1),v(`div`,De,a(Le.value),1)])):e(``,!0),Q.value===`SCREEN_MODE_RESULTS`?(i(),_(`div`,{key:9,ref_key:`resultsContainer`,ref:P,class:`results-screen`},[l[11]||=v(`h1`,null,`Результаты`,-1),v(`table`,null,[v(`thead`,null,[v(`tr`,null,[l[7]||=v(`th`,null,`Место`,-1),l[8]||=v(`th`,null,`Команда`,-1),(i(!0),_(p,null,r(N.value,e=>(i(),_(`th`,{key:e.code},a(e.code),1))),128)),l[9]||=v(`th`,null,`Сумма`,-1),l[10]||=v(`th`,null,`Ходы`,-1)])]),v(`tbody`,null,[(i(!0),_(p,null,r(M.value,e=>(i(),_(`tr`,{key:e.team?.ID},[v(`td`,null,a(e.place),1),v(`td`,null,a(e.team?.name),1),(i(!0),_(p,null,r(N.value,t=>(i(),_(`td`,{key:t.code},a(e.answers?.find(e=>e.questionCode===t.code)?.score??0),1))),128)),v(`td`,null,a(e.totalScore),1),v(`td`,null,a(e.actionsCount),1)]))),128))])])],512)):e(``,!0),Q.value===`SCREEN_MODE_COVER`?(i(),_(`div`,Oe,[j.value.coverImage?(i(),_(`img`,{key:0,src:j.value.coverImage,class:`cover-image`,alt:`Обложка дела`},null,8,ke)):e(``,!0),z.value?e(``,!0):(i(),_(`div`,Ae,[o(y(x),{type:`primary`,onClick:Qe},{default:m(()=>[...l[12]||=[t(`Подготовить экран`,-1)]]),_:1})]))])):e(``,!0)],4)):(i(),_(`div`,pe,[o(y(b),{class:`qr-card`,title:`Подключение экрана`},{default:m(()=>[Pe.value?(i(),_(`div`,me,[o(y(ae),{value:Pe.value,size:260,padding:0},null,8,[`value`])])):e(``,!0),l[6]||=v(`p`,null,`Отсканируйте QR телефоном организатора и выберите игру.`,-1),z.value?e(``,!0):(i(),c(y(x),{key:1,type:`primary`,onClick:Qe},{default:m(()=>[...l[5]||=[t(`Подготовить экран`,-1)]]),_:1}))]),_:1})]))],64))])),Z.value?(i(),c(se,{key:2,active:`games`})):e(``,!0)],64))}}),[[`__scopeId`,`data-v-cf99ca4a`]]),D=h({__name:`ScreenView`,setup(e){return(e,t)=>(i(),c(E))}});export{D as default};