Files
prod/frontend/dist/assets/ScreenView-CBMpnxAR.js
T
2026-10-27 14:53:56 +07:00

1 line
13 KiB
JavaScript

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