mirror of
https://github.com/PR0M3TH3AN/bitvid.git
synced 2026-10-27 07:52:24 +00:00
- Format `css/tailwind.source.css` with Prettier. - Add allowlist entry for `VideoCard.js` media query pixel value in `scripts/check-design-tokens.mjs`. - Remove accidental artifact `js/ui/dm/jules_session_4520373547615093905.zip`. - Fix bug in `js/app.js` and `js/services/moderationActionController.js` where blocked users' videos were not correctly hidden in the UI immediately after blocking. - Fix bug in `tests/app/moderation-overrides.test.mjs` where `userBlocks` mocks were insufficient to reflect state changes.
2 lines
25 KiB
JavaScript
2 lines
25 KiB
JavaScript
import{IS_DEV_MODE as Le,IS_VERBOSE_DEV_MODE as Ce,IS_LOCKDOWN_MODE as Ae,LOCKDOWN_TITLE as bt,LOCKDOWN_MESSAGE as Et,ADMIN_SUPER_NPUB as Tt,ADMIN_DM_IMAGE_URL as gt,BITVID_WEBSITE_URL as _t,BLOG_URL as St,COMMUNITY_URL as wt,NOSTR_URL as Lt,GITHUB_URL as Ct,BETA_URL as At,DNS_URL as xt,TIP_JAR_URL as vt,MAX_WALLET_DEFAULT_ZAP as It,PLATFORM_FEE_PERCENT as Ot,PLATFORM_LUD16_OVERRIDE as Nt,DEFAULT_RELAY_URLS_OVERRIDE as Bt,ADMIN_WHITELIST_MODE_STORAGE_KEY as Mt,DEFAULT_WHITELIST_MODE_ENABLED as Dt,ALLOW_NSFW_CONTENT as Rt,DEFAULT_TRUST_SEED_NPUBS as Ht,DEFAULT_BLUR_THRESHOLD as Ut,DEFAULT_AUTOPLAY_BLOCK_THRESHOLD as kt,DEFAULT_TRUSTED_MUTE_HIDE_THRESHOLD as Ft,DEFAULT_TRUSTED_SPAM_HIDE_THRESHOLD as Pt,WATCH_HISTORY_KIND as Vt,WATCH_HISTORY_LIST_IDENTIFIER as Wt,WATCH_HISTORY_MAX_ITEMS as qt,WATCH_HISTORY_BATCH_RESOLVE as jt,WATCH_HISTORY_BATCH_PAGE_SIZE as $t,WATCH_HISTORY_PAYLOAD_MAX_BYTES as Yt,WATCH_HISTORY_FETCH_EVENT_LIMIT as Gt,WATCH_HISTORY_CACHE_TTL_MS as zt,VIEW_COUNT_DEDUPE_WINDOW_SECONDS as Kt,VIEW_COUNT_BACKFILL_MAX_DAYS as Xt,VIEW_COUNT_CACHE_TTL_MS as Zt,ENSURE_PRESENCE_REBROADCAST_COOLDOWN_SECONDS as Jt}from"../config/instance-config.js";var H=!!Le;var xe=!!Ce;var ve=!!Ae;typeof window<"u"&&(window.__BITVID_DEV_MODE__=H,window.__BITVID_VERBOSE_DEV_MODE__=xe,window.__BITVID_LOCKDOWN_MODE__=ve);var k=()=>{};function Ie(){return typeof console>"u"||console===null?null:console}function Oe(){let e=Ie();if(!e)return{log:k,info:k,debug:k,warn:k,error:k};let t=typeof e.log=="function"?e.log.bind(e):k;return{log:typeof e.log=="function"?e.log.bind(e):t,info:typeof e.info=="function"?e.info.bind(e):t,debug:typeof e.debug=="function"?e.debug.bind(e):t,warn:typeof e.warn=="function"?e.warn.bind(e):t,error:typeof e.error=="function"?e.error.bind(e):t}}var _=Oe(),M="[bitvid]";function ee(e){if(e.length===0)return{args:e,force:!1};let t=e[e.length-1];if(t&&typeof t=="object"&&!Array.isArray(t)&&Object.prototype.hasOwnProperty.call(t,"force")){let r=[...e],o=r.pop();return{args:r,force:!!o.force}}return{args:e,force:!1}}var S=Object.freeze({log:(...e)=>{H&&_.log(...e)},info:(...e)=>{H&&_.info(...e)},debug:(...e)=>{H&&_.debug(...e)},warn:(...e)=>{H&&_.warn(...e)},error:(...e)=>{H&&_.error(...e)}}),y=Object.freeze({log:(...e)=>{let{args:t,force:r}=ee(e);if(!r&&t.length===0)return;if(r){_.log(M,...t);return}let[o,...n]=t;if(typeof o=="string"&&n.length===0){_.log(`${M} ${o}`);return}o!==void 0&&_.log(M,o)},info:(...e)=>{let{args:t,force:r}=ee(e);if(!r&&t.length===0)return;if(r){_.info(M,...t);return}let[o,...n]=t;if(typeof o=="string"&&n.length===0){_.info(`${M} ${o}`);return}o!==void 0&&_.info(M,o)},warn:(...e)=>{_.warn(M,...e)},error:(...e)=>{_.error(M,...e)}}),te=Object.freeze({dev:S,user:y});function Ne(e){return!e||typeof e!="object"?!1:Object.entries({dev:["log","info","debug","warn","error"],user:["log","info","warn","error"]}).every(([r,o])=>{let n=e[r];return!n||typeof n!="object"?!1:o.every(c=>typeof n[c]=="function")})}typeof window<"u"&&(Ne(window.bitvidLogger)||(window.bitvidLogger=te));Object.freeze(te);import{THEME_ACCENT_OVERRIDES as re}from"../config/instance-config.js";var K="bitvid:theme",v="dark",Be=new Set(["light","dark"]),ne={dark:"#0f172a",light:"#f8fafc"},oe=["[data-theme-toggle]",'[data-action="toggle-theme"]',".js-theme-toggle","#themeToggle"],ie=Object.freeze({accent:"--color-accent",accentStrong:"--color-accent-strong",accentPressed:"--color-accent-pressed"}),ae=new WeakSet,W=new Set,D=null,se=!1,F=null,I=()=>typeof window<"u"&&typeof document<"u",q=e=>{if(typeof e!="string")return null;let t=e.trim().toLowerCase();return t==="default"||t===""?v:Be.has(t)?t:null},Me=()=>{if(!I())return null;try{let e=window.localStorage.getItem(K);return q(e)}catch(e){return y.warn("Unable to read stored theme preference:",e),null}},De=e=>{if(I())try{window.localStorage.setItem(K,e)}catch(t){y.warn("Unable to persist theme preference:",t)}},G=()=>{if(!I())return null;let{documentElement:e}=document;return e instanceof HTMLElement?e:null},Re=e=>typeof e=="string"?e.trim():"",He=e=>{if(!e||typeof e!="object")return null;let t=Object.entries(e).reduce((r,[o,n])=>{if(!n||typeof n!="object")return r;let c=Object.entries(n).reduce((a,[u,d])=>(Object.prototype.hasOwnProperty.call(ie,u)&&(a[u]=d),a),{});return Object.keys(c).length>0&&(r[o]=c),r},{});return Object.keys(t).length>0?t:null},ce=e=>{F=He(e)};ce(typeof re<"u"?re:null);var le=(e,t)=>{if(!e)return;let r=F&&typeof F=="object"&&F[t]&&typeof F[t]=="object"?F[t]:null,o=!1;Object.entries(ie).forEach(([n,c])=>{let a=r?r[n]:null,u=Re(a);u?(e.style.setProperty(c,u),o=!0):e.style.removeProperty(c)}),o?e.dataset.themeAccent="override":e.removeAttribute("data-theme-accent")},Ue=e=>{if(!I())return;let t=document.querySelector('meta[name="theme-color"]');if(!t)return;let r=G();if(!r)return;let o="";try{typeof window.getComputedStyle=="function"&&(o=getComputedStyle(r).getPropertyValue("--color-page").trim())}catch(a){y.warn("Unable to compute theme color token:",a)}let n=ne[e]||ne[v],c=o||n;c&&t.setAttribute("content",c)},de=(e,t)=>{if(!(e instanceof HTMLElement))return;e.dataset.themeState=t,e.setAttribute("aria-pressed",t==="dark"?"true":"false");let r=t==="dark"?"Switch to light theme":"Switch to dark theme";e.setAttribute("aria-label",r),e.setAttribute("title",r);let o=e.querySelector("[data-theme-toggle-label]")||e.querySelector(".sr-only");o&&(o.textContent=r);let n=e.querySelector("[data-theme-toggle-icon]")||e.querySelector('[aria-hidden="true"]');if(n){let c=typeof SVGElement<"u"?SVGElement:null;if(c&&n instanceof c||n instanceof Element&&!!n.querySelector("svg"))n instanceof Element&&n.setAttribute("data-theme-icon-state",t);else{let u=e.dataset.iconLight||"\u2600\uFE0F",d=e.dataset.iconDark||"\u{1F319}";n.textContent=t==="dark"?u:d}}},ke=()=>{if(!I()){W.clear();return}W.forEach(e=>{(!(e instanceof HTMLElement)||!document.contains(e))&&W.delete(e)})},Fe=e=>{ke(),W.forEach(t=>{de(t,e)})},Pe=e=>{!(e instanceof HTMLElement)||ae.has(e)||(e.addEventListener("click",t=>{t.preventDefault(),We(D==="dark"?"light":"dark")}),e.dataset.themeToggleBound="true",ae.add(e))},Ve=(e=document)=>{if(!I())return[];let t=new Set,r=e&&typeof e.querySelectorAll=="function"?e:document;return oe.forEach(o=>{try{r.querySelectorAll(o).forEach(n=>{n instanceof HTMLElement&&t.add(n)})}catch(n){y.warn(`Invalid selector for theme toggle: ${o}`,n)}}),e instanceof HTMLElement&&oe.forEach(o=>{e.matches(o)&&t.add(e)}),Array.from(t)},X=(e,{persist:t=!0}={})=>{let r=q(e)||v;D=r;let o=G();return o&&(o.dataset.theme=r,le(o,r)),t&&De(r),Ue(r),Fe(r),r},ue=e=>{ce(e);let t=G();if(!t)return;le(t,D||v)};var We=e=>I()?X(e,{persist:!0}):(D=q(e)||v,D),qe=(e=document)=>{if(!I())return;Ve(e).forEach(r=>{W.add(r),Pe(r),de(r,D||v)})},je=()=>{if(!I())return v;let e=G();return(e?q(e.dataset.theme):null)||Me()||v},$e=e=>{if(!e||e.key!==K)return;let t=q(e.newValue)||v;t!==D&&X(t,{persist:!1})},fe=()=>{if(!I()){D=v;return}se||(window.addEventListener("storage",$e),se=!0);let e=je();X(e,{persist:!0}),qe(document)};var pe={info:"torrent-toast torrent-toast--info",success:"torrent-toast torrent-toast--success",error:"torrent-toast torrent-toast--error",warn:"torrent-toast torrent-toast--warn"},me="transition duration-200 ease-out",Ye="beacon-toast-motion",Z="data-beacon-motion";function Ge(e,t){let r=e?.defaultView;if(r&&typeof r.requestAnimationFrame=="function"){r.requestAnimationFrame(t);return}setTimeout(t,16)}function ze(e){let t=e||(typeof document<"u"?document:null);if(!t)return null;let r=t.getElementById("beacon-toast-container");if(!r){r=t.createElement("div"),r.id="beacon-toast-container",r.setAttribute("role","region"),r.setAttribute("aria-live","polite"),r.className=["pointer-events-none","fixed","inset-x-0","top-0","z-overlay-toast","flex","w-full","flex-col","items-center","gap-3","px-4","pt-6","sm:items-end","sm:px-6","sm:pt-8"].join(" ");let o=t.body||t.getElementsByTagName?.("body")?.[0];o&&o.appendChild(r)}return r}function Ke(e,t,r){let o=e.createElement("div");o.className=[me,r].join(" "),o.setAttribute("role","status"),o.setAttribute("tabindex","0"),o.textContent=t;let n=e.createElement("button");n.type="button",n.className=["notification-dismiss","focus-ring","absolute","right-3","top-3"].join(" "),n.setAttribute("aria-label","Dismiss notification"),n.innerHTML='<svg class="h-4 w-4" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M3.75 3.75l8.5 8.5"></path><path d="M12.25 3.75l-8.5 8.5"></path></svg>';let c=e.createElement("div");return c.className=["relative","w-full",me,Ye].join(" "),c.setAttribute(Z,"exit"),c.appendChild(o),o.appendChild(n),{wrapper:c,toast:o,closeButton:n}}function Xe(e,t=setTimeout,r=clearTimeout){return{show(o,n={}){if(!o)return;let c=n.type&&pe[n.type]?n.type:"info",a=ze(e);if(!a)return;let{wrapper:u,toast:d,closeButton:L}=Ke(e,o,pe[c]);a.appendChild(u),Ge(e,()=>{u.setAttribute(Z,"enter")});let w=typeof n.duration=="number"?n.duration:3500,m=()=>{u.setAttribute(Z,"exit");let B=t(()=>{u.parentNode&&u.parentNode.removeChild(u)},200);return L.removeEventListener("click",C),d.removeEventListener("keydown",b),L.removeEventListener("keydown",b),B},C=()=>m(),b=B=>{B.key==="Escape"&&(B.stopPropagation(),m())};L.addEventListener("click",C),d.addEventListener("keydown",b),L.addEventListener("keydown",b);let N=null;return n.sticky||(N=t(()=>{m()},w)),{dismiss(){N&&r(N),m()}}},set(o,n){return typeof n=="string"?this.show(o,{type:n}):this.show(o,n)},info(o,n={}){return this.show(o,{...n,type:"info"})},success(o,n={}){return this.show(o,{...n,type:"success"})},error(o,n={}){return this.show(o,{...n,type:"error"})},warn(o,n={}){return this.show(o,{...n,type:"warn"})}}}function he(e,t=setTimeout,r=clearTimeout){return Xe(e,t,r)}var J=[{key:"name",label:"Name",headerClass:"w-full sm:w-1/3 text-left",cellClass:"font-medium text-text truncate"},{key:"progress",label:"Progress",headerClass:"w-24 text-right",cellClass:"tabular-nums text-right",formatter:"progress"},{key:"downloadSpeed",label:"\u2193 Speed",headerClass:"w-24 text-right",cellClass:"tabular-nums text-right",formatter:"bytesPerSecond"},{key:"uploadSpeed",label:"\u2191 Speed",headerClass:"w-24 text-right",cellClass:"tabular-nums text-right",formatter:"bytesPerSecond"},{key:"numPeers",label:"Peers",headerClass:"w-20 text-right",cellClass:"tabular-nums text-right",formatter:"integer"},{key:"ratio",label:"Ratio",headerClass:"w-20 text-right",cellClass:"tabular-nums text-right",formatter:"ratio"}];function Ze(e){return e?e.infoHash||e.magnetURI||e.name||String(Math.random()):""}function Je(e,t){return!e||!t?!1:e===t||e.magnetURI&&e.magnetURI===t.magnetURI||e.infoHash&&e.infoHash===t.infoHash}function Qe(e){return typeof e!="number"||Number.isNaN(e)?"":`${(e*100).toFixed(1)}%`}function et(e){return typeof e!="number"||!Number.isFinite(e)?"0.00":e.toFixed(2)}function tt(e){return typeof e!="number"||!Number.isFinite(e)?"0":Math.max(0,Math.floor(e)).toString()}function rt(e,t){if(typeof t=="function")return t(e,!0)||"";if(typeof e!="number"||Number.isNaN(e)||e<1)return"";let r=["B","kB","MB","GB","TB"],o=Math.min(Math.floor(Math.log(e)/Math.log(1e3)),r.length-1);return`${(e/Math.pow(1e3,o)).toFixed(1)} ${r[o]}/s`}function nt(e,t){let r=e.formatter;if(typeof r=="function")return r;let o=t?.[r];if(typeof o=="function")return o;switch(r){case"progress":return Qe;case"ratio":return et;case"integer":return tt;case"bytesPerSecond":return n=>rt(n,t?.bytes);default:return n=>n}}function ye({documentRef:e=typeof document<"u"?document:null,root:t,onSelect:r,formatters:o={}}={}){if(!e)throw new Error("createTorrentTable requires a document reference");if(!(t instanceof e.defaultView.HTMLElement))throw new Error("createTorrentTable requires a valid root element");let n=e;t.innerHTML="";let c=n.createElement("div");c.className="overflow-hidden rounded-xl border border-border-translucent bg-surface shadow-sm";let a=n.createElement("div");a.className="overflow-x-auto",c.appendChild(a);let u=n.createElement("table");u.className="min-w-full divide-y divide-border-translucent text-sm",a.appendChild(u);let d=n.createElement("thead");d.className="bg-surface-alt text-muted-strong";let L=n.createElement("tr");J.forEach(E=>{let x=n.createElement("th");x.setAttribute("scope","col"),x.className="px-4 py-3 text-left text-xs font-semibold uppercase tracking-wide",E.headerClass&&(x.className+=` ${E.headerClass}`),x.textContent=E.label,L.appendChild(x)}),d.appendChild(L),u.appendChild(d);let w=n.createElement("tbody");w.className="divide-y divide-border-translucent",u.appendChild(w);let m=n.createElement("tbody"),C=n.createElement("tr"),b=n.createElement("td");b.className="px-4 py-8 text-center text-sm text-muted",b.colSpan=J.length,b.textContent="No active torrents yet. Add a magnet link to get started.",C.appendChild(b),m.appendChild(C),u.appendChild(m),t.appendChild(c);function N(E=[],x=null){let P=Array.isArray(E)?E:[];if(w.innerHTML="",!P.length){w.hidden=!0,m.hidden=!1;return}w.hidden=!1,m.hidden=!0;for(let O of P){let g=n.createElement("tr");g.className=["group","align-middle","cursor-pointer","transition","hover:bg-panel-hover","focus-visible:outline","focus-visible:outline-2","focus-visible:outline-offset-2","focus-visible:outline-info"].join(" "),g.setAttribute("role","button"),g.setAttribute("tabindex","0"),g.dataset.torrentId=Ze(O),Je(x,O)?(g.classList.add("bg-info/10","text-text"),g.setAttribute("aria-pressed","true")):g.setAttribute("aria-pressed","false"),g.addEventListener("click",()=>{typeof r=="function"&&r(O)}),g.addEventListener("keydown",A=>{(A.key==="Enter"||A.key===" ")&&(A.preventDefault(),typeof r=="function"&&r(O))}),J.forEach(A=>{let U=n.createElement("td");U.className="px-4 py-3",A.cellClass&&(U.className+=` ${A.cellClass}`);let z=O?O[A.key]:void 0,s=nt(A,o)(z,O,A),i=n.createElement("span");i.textContent=s==null?"":String(s),U.appendChild(i),g.appendChild(U)}),w.appendChild(g)}}function B(){t.innerHTML=""}return{render:N,destroy:B}}var ot="2.0",ge=["wss://tracker.btorrent.xyz","wss://tracker.openwebtorrent.com"],be={announce:ge},at={announce:ge};function j(e,t=!1){if(typeof e!="number"||Number.isNaN(e))return"";if(e<1)return t?"":"0 B";let r=["B","kB","MB","GB","TB"],o=Math.min(Math.floor(Math.log(e)/Math.log(1e3)),r.length-1);return`${(e/Math.pow(1e3,o)).toFixed(1)} ${r[o]}${t?"/s":""}`}function st(e){return typeof e!="number"||Number.isNaN(e)?"":`${(e*100).toFixed(1)}%`}function Ee(e){return typeof e!="number"||!Number.isFinite(e)?"0.00":e.toFixed(2)}function it(e,t){return!e||!t?!1:!!(e===t||e.infoHash&&t.infoHash&&e.infoHash===t.infoHash||e.magnetURI&&t.magnetURI&&e.magnetURI===t.magnetURI)}function ct(e){if(!(!e||!Array.isArray(e.files))&&(e.files.forEach(t=>{typeof t.priority!="string"&&(t.priority="0"),typeof t.getBlobURL=="function"&&t.getBlobURL((r,o)=>{r||!o||(t.url=o)})}),e.torrentFile&&typeof Blob=="function"&&typeof URL<"u"))try{let t=new Blob([e.torrentFile],{type:"application/x-bittorrent"});if(e.torrentFileBlobURL=URL.createObjectURL(t),!e.fileName){let r=e.name||"download";e.fileName=`${r}.torrent`}}catch(t){S.warn("[beacon] Failed to create torrent blob URL",t)}}function lt(e,t){if(!e)return;let r=typeof t=="string"?t:String(t??"0");if(e.priority=r,r==="-1"){typeof e.deselect=="function"&&e.deselect();return}let o=Number.parseInt(r,10);Number.isFinite(o)&&typeof e.select=="function"&&e.select(o)}function Te(e,t){if(!Array.isArray(t)||t.length===0)return null;if(!e)return t[0];let r=t.find(o=>it(o,e));return r||t[0]}function _e({documentRef:e=typeof document<"u"?document:null,WebTorrentCtor:t}={}){if(!e)throw new Error("createBeaconApp requires a document reference");let r=e.defaultView||globalThis,o=typeof t=="function"?t:typeof r?.WebTorrent=="function"?r.WebTorrent:null;if(!o)throw new Error("createBeaconApp requires a WebTorrent constructor");let n=he(e),c=new o({tracker:at}),a={form:e.querySelector('[data-beacon="magnet-form"]'),magnetInput:e.querySelector('[data-beacon="magnet-input"]'),seedButton:e.querySelector('[data-beacon="seed-button"]'),seedInput:e.querySelector('[data-beacon="seed-input"]'),tableRoot:e.querySelector('[data-beacon="torrent-table"]'),selectedSection:e.querySelector('[data-beacon="selected"]'),selectedName:e.querySelector('[data-beacon="selected-name"]'),pauseButton:e.querySelector('[data-beacon-action="pause"]'),resumeButton:e.querySelector('[data-beacon-action="resume"]'),downloadAllButton:e.querySelector('[data-beacon-action="download-all"]'),removeButton:e.querySelector('[data-beacon-action="remove"]'),copyMagnetButton:e.querySelector('[data-beacon-action="copy-magnet"]'),infoHashValue:e.querySelector('[data-beacon="info-hash"]'),fileList:e.querySelector('[data-beacon="file-list"]'),stats:e.querySelector('[data-beacon="client-stats"]'),overlay:e.querySelector('[data-beacon="processing-overlay"]')},u=a.tableRoot?ye({documentRef:e,root:a.tableRoot,formatters:{bytes:(s,i=!1)=>j(s,i),progress:s=>st(s),ratio:s=>Ee(s),integer:s=>typeof s=="number"&&Number.isFinite(s)?Math.floor(s).toString():"0",bytesPerSecond:s=>j(s,!0)},onSelect(s){d.selectedTorrent=s,E()}}):null,d={selectedTorrent:null,processing:!1},L=[],w=[];function m(s){L.push(s)}function C(s){if(d.processing=!!s,!a.overlay)return;let i=d.processing;a.overlay.hidden=!i,a.overlay.setAttribute("aria-hidden",i?"false":"true"),i?a.overlay.style.removeProperty("display"):a.overlay.style.display="none"}function b(){return Array.isArray(c.torrents)?[...c.torrents]:[]}function N(){if(!a.stats)return;let s=j(c.downloadSpeed,!0)||"0 B/s",i=j(c.uploadSpeed,!0)||"0 B/s",p=Ee(c.ratio);a.stats.textContent=`Client stats: \u2193 ${s} \xB7 \u2191 ${i} \xB7 Ratio: ${p}`}function B(s){a.fileList&&(a.fileList.innerHTML="",!(!s||!Array.isArray(s.files)||!s.files.length)&&s.files.forEach((i,p)=>{let f=e.createElement("tr");f.className="align-top";let l=e.createElement("td");if(l.className="px-3 py-2",i.done&&i.url){let T=e.createElement("a");T.className="text-info hover:text-info-strong",T.href=i.url,T.download=i.name||`file-${p+1}`,T.textContent=i.name||`File ${p+1}`,l.appendChild(T)}else{let T=e.createElement("span");T.textContent=i.name||`File ${p+1}`,l.appendChild(T)}f.appendChild(l);let h=e.createElement("td");h.className="px-3 py-2 text-muted-strong",h.textContent=j(i.length)||"0 B",f.appendChild(h);let V=e.createElement("td");V.className="px-3 py-2";let R=e.createElement("select");R.className="select",R.name=`${i.name||`file-${p+1}`}-priority`,R.setAttribute("aria-label",`Set priority for ${i.name||`file ${p+1}`}`),[{value:"1",label:"High priority"},{value:"0",label:"Low priority"},{value:"-1",label:"Don't download"}].forEach(T=>{let Y=e.createElement("option");Y.value=T.value,Y.textContent=T.label,T.value===i.priority&&(Y.selected=!0),R.appendChild(Y)}),R.value=i.priority??"0",R.addEventListener("change",T=>{lt(i,T.target.value)}),V.appendChild(R),f.appendChild(V),a.fileList.appendChild(f)}))}function E(){if(!a.selectedSection)return;let s=b();d.selectedTorrent=Te(d.selectedTorrent,s);let i=d.selectedTorrent;a.selectedSection.hidden=!i,i&&(a.selectedName&&(a.selectedName.textContent=i.name||"Untitled torrent"),a.pauseButton&&(a.pauseButton.hidden=i.paused===!0,a.pauseButton.disabled=i.paused===!0),a.resumeButton&&(a.resumeButton.hidden=i.paused!==!0,a.resumeButton.disabled=i.paused!==!0),a.downloadAllButton&&(a.downloadAllButton.disabled=!(i.progress>=1)),a.infoHashValue&&(a.infoHashValue.textContent=i.infoHash||""),B(i))}function x(s,{isSeed:i=!1}={}){C(!1),ct(s),i||n.info(`Received ${s.name||"torrent"} metadata`),d.selectedTorrent||(d.selectedTorrent=s),E(),u?.render(b(),d.selectedTorrent)}function P(s){let i=typeof s=="string"?s.trim():"";i&&(C(!0),c.add(i,be,p=>{x(p,{isSeed:!1})}))}function O(s){!Array.isArray(s)||s.length===0||(C(!0),c.seed(s,be,i=>{x(i,{isSeed:!0}),n.success(`Seeding ${i.files.length} file(s)`)}))}function g(s){if(s){if(s.progress<1){n.warn("Torrent is not finished downloading yet.");return}s.files.forEach(i=>{typeof i.getBlob=="function"&&i.getBlob((p,f)=>{if(p||!f){y.error("[beacon] Failed to get blob for file",i?.name,p),n.error("Failed to prepare file for download.");return}let l=URL.createObjectURL(f),h=e.createElement("a");h.className="beacon-hidden-download",h.setAttribute("data-beacon-hidden-download","true"),h.href=l,h.download=i.name||"download",e.body.appendChild(h),h.click(),e.body.removeChild(h),URL.revokeObjectURL(l)})})}}function A(s){if(!s?.magnetURI)return;let i=s.magnetURI,p=r?.navigator?.clipboard;if(p&&typeof p.writeText=="function"){p.writeText(i).then(()=>{n.success("Magnet URI copied to clipboard!")}).catch(f=>{y.error("[beacon] Clipboard error",f),n.error("Failed to copy magnet URI")});return}try{let f=e.createElement("textarea");f.value=i,f.className="beacon-clipboard-offscreen",f.setAttribute("data-beacon-clipboard-state","offscreen"),e.body.appendChild(f),f.select(),e.execCommand?.("copy"),e.body.removeChild(f),n.success("Magnet URI copied (fallback)!")}catch(f){y.error("[beacon] Clipboard fallback error",f),n.error("Failed to copy magnet URI")}}function U(s){s&&s.destroy(i=>{i&&(y.error("[beacon] Failed to destroy torrent",i),n.error("Failed to remove torrent"));let p=b();d.selectedTorrent=Te(null,p),u?.render(p,d.selectedTorrent),E()})}function z(){if(S.info(`[beacon] Starting beacon runtime v${ot}`),n||S.warn("[beacon] Toast service unavailable"),o.WEBRTC_SUPPORT||n?.error("Please use a browser with WebRTC support.",{sticky:!0}),a.form){let l=h=>{h.preventDefault(),P(a.magnetInput?.value||""),a.magnetInput&&(a.magnetInput.value="")};a.form.addEventListener("submit",l),m(()=>a.form.removeEventListener("submit",l))}if(a.seedButton&&a.seedInput){let l=()=>{a.seedInput.click()},h=()=>{let V=Array.from(a.seedInput.files||[]);a.seedInput.value="",O(V)};a.seedButton.addEventListener("click",l),a.seedInput.addEventListener("change",h),m(()=>{a.seedButton.removeEventListener("click",l),a.seedInput.removeEventListener("change",h)})}if(a.pauseButton){let l=()=>{d.selectedTorrent&&typeof d.selectedTorrent.pause=="function"&&(d.selectedTorrent.pause(),E())};a.pauseButton.addEventListener("click",l),m(()=>a.pauseButton.removeEventListener("click",l))}if(a.resumeButton){let l=()=>{d.selectedTorrent&&typeof d.selectedTorrent.resume=="function"&&(d.selectedTorrent.resume(),E())};a.resumeButton.addEventListener("click",l),m(()=>a.resumeButton.removeEventListener("click",l))}if(a.downloadAllButton){let l=()=>g(d.selectedTorrent);a.downloadAllButton.addEventListener("click",l),m(()=>a.downloadAllButton.removeEventListener("click",l))}if(a.removeButton){let l=()=>U(d.selectedTorrent);a.removeButton.addEventListener("click",l),m(()=>a.removeButton.removeEventListener("click",l))}if(a.copyMagnetButton){let l=()=>A(d.selectedTorrent);a.copyMagnetButton.addEventListener("click",l),m(()=>a.copyMagnetButton.removeEventListener("click",l))}let s=l=>{y.error("[beacon] Torrent client error",l),n?.error(l?.message||String(l)),C(!1)};c.on("error",s),m(()=>c.removeListener("error",s));let i=l=>{if(c.torrents&&c.torrents.length>0)return l.preventDefault(),l.returnValue="Transfers are in progress. Are you sure you want to leave or refresh?",l.returnValue};r&&typeof r.addEventListener=="function"&&(r.addEventListener("beforeunload",i),m(()=>r.removeEventListener("beforeunload",i))),u?.render(b(),d.selectedTorrent),E(),N(),C(!1);let p=r.setInterval(()=>{u?.render(b(),d.selectedTorrent),E(),N()},1e3);w.push(p);let f=r?.location?.hash;typeof f=="string"&&f.length>1&&P(f.slice(1))}function Q(){w.forEach(s=>r.clearInterval(s)),w.length=0,L.forEach(s=>{try{s()}catch(i){S.warn("[beacon] Cleanup task failed",i)}}),L.length=0,u?.destroy();try{c.destroy()}catch(s){S.warn("[beacon] Failed to destroy client",s)}}return{mount:z,destroy:Q}}var Se="../../config/instance-config.js";function dt(){return typeof window<"u"&&window||typeof globalThis<"u"&&globalThis||null}function ut(){let e=dt();if(e&&typeof e.WebTorrent=="function")return e.WebTorrent;throw new Error("WebTorrent runtime is not available on the global scope")}var $=null,ft=async()=>{try{let e=await import(Se);if(e&&typeof e.THEME_ACCENT_OVERRIDES<"u")return e.THEME_ACCENT_OVERRIDES}catch(e){S.warn(`[beacon] Failed to load theme accent overrides from ${Se}`,e)}return null},pt=async()=>{try{let e=await ft();e&&ue(e)}catch(e){S.warn("[beacon] Unable to hydrate theme accent overrides",e)}try{fe()}catch(e){S.warn("[beacon] Failed to initialize theme controller",e)}};pt();function we(){if($)return S.info("[beacon] Reusing existing beacon app instance"),$;if(typeof document>"u")throw new Error("Beacon runtime requires a document environment");let e=ut();return S.info("[beacon] Creating beacon app instance"),$=_e({documentRef:document,WebTorrentCtor:e}),$.mount(),$}if(typeof document<"u")if(document.readyState==="loading")document.addEventListener("DOMContentLoaded",()=>{try{we()}catch(e){y.error("[beacon] Failed to mount app",e)}});else try{we()}catch(e){y.error("[beacon] Failed to mount app",e)}export{_e as createBeaconApp,we as mountBeaconApp};
|