peertube-plugin-youth-schedule
Version:
PeerTube plugin: youth protection schedule (configurable HH:mm slots and end time)
2 lines (1 loc) • 7.25 kB
JavaScript
var o={decided:!1,allowed:!0,open:null,end:null,videoUuid:null},u=new WeakMap;async function L({registerHook:c}){let h=await fetch("/plugins/youth-schedule/router/config").then(e=>e.json()).catch(()=>({timeSource:"server",endTime:"06:00"})),b=()=>{let e=new Date;return e.getHours()*60+e.getMinutes()},S=e=>new Promise(t=>setTimeout(t,e));async function m(e){let t=new URLSearchParams;h.timeSource==="user"&&t.set("clientMinutes",String(b()));let i="/plugins/youth-schedule/router/video/".concat(e,"/youth-allowed?").concat(t),r=[300,800,1500];for(let n=0;n<=r.length;n++){try{let l=new AbortController,y=setTimeout(()=>l.abort(),5e3),p=await fetch(i,{signal:l.signal});if(clearTimeout(y),p.ok)return await p.json();console.warn("[YouthSchedule] API error:",p.status,p.statusText)}catch(l){console.warn("[YouthSchedule] Network error attempt ".concat(n+1,":"),l)}n<r.length&&await S(r[n])}return{allowed:!1,isError:!0}}function s(){let e=["#plugin-selector-player-container","#videojs-wrapper","#video-wrapper","#player"];for(let r of e){let n=document.querySelector(r);if(n)return console.log("[YouthSchedule] player root via selector:",r),n}let t=document.querySelector(".video-js.vjs-peertube-skin")||document.querySelector('[id^="vjs_video_"]');if(t)return console.log("[YouthSchedule] player root via videojs container"),t.closest("#videojs-wrapper, #video-wrapper")||t;let i=document.querySelector("video.vjs-tech")||document.querySelector("video");if(i){let r=i.closest("#videojs-wrapper, #video-wrapper, .video-js")||i.parentElement;if(r)return console.log("[YouthSchedule] player root via video parent"),r}return console.warn("[YouthSchedule] player root not found; please share DOM around <video>."),null}if(!document.getElementById("youth-schedule-style")){let e=document.createElement("style");e.id="youth-schedule-style",e.textContent="\n .youth-schedule-init-hidden { visibility: hidden !important; }\n .youth-schedule-overlay { position: absolute; inset: 0; background: rgba(0,0,0,0.75); display: flex; align-items: center; justify-content: center; z-index: 2147483647; padding: 16px; text-align: center; }\n .youth-schedule-overlay .msg { max-width: 720px; color: #fff; font-family: system-ui, -apple-system, Segoe UI, Roboto, Ubuntu, 'Helvetica Neue', Arial, sans-serif; }\n .youth-schedule-overlay .msg .title { font-size: 1.1rem; margin-bottom: 8px; }\n .youth-schedule-overlay .msg .subtitle { font-size: .95rem; opacity: .9; }\n .youth-schedule-block-video video, .youth-schedule-block-video .video-js { pointer-events: none !important; }\n ",document.head.appendChild(e)}function w(e){if(!e||u.has(e))return;let t=i=>{i.preventDefault(),i.stopPropagation(),e.pause(),e.currentTime=0};e.addEventListener("play",t,{capture:!0,passive:!1}),e.addEventListener("playing",t,{capture:!0,passive:!1}),e.addEventListener("loadstart",t,{capture:!0,passive:!1});try{e.pause(),e.currentTime=0}catch(i){}u.set(e,t)}function E(e){if(!e||!u.has(e))return;let t=u.get(e);e.removeEventListener("play",t,{capture:!0}),e.removeEventListener("playing",t,{capture:!0}),e.removeEventListener("loadstart",t,{capture:!0}),u.delete(e)}function d(e){if(!e)return;e.classList.remove("youth-schedule-block-video");let t=e.querySelector(".youth-schedule-overlay");t&&t.remove();let i=e.querySelector("video");i&&E(i)}let a={};function g(e){if(!e)return;let t=getComputedStyle(e).position;(t==="static"||!t)&&(e.style.position="relative"),e.classList.add("youth-schedule-block-video"),e.classList.remove("youth-schedule-init-hidden");let i=e.querySelector(".youth-schedule-overlay");i||(i=document.createElement("div"),i.className="youth-schedule-overlay",e.appendChild(i)),i.innerHTML='\n <div class="msg">\n <div class="title">\xDCberpr\xFCfung... / Checking...</div>\n </div>\n '}function f(e,t,i,r){if(!e)return;let n=getComputedStyle(e).position;(n==="static"||!n)&&(e.style.position="relative"),e.classList.add("youth-schedule-block-video"),e.classList.remove("youth-schedule-init-hidden");let l=e.querySelector(".youth-schedule-overlay");l||(l=document.createElement("div"),l.className="youth-schedule-overlay",e.appendChild(l)),r?l.innerHTML='\n <div class="msg">\n <div class="title">Dieses Video ist aus Jugendschutzgr\xFCnden derzeit nicht verf\xFCgbar (Fehler bei der Pr\xFCfung).</div>\n </div>\n ':l.innerHTML='\n <div class="msg">\n <div class="title">Dieses Video ist aus Jugendschutzgr\xFCnden derzeit nicht verf\xFCgbar.</div>\n <div class="subtitle">Freigabe von '.concat(t||"\u2014"," bis ").concat(i,".</div>\n </div>\n ");let y=e.querySelector("video");y&&w(y)}c({target:"action:video-watch.video.loaded",handler:async({video:e})=>{try{if(!e||!e.uuid)return;let t=s();t&&(o.videoUuid&&o.videoUuid!==e.uuid&&d(t),g(t)),o={decided:!1,allowed:!0,open:null,end:null,videoUuid:e.uuid,isError:!1};let i=m(e.uuid);a[e.uuid]=i;let r=await i;o={decided:!0,allowed:!!r.allowed,open:r.openLabel||null,end:r.endLabel||h.endTime||"06:00",videoUuid:e.uuid,isError:!!r.isError},console.log("[YouthSchedule:video.loaded] decision",o),t&&(o.allowed?d(t):(f(t,o.open,o.end,o.isError),v(t)))}catch(t){console.warn("[YouthSchedule:video.loaded] error",t)}}}),c({target:"action:video-watch.init",handler:async e=>{try{let t=e&&e.video&&e.video.uuid;if(!t){let l=s();l&&l.classList.remove("youth-schedule-init-hidden");return}if(o.decided&&o.videoUuid!==t){o={decided:!1,allowed:!0,open:null,end:null,videoUuid:null,isError:!1};let l=s();l&&d(l)}if(o.decided&&o.videoUuid===t)return;let i=s();i&&g(i);let r=m(t);a[t]=r;let n=await r;o={decided:!0,allowed:!!n.allowed,open:n.openLabel||null,end:n.endLabel||h.endTime||"06:00",videoUuid:t,isError:!!n.isError},console.log("[YouthSchedule:init] decision",o),i&&(o.allowed?d(i):(f(i,o.open,o.end,o.isError),v(i)))}catch(t){console.warn("[YouthSchedule:init] error",t)}}}),c({target:"filter:internal.video-watch.player.build-options.result",handler:async(e,t)=>{try{let i=t&&t.video&&t.video.uuid;i&&a[i]&&await a[i],o.decided&&o.allowed===!1&&(!i||o.videoUuid===i)&&(e.controls=!1,e.responsive=!1,e.fluid=!1,e.autoplay=!1,e.userActions||(e.userActions={}),e.userActions.hotkeys=!1)}catch(i){}return e}});function v(e){if(!e||e.dataset.youthScheduleMonitored)return;e.dataset.youthScheduleMonitored="true",new MutationObserver(()=>{if(!o.decided||o.allowed)return;let r=e.querySelector("video");r&&!u.has(r)&&w(r)}).observe(e,{childList:!0,subtree:!0});let i=e.querySelector("video");i&&!o.allowed&&w(i)}c({target:"action:video-watch.player.loaded",handler:async({video:e})=>{try{if(!e||!e.uuid)return;if(o.decided&&o.videoUuid!==e.uuid){o={decided:!1,allowed:!0,open:null,end:null,videoUuid:null,isError:!1};let n=s();n&&d(n)}if(o.decided&&o.videoUuid===e.uuid){if(o.allowed)d(s());else{let n=s();n&&(f(n,o.open,o.end,o.isError),v(n))}return}let t=m(e.uuid);a[e.uuid]=t;let i=await t;if(o={decided:!0,allowed:!!i.allowed,open:i.openLabel||null,end:i.endLabel||h.endTime||"06:00",videoUuid:e.uuid,isError:!!i.isError},console.log("[YouthSchedule:player.loaded] decision",o),o.allowed){d(s());return}let r=s();if(!r)return;f(r,o.open,o.end,o.isError),v(r)}catch(t){}}})}export{L as register};