Files
prod/frontend/dist/assets/ScreenView--qKU1csM.js
T
2026-10-27 12:05:04 +07:00

1 line
13 KiB
JavaScript

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