13 lines
180 KiB
JavaScript
13 lines
180 KiB
JavaScript
import{r as x,a as Ms,u as qe,L as ne,b as Fe,m as Te,O as Es,N as Rs,c as Re,B as As,R as Is,d as _,e as $s}from"./router-D9WH5XEU.js";(function(){const n=document.createElement("link").relList;if(n&&n.supports&&n.supports("modulepreload"))return;for(const a of document.querySelectorAll('link[rel="modulepreload"]'))i(a);new MutationObserver(a=>{for(const c of a)if(c.type==="childList")for(const t of c.addedNodes)t.tagName==="LINK"&&t.rel==="modulepreload"&&i(t)}).observe(document,{childList:!0,subtree:!0});function l(a){const c={};return a.integrity&&(c.integrity=a.integrity),a.referrerPolicy&&(c.referrerPolicy=a.referrerPolicy),a.crossOrigin==="use-credentials"?c.credentials="include":a.crossOrigin==="anonymous"?c.credentials="omit":c.credentials="same-origin",c}function i(a){if(a.ep)return;a.ep=!0;const c=l(a);fetch(a.href,c)}})();var ds={exports:{}},Ae={};/**
|
|||
|
|
* @license React
|
||
|
|
* react-jsx-runtime.production.min.js
|
||
|
|
*
|
||
|
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
||
|
|
*
|
||
|
|
* This source code is licensed under the MIT license found in the
|
||
|
|
* LICENSE file in the root directory of this source tree.
|
||
|
|
*/var Ts=x,Ls=Symbol.for("react.element"),Ds=Symbol.for("react.fragment"),qs=Object.prototype.hasOwnProperty,Fs=Ts.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner,Ps={key:!0,ref:!0,__self:!0,__source:!0};function hs(s,n,l){var i,a={},c=null,t=null;l!==void 0&&(c=""+l),n.key!==void 0&&(c=""+n.key),n.ref!==void 0&&(t=n.ref);for(i in n)qs.call(n,i)&&!Ps.hasOwnProperty(i)&&(a[i]=n[i]);if(s&&s.defaultProps)for(i in n=s.defaultProps,n)a[i]===void 0&&(a[i]=n[i]);return{$$typeof:Ls,type:s,key:c,ref:t,props:a,_owner:Fs.current}}Ae.Fragment=Ds;Ae.jsx=hs;Ae.jsxs=hs;ds.exports=Ae;var e=ds.exports,us,Be=Ms;us=Be.createRoot,Be.hydrateRoot;const ms={overview:"M4 13h6V4H4zm0 7h6v-4H4zm10 0h6v-9h-6zm0-16v4h6V4z",library:"M3 5h18v14H3zM7 5v14M17 5v14M3 9.5h4M3 14.5h4M17 9.5h4M17 14.5h4",people:"M15 19v-1.2a3.3 3.3 0 0 0-3.3-3.3H6.8A3.3 3.3 0 0 0 3.5 17.8V19M9.2 11a3.2 3.2 0 1 0 0-6.4 3.2 3.2 0 0 0 0 6.4ZM17 10.6a3 3 0 0 0-1.4-5.7M20.5 19v-1.2a3.3 3.3 0 0 0-2.4-3.2",person:"M18 20v-1.5a4 4 0 0 0-4-4h-4a4 4 0 0 0-4 4V20M12 10.5a3.5 3.5 0 1 0 0-7 3.5 3.5 0 0 0 0 7Z",tv:"M4 5h16v10H4zM9 19h6M12 15v4M8 2.5 12 5l4-2.5",sliders:"M4 7h10M18 7h2M4 17h2m4 0h10M14 4v6M6 14v6",clock:"M12 21a9 9 0 1 0 0-18 9 9 0 0 0 0 18ZM12 7.2V12l3 1.8",pulse:"M3 12h3.5L9 19l5-14 2.5 7H21",chart:"M4 19V9m5 10V5m5 14v-7m5 7V3",chip:"M8 8h8v8H8zM4.5 4.5h15v15h-15zM9 2v2.5M15 2v2.5M9 19.5V22M15 19.5V22M2 9h2.5M2 15h2.5M19.5 9H22M19.5 15H22",database:"M12 8.2c4.4 0 8-1.2 8-2.6S16.4 3 12 3 4 4.2 4 5.6s3.6 2.6 8 2.6ZM4 5.6v12.8C4 19.8 7.6 21 12 21s8-1.2 8-2.6V5.6M4 12c0 1.4 3.6 2.6 8 2.6s8-1.2 8-2.6",download:"M12 3.5v10m0 0 4-4m-4 4-4-4M4.5 18h15",upload:"M12 16V4m0 0L8 8m4-4 4 4M5 13v6h14v-6",sync:"M3.5 12a8.5 8.5 0 0 1 14.6-6M20.5 12a8.5 8.5 0 0 1-14.6 6M18 2.5V6h-3.5M6 21.5V18h3.5",search:"M10.5 17a6.5 6.5 0 1 1 0-13 6.5 6.5 0 0 1 0 13Zm4.6-1.9L20 20",star:"m12 3.2 2.6 5.4 5.9.8-4.3 4.1 1 5.9-5.2-2.8-5.2 2.8 1-5.9L3.5 9.4l5.9-.8L12 3.2Z",sparkle:"m10 3 1.5 4.3L16 8.8l-4.5 1.5L10 14.6 8.5 10.3 4 8.8l4.5-1.5L10 3ZM17.5 14l.9 2.4 2.6.9-2.6.9-.9 2.4-.9-2.4-2.6-.9 2.6-.9.9-2.4Z",bell:"M6.2 9.5a5.8 5.8 0 1 1 11.6 0c0 4.6 2.2 5.9 2.2 5.9H4s2.2-1.3 2.2-5.9M10 19.5a2 2 0 0 0 4 0",shield:"m12 3 7.5 3v5.4c0 5-3.2 8.2-7.5 9.6-4.3-1.4-7.5-4.6-7.5-9.6V6L12 3Zm-2.6 8.7 1.9 1.9 3.6-3.6",wrench:"m14.5 6.5 3-3 3 3-3 3M9 15l-5.5 5.5M13 4a5 5 0 0 0 6.5 6.5L10 20l-6-6 9.5-9.5Z",play:"M8 5.2v13.6L19 12 8 5.2ZM4 5v14",list:"M4 7h16M4 12h16M4 17h10",inbox:"M4 7h16v13H4zM8 4h8v3M8 12h8M8 16h5",history:"M3.5 12a8.5 8.5 0 1 0 2.8-6.3M3.5 4v4h4M12 7.5V12l3 1.8",check:"m5 12.5 4.5 4.5L19 7.5",alert:"M12 8.5v5m0 3.2h.01M10.3 4.4 2.7 17.5a2 2 0 0 0 1.7 3h15.2a2 2 0 0 0 1.7-3L13.7 4.4a2 2 0 0 0-3.4 0Z",power:"M12 3v9M7.5 6.2a7.5 7.5 0 1 0 9 0",key:"M14.5 3a6.5 6.5 0 1 0 3.4 12L19 14h2v-2h2V9.5l-2.5-2.5A6.5 6.5 0 0 0 14.5 3Zm-2.6 4.6a1.6 1.6 0 1 1-2.3 2.3 1.6 1.6 0 0 1 2.3-2.3Z",captions:"M4 5.5h16v13H4zM7 15h5m3 0h2M7 11h3m2 0h5",journey:"M4 6h5v5h6v7h5M7 3 4 6l3 3m10 6 3 3-3 3",plug:"M9 3v6M15 3v6M6.5 9h11v3.5a5.5 5.5 0 0 1-11 0zM12 18v3",calendar:"M4 6h16v15H4zM8 3v5M16 3v5M4 11h16",trash:"M4 7h16M9 7V4.5h6V7M6.5 7l1 13h9l1-13M10 11v5M14 11v5",plus:"M12 5v14M5 12h14",close:"M6 6l12 12M18 6 6 18",caret:"m6 9 6 6 6-6",external:"M14 4h6v6M20 4l-9 9M18 14v5.5H4.5V6H10",refresh:"M3.5 12a8.5 8.5 0 0 1 14.6-6M20.5 12a8.5 8.5 0 0 1-14.6 6M18 2.5V6h-3.5M6 21.5V18h3.5",filter:"M3.5 5.5h17l-6.5 7.5V20l-4-2v-5L3.5 5.5Z",menu:"M4 7h16M4 12h16M4 17h16",globe:"M12 21a9 9 0 1 0 0-18 9 9 0 0 0 0 18ZM3.5 9h17M3.5 15h17M12 3a14 14 0 0 1 0 18 14 14 0 0 1 0-18Z",logout:"M15 17l5-5-5-5M20 12H9M12 4H5v16h7"};function te({name:s,className:n}){const l=ms[s];return l?e.jsx("svg",{className:n??"ico",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",preserveAspectRatio:"xMidYMid meet","aria-hidden":"true",children:e.jsx("path",{d:l})}):null}function Ie({name:s,tone:n}){return ms[s]?e.jsx("span",{className:"glyph","data-tone":n,children:e.jsx(te,{name:s})}):null}const fe=[{id:"everyday",label:"Everyday",defaultCollapsed:!1,items:[{id:"overview",path:"/admin",label:"Overview",title:"Overview",intro:"
|
||
|
|
`),onChange:a=>l(a.target.value.split(`
|
||
|
|
`).map(c=>c.trim()).filter(Boolean))})})}function hn({initial:s,busy:n,onConfirm:l,onCancel:i}){const[a,c]=x.useState(s||"Memby TV");return e.jsx("div",{className:"scrim",onPointerDown:t=>t.target===t.currentTarget&&i(),children:e.jsxs("div",{className:"dialog",role:"dialog","aria-modal":"true",children:[e.jsx("h2",{children:"Name this device"}),e.jsx("p",{children:"The name a viewer sees in Settings → Devices, and what the console calls it."}),e.jsx(D,{label:"Device name",children:e.jsx("input",{type:"text",value:a,autoFocus:!0,maxLength:80,onChange:t=>c(t.target.value)})}),e.jsxs("div",{className:"dialog-actions",children:[e.jsx(R,{variant:"quiet",onClick:i,children:"Cancel"}),e.jsx(R,{variant:"primary",busy:n,disabled:!a.trim(),onClick:()=>l(a.trim()),children:"Rename"})]})]})})}function un({pending:s,busy:n,username:l,onConfirm:i,onCancel:a}){const t={"remove-device":{title:"Sign this device out of Memby?",body:"Its Emby account will not be changed. The set can sign in again at any time.",label:"Sign out",destructive:!0},"remove-account":{title:`Remove Memby access for ${l||"this user"}?`,body:"Every Memby device will be signed out. Their Emby account, viewing history and library permissions are untouched.",label:"Remove access",destructive:!0},"reset-recommendations":{title:"Clear this person's stored recommendation choices?",body:"Viewing history remains intact; only the explicit setup answers are removed.",label:"Clear",destructive:!0},"cancel-prompt":{title:"Cancel this person's queued recommendation prompt?",body:"They will not be invited to set up recommendations on their next launch.",label:"Cancel prompt",destructive:!1},"reset-preferences":{title:"Restore the Memby defaults for this person?",body:"Their televisions will pick the change up the next time they check in.",label:"Restore defaults",destructive:!0},"no-themes":{title:"Allow this person no colour schemes?",body:"They will be left on Midnight with nothing to choose between.",label:"Save anyway",destructive:!0}}[s.kind];return e.jsx(he,{title:t.title,body:t.body,confirmLabel:t.label,destructive:t.destructive,busy:!!n,onConfirm:i,onCancel:a})}function mn(s,n){if(s.kind==="toggle")return n?"On":"Off";if(s.kind==="choice"){const i=(s.options??[]).find(a=>a.value===n);return i?i.label:String(n??"")}if(s.kind==="number")return Number(n)===0&&s.unit?"No limit":s.unit?`${n} ${s.unit}`:String(n??"");const l=Array.isArray(n)?n:[];return l.length===0?"None":l.map(i=>{var a;return((a=(s.options??[]).find(c=>c.value===i))==null?void 0:a.label)??i}).join(", ")}function pn(){const{userId:s=""}=Re(),{wrap:n}=Q(),{busy:l,run:i}=Y(),a=`/admin/api/accounts/${encodeURIComponent(s)}`,{data:c,error:t,loading:o,reload:d}=J(`${a}/preferences/history`,{pollMs:3e4}),[r,j]=x.useState(new Set),[w,p]=x.useState(null),m=(c==null?void 0:c.username)||"this account",f=(c==null?void 0:c.devices)??[],u=(c==null?void 0:c.revisions)??[],v=(c==null?void 0:c.catalogue)??[],b=h=>j(g=>{const E=new Set(g);return E.has(h)?E.delete(h):E.add(h),E}),S=h=>i("restore",async()=>{await n(()=>F.post(`${a}/preferences/revisions/${h}/restore`),`Restored r${h}.`),p(null),await d()});return e.jsxs(e.Fragment,{children:[e.jsx(U,{title:"Settings history",intro:`Every change to ${m}'s synced settings, and which of their televisions has taken it.`,crumbs:e.jsxs(ne,{to:`/admin/accounts/${encodeURIComponent(s)}`,children:["← ",m]})}),e.jsx(B,{message:t}),o?e.jsx(W,{}):e.jsxs(e.Fragment,{children:[e.jsx(A,{title:"Where each device has got to",intro:"A set takes a change by fetching it, which it does within a few seconds of being told — so anything still behind is switched off, mid-film, or cannot reach the gateway.",icon:"tv",tone:"info",actions:c!=null&&c.saved?e.jsxs(M,{tone:c.currentSource==="admin"?"warn":"ok",children:["now on r",N(c.currentRevision)," · ",c.currentSource||"device"]}):e.jsx(M,{children:"defaults · never synced"}),children:f.length===0?e.jsx(Z,{children:"No television has been signed in to this account."}):e.jsx("div",{className:"list",children:f.map(h=>{const g=h.never?void 0:h.be
|
||
|
|
`)}):null,e.jsxs(ue,{children:["Command-line fallback: ",e.jsx("code",{children:(h==null?void 0:h.fallback)??"docker compose run --rm --build memby-builder release"})]})]}),l||!o?e.jsx(W,{rows:1}):e.jsxs(A,{title:"Update policy",intro:"Televisions check on every launch. An optional update is a prompt the viewer can dismiss; a required one covers the home screen until they update, so it needs a download URL that actually works.",icon:"download",tone:"info",actions:y!=null&&y.enabled?e.jsxs(M,{tone:ee?"warn":"ok",children:[re?"sign-out · ":ee?"required · ":"optional · ",y.latestVersion]}):e.jsx(M,{children:"off"}),footer:e.jsxs(e.Fragment,{children:[e.jsx(R,{variant:"primary",busy:c==="save",onClick:()=>o.required?j(!0):void L(!0),children:"Save policy"}),e.jsx(R,{busy:c==="off",onClick:()=>void L(!1),children:"Turn prompts off"})]}),children:[e.jsxs("div",{className:"fields",children:[e.jsx(D,{label:"Latest version",children:e.jsx("input",{type:"text",value:o.version,placeholder:"0.2.63",onChange:k=>K({version:k.target.value})})}),e.jsx(D,{label:"APK URL",children:e.jsx("input",{type:"text",value:o.url,placeholder:"https://nas/memby/memby-0.2.63.apk",onChange:k=>K({url:k.target.value})})})]}),e.jsx(D,{label:"What's new",hint:"Shown on the television above the update button.",children:e.jsx("input",{type:"text",value:o.notes,placeholder:"One line the viewer reads",onChange:k=>K({notes:k.target.value})})}),e.jsx(D,{label:"Sign out builds below",hint:"The destructive compatibility floor. Leave blank to keep every supported viewer signed in.",children:e.jsx("input",{type:"text",value:o.retireBelow,placeholder:"0.2.44",onChange:k=>K({retireBelow:k.target.value})})}),e.jsx(z,{label:"Require this update",hint:"Blocks the home screen on every television below this version.",checked:o.required,onChange:k=>K({required:k})}),e.jsx(z,{label:"Set the destructive floor to this update",hint:"Deletes sessions on every older television when it next uses Memby, then shows the required update screen.",checked:o.destructive,onChange:k=>K(k?{destructive:!0,required:!0,retireBelow:o.version.trim()}:{destructive:!1,retireBelow:o.retireBelow.trim()===o.version.trim()?"":o.retireBelow})})]}),r&&o?e.jsx(he,{title:o.destructive?"Sign every older television out?":"Require this update?",body:o.destructive?"This deletes sessions on every older television and forces viewers to sign in again after updating.":"Required updates block the home screen on every television below this version until they update.",confirmLabel:"Publish",destructive:o.destructive,busy:c==="save",onConfirm:()=>void L(!0),onCancel:()=>j(!1)}):null,w?e.jsx(he,{title:"Build a required update?",body:"When this signed APK is published, every older television will be blocked until it installs the update.",confirmLabel:"Build and publish",busy:c==="release",onConfirm:()=>void I(),onCancel:()=>p(!1)}):null]})}const Bn=2e4,Un=3e3,Vn=[{value:60,label:"Every minute"},{value:300,label:"Every 5 minutes"},{value:600,label:"Every 10 minutes"},{value:900,label:"Every 15 minutes"},{value:1800,label:"Every 30 minutes"},{value:3600,label:"Hourly"},{value:10800,label:"Every 3 hours"},{value:21600,label:"Every 6 hours"},{value:43200,label:"Every 12 hours"},{value:86400,label:"Daily"},{value:604800,label:"Weekly"}];function _n(s){const n=[...Vn];for(const l of[s.defaultIntervalSeconds,s.intervalSeconds])l>0&&!n.some(i=>i.value===l)&&n.push({value:l,label:Le(l).replace(/^every /,"Every ")});return n.sort((l,i)=>l.value-i.value)}function Xe(s){return s==="failed"?"bad":s==="running"?"info":s==="skipped"?"warn":"ok"}function Wn(){const{wrap:s}=Q(),{busy:n,run:l}=Y(),[i,a]=x.useState(!1),{data:c,error:t,loading:o,reload:d}=J("/admin/api/tasks?limit=60",{pollMs:i?Un:Bn}),r=(c==null?void 0:c.tasks)??[],j=r.some(g=>g.running);j!==i&&a(j);const w=g=>l(g.id,async()=>{await s(()=>F.post(`/admin/api/tasks/${encodeURIComponent(g.id)}/run`),`${g.name} started.`),await d()}),p=(g,E)=>l(`${g.id}:enabled`,async()=>{await s(()=>F.put(`/admin/api/tasks/${encodeURIComponent(g.id)}`,{enabled:E}),E?`${g.name} switched
|