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