1 line
47 KiB
JavaScript
1 line
47 KiB
JavaScript
import{B as e,C as t,E as n,H as r,I as i,J as a,K as o,O as s,P as c,T as l,U as u,W as d,Z as f,a as p,b as m,d as h,g,j as _,m as v,n as y,p as b,r as x,t as S,u as C,v as w,w as T}from"./ui-CBKBDzcl.js";import{n as ee,r as te,t as E}from"./message-square-B6idW0xb.js";import{t as D}from"./globe-BYt6yQt4.js";import{t as O}from"./hash-DAuOZ9k3.js";import{n as k,r as ne,t as A}from"./users-DJn4rrjp.js";import{t as j}from"./radio-tower-DcOqbcos.js";import{n as M,t as N}from"./user-round-3UDfHwDp.js";import{t as P}from"./shield-check-CMgIbfEy.js";import{i as F,n as I,r as re}from"./index-Cfr72k3j.js";var L=[[`path`,{d:`M2.586 17.414A2 2 0 0 0 2 18.828V21a1 1 0 0 0 1 1h3a1 1 0 0 0 1-1v-1a1 1 0 0 1 1-1h1a1 1 0 0 0 1-1v-1a1 1 0 0 1 1-1h.172a2 2 0 0 0 1.414-.586l.814-.814a6.5 6.5 0 1 0-4-4z`,key:`1s6t7t`}],[`circle`,{cx:`16.5`,cy:`7.5`,r:`.5`,fill:`currentColor`,key:`w0ekpg`}]],R=t=>e(m,a(t,{iconNode:L,name:`key-round`})),z=[[`path`,{d:`M12.83 2.18a2 2 0 0 0-1.66 0L2.6 6.08a1 1 0 0 0 0 1.83l8.58 3.91a2 2 0 0 0 1.66 0l8.58-3.9a1 1 0 0 0 0-1.83z`,key:`zw3jo`}],[`path`,{d:`M2 12a1 1 0 0 0 .58.91l8.6 3.91a2 2 0 0 0 1.65 0l8.58-3.9A1 1 0 0 0 22 12`,key:`1wduqc`}],[`path`,{d:`M2 17a1 1 0 0 0 .58.91l8.6 3.91a2 2 0 0 0 1.65 0l8.58-3.9A1 1 0 0 0 22 17`,key:`kqbvx6`}]],B=t=>e(m,a(t,{iconNode:z,name:`layers`})),V=[[`path`,{d:`M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8`,key:`v9h5vc`}],[`path`,{d:`M21 3v5h-5`,key:`1q7to0`}],[`path`,{d:`M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16`,key:`3uifl3`}],[`path`,{d:`M8 16H3v5`,key:`1cv678`}]],ie=t=>e(m,a(t,{iconNode:V,name:`refresh-cw`})),H=[[`path`,{d:`M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8`,key:`1357e3`}],[`path`,{d:`M3 3v5h5`,key:`1xhq8a`}]],ae=t=>e(m,a(t,{iconNode:H,name:`rotate-ccw`})),U=[[`path`,{d:`M15.2 3a2 2 0 0 1 1.4.6l3.8 3.8a2 2 0 0 1 .6 1.4V19a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2z`,key:`1c8476`}],[`path`,{d:`M17 21v-7a1 1 0 0 0-1-1H8a1 1 0 0 0-1 1v7`,key:`1ydtos`}],[`path`,{d:`M7 3v4a1 1 0 0 0 1 1h7`,key:`t51u73`}]],W=t=>e(m,a(t,{iconNode:U,name:`save`})),G=[[`path`,{d:`M9.671 4.136a2.34 2.34 0 0 1 4.659 0 2.34 2.34 0 0 0 3.319 1.915 2.34 2.34 0 0 1 2.33 4.033 2.34 2.34 0 0 0 0 3.831 2.34 2.34 0 0 1-2.33 4.033 2.34 2.34 0 0 0-3.319 1.915 2.34 2.34 0 0 1-4.659 0 2.34 2.34 0 0 0-3.32-1.915 2.34 2.34 0 0 1-2.33-4.033 2.34 2.34 0 0 0 0-3.831A2.34 2.34 0 0 1 6.35 6.051a2.34 2.34 0 0 0 3.319-1.915`,key:`1i5ecw`}],[`circle`,{cx:`12`,cy:`12`,r:`3`,key:`1v7zrd`}]],K=t=>e(m,a(t,{iconNode:G,name:`settings`})),oe=[[`path`,{d:`M10 5H3`,key:`1qgfaw`}],[`path`,{d:`M12 19H3`,key:`yhmn1j`}],[`path`,{d:`M14 3v4`,key:`1sua03`}],[`path`,{d:`M16 17v4`,key:`1q0r14`}],[`path`,{d:`M21 12h-9`,key:`1o4lsq`}],[`path`,{d:`M21 19h-5`,key:`1rlt1p`}],[`path`,{d:`M21 5h-7`,key:`1oszz2`}],[`path`,{d:`M8 10v4`,key:`tgpxqk`}],[`path`,{d:`M8 12H3`,key:`a7s4jb`}]],q=t=>e(m,a(t,{iconNode:oe,name:`sliders-horizontal`})),se=[[`path`,{d:`M10 11v6`,key:`nco0om`}],[`path`,{d:`M14 11v6`,key:`outv1u`}],[`path`,{d:`M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6`,key:`miytrc`}],[`path`,{d:`M3 6h18`,key:`d0wm0j`}],[`path`,{d:`M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2`,key:`e791ji`}]],J=t=>e(m,a(t,{iconNode:se,name:`trash-2`})),Y=[[`path`,{d:`m16 13 5.223 3.482a.5.5 0 0 0 .777-.416V7.87a.5.5 0 0 0-.752-.432L16 10.5`,key:`ftymec`}],[`rect`,{x:`2`,y:`6`,width:`14`,height:`12`,rx:`2`,key:`158x01`}]],X=t=>e(m,a(t,{iconNode:Y,name:`video`})),ce=_(`<div class="flex flex-wrap gap-1.5">`),le=_(`<button type=button>`),Z=[{path:`overview`,label:`概览`,icon:B,perms:[`room:list`]},{path:`rooms`,label:`房间`,icon:j,perms:[`room:manage`]},{path:`permissions`,label:`权限`,icon:R,perms:[`room:manage`]},{path:`users`,label:`用户`,icon:A,perms:[`user:list`]},{path:`system`,label:`系统`,icon:K,perms:[`system:manage`,`config:read`]}];function ue(n){F();let r=u(()=>Z.filter(e=>e.perms.some(e=>b.can(e))||b.isAdminOrAbove()));return(()=>{var i=ce();return l(i,e(c,{get each(){return r()},children:r=>{let i=r.icon,a=()=>n.value===r.path;return(()=>{var o=le();return o.$$click=()=>n.onChange(r.path),l(o,e(i,{class:`size-3.5`}),null),l(o,()=>r.label,null),d(e=>{var n=`inline-flex h-9 items-center gap-1.5 border px-3 text-xs font-medium transition-colors ${a()?`border-line bg-acid-lime text-black`:`border-line bg-card text-muted-foreground hover:bg-accent`}`,r=a()?`page`:void 0;return n!==e.e&&t(o,e.e=n),r!==e.t&&s(o,`aria-current`,e.t=r),e},{e:void 0,t:void 0}),o})()}})),i})()}T([`click`]);var de=_(`<div>`),fe=_(`<p class="mt-3 max-w-2xl text-sm text-muted-foreground">`),pe=_(`<div class="flex shrink-0 items-center gap-2">`),me=_(`<div class="flex flex-wrap items-start justify-between gap-4"><div class="min-w-0 flex-1"><p class="mono-label text-muted-foreground">manage / console</p><h1 class="display mt-2 text-4xl sm:text-5xl">`);function he(e){return(()=>{var n=de();return l(n,()=>e.children),d(()=>t(n,`mx-auto max-w-[1400px] space-y-6 px-4 py-8 sm:px-6 sm:py-10 ${e.class??``}`)),n})()}function ge(t){return(()=>{var n=me(),r=n.firstChild,a=r.firstChild.nextSibling;return l(a,()=>t.title),l(r,e(i,{get when(){return t.description},get children(){var e=fe();return l(e,()=>t.description),e}}),null),l(n,e(i,{get when(){return t.actions},get children(){var e=pe();return l(e,()=>t.actions),e}}),null),n})()}var _e=_(`<p class="mt-1 text-xs text-muted-foreground">`),ve=_(`<div class="relative border border-line bg-card/60 p-4"><div class="flex items-start justify-between gap-3"><div><p class="micro-label text-muted-foreground"></p><p class="display mt-2 text-3xl"></p></div><span class="flex size-8 items-center justify-center border border-line bg-background text-muted-foreground">`),ye=_(`<p class="py-6 text-center text-sm text-muted-foreground">暂无房间数据`),be=_(`<div class=space-y-6><div class="grid gap-4 sm:grid-cols-2 lg:grid-cols-4"></div><div class="grid gap-4 lg:grid-cols-3"><div class="border border-line bg-card/50 p-4 lg:col-span-2"><div class="flex items-center justify-between gap-3"><h3 class=font-semibold>房间分发状态</h3><span class="mono-label text-muted-foreground"> rooms</span></div><div class="mt-4 space-y-2"></div></div><div class="border border-line bg-card/50 p-4"><h3 class=font-semibold>后端能力</h3><div class="mt-4 space-y-2">`),xe=_(`<div class="flex items-center justify-between gap-3 border border-line/60 bg-background/50 px-3 py-2.5"><div class="flex min-w-0 items-center gap-2.5"><span class="truncate font-mono text-sm"></span></div><div class="flex items-center gap-3 text-xs text-muted-foreground"><span class="hidden sm:inline"> 成员</span><span> targets`),Se=_(`<div class="flex items-center justify-between border border-line/60 px-3 py-2.5"><span class="font-mono text-xs uppercase">`);function Q(t){let n=t.icon;return(()=>{var r=ve(),a=r.firstChild.firstChild,o=a.firstChild,s=o.nextSibling,c=a.nextSibling;return l(o,()=>t.label),l(s,()=>t.value),l(a,e(i,{get when(){return t.hint},get children(){var e=_e();return l(e,()=>t.hint),e}}),null),l(c,e(n,{class:`size-4`})),r})()}function Ce(t){let n=()=>t.overview,r=()=>t.rooms;return(()=>{var t=be(),a=t.firstChild,o=a.nextSibling.firstChild,s=o.firstChild,u=s.firstChild.nextSibling,d=u.firstChild,f=s.nextSibling,m=o.nextSibling.firstChild.nextSibling;return l(a,e(Q,{label:`房间总数`,get value(){return n()?.rooms_total??`-`},get hint(){return`${n()?.rooms_live??0} 个正在直播`},icon:B}),null),l(a,e(Q,{label:`在线房间`,get value(){return n()?.rooms_live??`-`},hint:`有推流目标的房间`,icon:X}),null),l(a,e(Q,{label:`房间成员`,get value(){return n()?.members_total??`-`},hint:`所有房间成员汇总`,icon:A}),null),l(a,e(Q,{label:`系统用户`,get value(){return n()?.users_total??`-`},hint:`已注册账号`,icon:P}),null),l(u,()=>r().length,d),l(f,e(c,{get each(){return r().slice(0,6)},children:t=>(()=>{var n=xe(),r=n.firstChild,i=r.firstChild,a=r.nextSibling.firstChild,o=a.firstChild,s=a.nextSibling,c=s.firstChild;return l(r,e(p,{get active(){return t.live}}),i),l(i,()=>t.room.name),l(r,e(y,{get variant(){return t.live?`success`:`muted`},class:`hidden sm:inline-flex`,get children(){return t.live?`LIVE`:`IDLE`}}),null),l(a,()=>t.member_count,o),l(s,()=>t.targets?.length??0,c),n})()}),null),l(f,e(i,{get when(){return r().length===0},get children(){return ye()}}),null),l(m,e(c,{get each(){return n()?.backends||[]},children:t=>(()=>{var n=Se(),r=n.firstChild;return l(r,()=>t.name||t.kind),l(n,e(y,{get variant(){return t.configured?`success`:`muted`},get children(){return t.configured?`已配置`:`未配置`}}),null),n})()})),t})()}var we=[`send_chat`,`view_chat_history`,`view_members`,`subscribe`,`watch_room`,`publish`,`stop_stream`,`broadcast`,`manage_members`,`add_members`,`remove_members`,`manage_permissions`,`manage_room`,`delete_room`,`delete_chat_messages`,`control_stream`],Te={send_chat:`发弹幕`,view_chat_history:`看记录`,view_members:`看成员`,subscribe:`拉流`,watch_room:`监听`,publish:`推流`,stop_stream:`停播`,broadcast:`广播`,manage_members:`管成员`,add_members:`邀成员`,remove_members:`踢人`,manage_permissions:`管权限`,manage_room:`管房间`,delete_room:`删房间`,delete_chat_messages:`删消息`,control_stream:`控流`},$={creator:{label:`房主`,color:`border-amber-400/40 bg-amber-400/10 text-amber-600`},admin:{label:`管理员`,color:`border-acid-magenta/30 bg-acid-magenta/10 text-acid-magenta`},member:{label:`成员`,color:`border-acid-cyan/30 bg-acid-cyan/10 text-acid-cyan`},guest:{label:`访客`,color:`border-line bg-muted text-muted-foreground`},root:{label:`超管`,color:`border-amber-500/40 bg-amber-500/10 text-amber-600`},viewer:{label:`观看者`,color:`border-acid-cyan/30 bg-acid-cyan/10 text-acid-cyan`},publisher:{label:`发布者`,color:`border-warning/30 bg-warning/10 text-warning`}},Ee=_(`<div class="border border-line bg-card/60 p-4"><div class="flex flex-wrap items-start justify-between gap-3"><div class=min-w-0><p class="mono-label text-muted-foreground">room / </p><h3 class="display mt-1 truncate text-2xl"></h3><p class="text-xs text-muted-foreground">创建者 <!> · 状态 </p></div></div><div class="mt-4 grid gap-3 sm:grid-cols-2"><div class=space-y-1.5><label class=label>描述</label><input class=field></div><div class=space-y-1.5><label class=label>人数上限</label><input class="field field-mono"></div></div><div class="mt-3 flex flex-wrap gap-2">`),De=_(`<div class="border border-warning/30 bg-warning/10"><div class="flex items-center justify-between border-b border-warning/20 px-4 py-3"><h4 class="flex items-center gap-2 font-semibold text-warning"> 待审批 </h4></div><div class="divide-y divide-warning/20">`),Oe=_(`<p class="px-4 py-6 text-sm text-muted-foreground">暂无活跃成员`),ke=_(`<div class="border border-line bg-card/50"><div class="flex items-center justify-between border-b border-line/80 px-4 py-3"><h4 class=font-semibold>成员 <!> <span class="text-xs font-normal text-muted-foreground">· 含待审批 </span></h4></div><div class="divide-y divide-line/60">`),Ae=_(`<div class="mt-4 grid gap-4 sm:grid-cols-2"><label class="flex items-center justify-between gap-3 border border-line bg-background px-3 py-2.5"><span class="flex items-center gap-2 text-sm"> 聊天</span><input type=checkbox></label><label class="flex items-center justify-between gap-3 border border-line bg-background px-3 py-2.5"><span class="flex items-center gap-2 text-sm"> 访客加入</span><input type=checkbox></label><label class="flex items-center justify-between gap-3 border border-line bg-background px-3 py-2.5"><span class="flex items-center gap-2 text-sm"> 需审批</span><input type=checkbox></label><label class="flex items-center justify-between gap-3 border border-line bg-background px-3 py-2.5"><span class="flex items-center gap-2 text-sm"> 公开</span><input type=checkbox>`),je=_(`<div class="border border-line bg-card/50 p-4"><h4 class="flex items-center gap-2 font-semibold">房间设置`),Me=_(`<div class="border border-line bg-card/50 p-4"><div class="flex items-center justify-between gap-2"><h4 class="flex items-center gap-2 font-semibold">分发设置</h4></div><p class="mt-1.5 text-xs text-muted-foreground">全局:<!> · 生效:</p><div class="mt-3 grid gap-2 sm:grid-cols-3"></div><p class="mt-2 text-[11px] text-muted-foreground">未设置时自动使用全局分发;勾选即为该房间单独覆盖(可为空表示关闭全部)。`),Ne=_(`<div class="grid gap-4 lg:grid-cols-3"><div class="lg:col-span-1 space-y-4"><div class="border border-line bg-card/60 p-4"><h3 class=font-semibold>创建房间</h3><div class="mt-4 space-y-3"><div class=space-y-1.5><label class=label>房间名 *</label><div class="flex items-center gap-2 border border-line bg-background px-3 py-2 focus-within:border-ring"><input class="w-full bg-transparent font-mono text-sm outline-none"placeholder="如 live-101"></div></div><div class=space-y-1.5><label class=label>描述</label><input class=field placeholder=一句话介绍></div><div class="grid grid-cols-2 gap-3"><div class=space-y-1.5><label class=label>可见性</label></div><div class=space-y-1.5><label class=label>人数上限</label><input class="field field-mono"></div></div><div class=space-y-1.5><label class=label>房间密码(可选)</label><div class="flex items-center gap-2 border border-line bg-background px-3 py-2 focus-within:border-ring"><input class="w-full bg-transparent font-mono text-sm outline-none"placeholder=留空为无密码><button type=button class=text-muted-foreground></button></div></div></div></div><div class="border border-line bg-card/50"><div class="flex items-center justify-between border-b border-line/80 px-4 py-3"><h3 class=font-semibold>房间列表</h3><span class="mono-label text-muted-foreground"></span></div><div class="max-h-[480px] overflow-auto"></div></div></div><div class="space-y-4 lg:col-span-2">`),Pe=_(`<button type=button><div class=min-w-0><p class="truncate font-mono text-sm font-medium"></p><p class="truncate text-xs text-muted-foreground"></p></div><div class="flex shrink-0 flex-col items-end gap-1"><span class="micro-label text-muted-foreground"> 成员`),Fe=_(`<div class="border border-dashed border-line p-8 text-center text-sm text-muted-foreground">选择一个房间以管理`),Ie=_(`<div class="flex flex-wrap items-center justify-between gap-3 px-4 py-3"><span class="font-mono text-sm"> <span class="text-xs text-muted-foreground">· </span></span><div class="flex gap-2">`),Le=_(`<div class="flex flex-wrap items-center gap-3 px-4 py-3"><span></span><div class="min-w-0 flex-1"><p class="truncate font-mono text-sm font-medium flex items-center gap-1.5"> <!> </p><p class="micro-label truncate text-muted-foreground"></p></div><div class="flex items-center gap-1">`),Re=_(`<p class="mt-3 text-sm text-muted-foreground">加载中…`),ze=_(`<label class="flex items-center justify-between gap-2 border border-line bg-background px-3 py-2.5"><span class="text-sm font-mono"></span><input type=checkbox>`);function Be(r){let a=()=>r.members.filter(e=>e.status===`pending`),o=()=>r.members.filter(e=>e.status!==`pending`);return(()=>{var u=Ne(),f=u.firstChild,m=f.firstChild,h=m.firstChild.nextSibling,g=h.firstChild,_=g.firstChild.nextSibling,v=_.firstChild,b=g.nextSibling,S=b.firstChild.nextSibling,w=b.nextSibling,T=w.firstChild;T.firstChild;var A=T.nextSibling.firstChild.nextSibling,j=w.nextSibling.firstChild.nextSibling,P=j.firstChild,F=P.nextSibling,L=m.nextSibling.firstChild,R=L.firstChild.nextSibling,z=L.nextSibling,B=f.nextSibling;return l(_,e(O,{class:`size-4 shrink-0 text-muted-foreground`}),v),v.$$input=e=>r.setNewRoom({name:e.currentTarget.value}),S.$$input=e=>r.setNewRoom({desc:e.currentTarget.value}),l(T,e(C,{get value(){return r.newRoom.isPublic?`public`:`private`},onChange:e=>r.setNewRoom({isPublic:e===`public`}),options:[{value:`public`,label:`公开`},{value:`private`,label:`私密`}]}),null),A.$$input=e=>r.setNewRoom({max:e.currentTarget.value}),l(j,e(ne,{class:`size-4 shrink-0 text-muted-foreground`}),P),P.$$input=e=>r.setNewRoom({pwd:e.currentTarget.value}),F.$$click=()=>r.setNewRoom({showPwd:!r.newRoom.showPwd}),l(F,e(i,{get when(){return r.newRoom.showPwd},get fallback(){return e(ee,{class:`size-4`})},get children(){return e(te,{class:`size-4`})}})),l(h,e(x,{class:`w-full`,get onClick(){return r.onCreate},get disabled(){return r.loading||!r.newRoom.name.trim()},get children(){return[e(k,{class:`size-4`}),`创建房间`]}}),null),l(R,()=>r.rooms.length),l(z,e(c,{get each(){return r.rooms},children:n=>(()=>{var i=Pe(),a=i.firstChild,o=a.firstChild,s=o.nextSibling,c=a.nextSibling,u=c.firstChild,f=u.firstChild;return i.$$click=()=>r.onSelectRoom(n.room.name),l(o,()=>n.room.name),l(s,()=>n.room.description||n.room.creator||`—`),l(c,e(p,{get active(){return n.live}}),u),l(u,()=>n.member_count,f),d(()=>t(i,`flex w-full items-center justify-between gap-3 border-b border-line/60 px-4 py-3 text-left hover:bg-accent/40 ${r.selectedRoom===n.room.name?`bg-acid-lime/10`:``}`)),i})()})),l(B,e(i,{get when(){return r.selectedRoom},get fallback(){return Fe()},get children(){return[(()=>{var t=Ee(),n=t.firstChild,i=n.firstChild.firstChild;i.firstChild;var a=i.nextSibling,o=a.nextSibling,s=o.firstChild.nextSibling;s.nextSibling;var c=n.nextSibling,u=c.firstChild,f=u.firstChild.nextSibling,p=u.nextSibling.firstChild.nextSibling,m=c.nextSibling;return l(i,()=>r.selectedRoom,null),l(a,()=>r.editingRoom?.display_name||r.selectedRoom),l(o,()=>r.editingRoom?.creator||`-`,s),l(o,()=>r.editingRoom?.status||`active`,null),l(n,e(y,{get variant(){return r.editingRoom?.is_public?`success`:`warning`},get children(){return r.editingRoom?.is_public?`公开`:`私密`}}),null),f.$$input=e=>r.setEdit({desc:e.currentTarget.value}),p.$$input=e=>r.setEdit({max:e.currentTarget.value}),l(m,e(x,{class:`gap-1.5`,get onClick(){return r.onSave},get children(){return[e(W,{class:`size-4`}),`保存`]}}),null),l(m,e(x,{variant:`danger`,class:`gap-1.5`,onClick:()=>r.onDelete(r.selectedRoom),get children(){return[e(J,{class:`size-4`}),`删除`]}}),null),d(()=>f.value=r.edit.desc),d(()=>p.value=r.edit.max),t})(),e(i,{get when(){return a().length>0},get children(){var t=De(),n=t.firstChild,i=n.firstChild,o=i.firstChild,s=n.nextSibling;return l(i,e(M,{class:`size-4`}),o),l(i,()=>a().length,null),l(s,e(c,{get each(){return a()},children:t=>(()=>{var n=Ie(),i=n.firstChild,a=i.firstChild,o=a.nextSibling;o.firstChild;var s=i.nextSibling;return l(i,()=>t.username,a),l(o,()=>t.role,null),l(s,e(x,{class:`h-7 px-3`,onClick:()=>r.onApprove(r.selectedRoom,t.username),children:`批准`}),null),l(s,e(x,{variant:`ghost`,class:`h-7 px-3`,onClick:()=>r.onReject(r.selectedRoom,t.username),children:`拒绝`}),null),n})()})),t}}),(()=>{var s=ke(),u=s.firstChild,f=u.firstChild,p=f.firstChild.nextSibling,m=p.nextSibling.nextSibling;m.firstChild;var h=u.nextSibling;return l(f,()=>r.members.length,p),l(m,()=>a().length,null),l(h,e(c,{get each(){return o()},children:a=>(()=>{var o=Le(),s=o.firstChild,c=s.nextSibling,u=c.firstChild,f=u.firstChild,p=f.nextSibling;p.nextSibling;var m=u.nextSibling,h=c.nextSibling;return l(s,()=>(a.username[0]||`?`).toUpperCase()),l(u,()=>a.username,f),l(u,e(i,{get when(){return a.status===`banned`},get children(){return e(y,{variant:`outline`,class:`border-destructive/30 text-destructive text-[10px]`,children:`banned`})}}),p),l(u,e(i,{get when(){return n(()=>a.status===`active`)()&&a.role===`creator`},get children(){return e(I,{class:`size-3 text-amber-500`})}}),null),l(m,()=>a.effective_permissions?.join(`, `)||``),l(o,e(C,{class:`w-28`,get value(){return a.role},onChange:e=>r.onChangeRole(r.selectedRoom,a.username,e),options:[{value:`creator`,label:`房主`},{value:`admin`,label:`管理员`},{value:`member`,label:`成员`},{value:`guest`,label:`访客`}]}),h),l(h,e(i,{get when(){return a.role!==`creator`},get children(){return[e(x,{variant:`ghost`,class:`h-8 px-2 text-muted-foreground`,title:`转让房主`,onClick:()=>{confirm(`转让房主给 ${a.username}?`)&&r.onTransfer(r.selectedRoom,a.username)},get children(){return e(I,{class:`size-4`})}}),e(x,{variant:`ghost`,class:`h-8 px-2 text-destructive`,title:`踢出`,onClick:()=>r.onKick(r.selectedRoom,a.username),get children(){return e(re,{class:`size-4`})}}),e(x,{variant:`ghost`,class:`h-8 px-2 text-destructive`,title:`封禁(房内)`,onClick:()=>{confirm(`房内封禁 ${a.username}?`)&&r.onBan(r.selectedRoom,a.username)},get children(){return e(M,{class:`size-4`})}})]}})),d(()=>t(s,`flex size-8 items-center justify-center border font-mono text-xs font-bold ${$[a.role]?.color||``}`)),o})()}),null),l(h,e(i,{get when(){return o().length===0},get children(){return Oe()}}),null),s})(),(()=>{var t=je(),n=t.firstChild,a=n.firstChild;return l(n,e(q,{class:`size-4`}),a),l(t,e(i,{get when(){return r.roomSettings},get fallback(){return Re()},get children(){return[(()=>{var t=Ae(),n=t.firstChild,i=n.firstChild,a=i.firstChild,o=i.nextSibling,s=n.nextSibling,c=s.firstChild,u=c.firstChild,f=c.nextSibling,p=s.nextSibling,m=p.firstChild,h=m.firstChild,g=m.nextSibling,_=p.nextSibling.firstChild,v=_.firstChild,y=_.nextSibling;return l(i,e(E,{class:`size-4 text-muted-foreground`}),a),o.$$input=e=>r.setRoomSettings({...r.roomSettings,chat_enabled:e.currentTarget.checked}),l(c,e(N,{class:`size-4 text-muted-foreground`}),u),f.$$input=e=>r.setRoomSettings({...r.roomSettings,allow_guest_join:e.currentTarget.checked}),l(m,e(M,{class:`size-4 text-muted-foreground`}),h),g.$$input=e=>r.setRoomSettings({...r.roomSettings,require_approval:e.currentTarget.checked}),l(_,e(D,{class:`size-4 text-muted-foreground`}),v),y.$$input=e=>r.setRoomSettings({...r.roomSettings,is_public:e.currentTarget.checked}),d(()=>o.checked=!!r.roomSettings?.chat_enabled),d(()=>f.checked=!!r.roomSettings?.allow_guest_join),d(()=>g.checked=!!r.roomSettings?.require_approval),d(()=>y.checked=!!r.roomSettings?.is_public),t})(),e(x,{class:`mt-4 gap-1.5`,get onClick(){return r.onSaveSettings},get children(){return[e(W,{class:`size-4`}),`保存设置`]}})]}}),null),t})(),(()=>{var t=Me(),n=t.firstChild,a=n.firstChild,o=a.firstChild,s=n.nextSibling,u=s.firstChild.nextSibling;u.nextSibling;var f=s.nextSibling;return l(a,e(D,{class:`size-4`}),o),l(a,e(i,{get when(){return r.distribution?.has_custom},get fallback(){return e(y,{variant:`outline`,class:`text-[10px]`,children:`跟随全局`})},get children(){return e(y,{variant:`success`,class:`text-[10px]`,children:`房间自定义`})}}),null),l(n,e(i,{get when(){return r.distribution?.has_custom},get children(){return e(x,{variant:`ghost`,class:`h-7 px-2 text-xs`,onClick:()=>r.onClearDistribution?.(),children:`恢复全局`})}}),null),l(s,()=>r.distribution?.global?.join(`, `)||`—`,u),l(s,()=>r.distribution?.effective?.join(`, `)||`(无)`,null),l(s,e(i,{get when(){return!r.distribution},children:` · 加载中…`}),null),l(f,e(c,{each:[`srs-hls`,`cf`,`cdn`],children:e=>(()=>{var t=ze(),n=t.firstChild,i=n.nextSibling;return l(n,e),i.$$input=t=>r.onToggleDistribution?.(e,t.currentTarget.checked),d(()=>i.checked=!!r.distribution?.effective?.includes(e)),t})()})),t})()]}})),d(()=>s(P,`type`,r.newRoom.showPwd?`text`:`password`)),d(()=>v.value=r.newRoom.name),d(()=>S.value=r.newRoom.desc),d(()=>A.value=r.newRoom.max),d(()=>P.value=r.newRoom.pwd),u})()}T([`input`,`click`]);var Ve=_(`<div class=overflow-auto><table class="w-full min-w-[900px] border-collapse"><thead><tr class="border-b border-line bg-muted/20"><th class="px-3 py-2 text-left text-xs font-mono text-muted-foreground">成员 / 角色</th></tr></thead><tbody>`),He=_(`<div class=space-y-4><div class="border border-line bg-card/60 p-4"><h3 class=font-semibold>角色默认权限</h3><p class="mt-1 text-xs text-muted-foreground">Creator 全量 · Guest 只读,个人覆盖 added/removed 生效。</p><div class="mt-4 overflow-auto"><table class="w-full min-w-[520px] border-collapse text-xs"><thead><tr class="border-b border-line"><th class="px-2 py-2 text-left font-mono text-muted-foreground">permission</th></tr></thead><tbody></tbody></table></div></div><div class="border border-line bg-card/50"><div class="flex flex-wrap items-center justify-between gap-3 border-b border-line/80 px-4 py-3"><h3 class=font-semibold>成员生效权限 · `),Ue=_(`<th class="px-2 py-2 text-center font-mono text-muted-foreground">`),We=_(`<tr class="border-b border-line/60"><td class="px-2 py-2 font-mono">`),Ge=_(`<td class="px-2 py-2 text-center">`),Ke=_(`<span class="inline-flex size-2 bg-acid-lime">`),qe=_(`<span class="inline-flex size-2 border border-line">`),Je=_(`<p class="px-4 py-8 text-center text-sm text-muted-foreground">请选择房间`),Ye=_(`<th class="px-1 py-2 text-center text-[10px] font-mono text-muted-foreground">`),Xe=_(`<tr class="border-b border-line/40"><td class="px-3 py-2"><div class="flex items-center gap-2"><span class="font-mono text-xs font-medium">`),Ze=_(`<td class="px-1 py-1 text-center"><button type=button>`);function Qe(n){return(()=>{var r=He(),a=r.firstChild,o=a.firstChild.nextSibling.nextSibling.firstChild.firstChild,s=o.firstChild;s.firstChild;var u=o.nextSibling,d=a.nextSibling,f=d.firstChild,p=f.firstChild;return p.firstChild,l(s,e(c,{each:[`creator`,`admin`,`member`,`guest`],children:e=>(()=>{var t=Ue();return l(t,e),t})()}),null),l(u,e(c,{each:we,children:t=>(()=>{var r=We(),i=r.firstChild;return l(i,()=>Te[t]||t),l(r,e(c,{each:[`creator`,`admin`,`member`,`guest`],children:e=>{let r=n.permDefs?.roles?.[e]?.perms?.includes(t);return(()=>{var e=Ge();return l(e,r?Ke():qe()),e})()}}),null),r})()})),l(p,()=>n.selectedRoom||`未选择`,null),l(f,e(C,{get value(){return n.selectedRoom},get onChange(){return n.onSelectRoom},get options(){return n.rooms.map(e=>({value:e.room.name,label:e.room.name}))},class:`w-48`}),null),l(d,e(i,{get when(){return n.selectedRoom},get fallback(){return Je()},get children(){var r=Ve(),i=r.firstChild.firstChild,a=i.firstChild;a.firstChild;var o=i.nextSibling;return l(a,e(c,{each:we,children:e=>(()=>{var t=Ye();return l(t,()=>Te[e]||e),t})()}),null),l(o,e(c,{get each(){return n.members},children:r=>(()=>{var i=Xe(),a=i.firstChild.firstChild,o=a.firstChild;return l(o,()=>r.username),l(a,e(y,{get class(){return`text-[10px] ${$[r.role]?.color||``}`},get children(){return r.role}}),null),l(i,e(c,{each:we,children:e=>{let i=r.effective_permissions?.includes(e),a=r.role===`creator`;return(()=>{var o=Ze(),s=o.firstChild;return s.$$click=()=>n.onTogglePerm(n.selectedRoom,r.username,e,!!i),s.disabled=a,t(s,`inline-flex size-6 items-center justify-center border text-[10px] ${i?`border-acid-lime bg-acid-lime text-black`:`border-line bg-background text-muted-foreground hover:border-ring`} ${a?`opacity-50`:``}`),l(s,i?`✓`:``),o})()}}),null),i})()})),r}}),null),r})()}T([`click`]);var $e=_(`<span class="flex items-center gap-2">`),et=_(`<button class="text-xs underline">关闭`),tt=_(`<div class=space-y-4><div class="flex flex-wrap items-center justify-between gap-3 border border-line bg-card/60 px-4 py-3"><div class=min-w-0><h3 class="flex items-center gap-2 text-sm font-semibold">运行时配置</h3><p class="mt-1 text-xs text-muted-foreground">修改后立即热生效并持久化到 <span class=font-mono>data/runtime_config.json</span>,无需重启。优先级:运行时覆盖 > 环境变量 > 默认值。</p></div><div class="flex shrink-0 flex-wrap items-center gap-2"></div></div><div class="grid gap-4 xl:grid-cols-[220px_1fr]"><div class="flex h-fit flex-col gap-1 border border-line bg-card/40 p-2 xl:sticky xl:top-[88px]"><div class="mt-2 border-t border-line/60 pt-3"><div class="space-y-2 px-2 text-[11px] leading-relaxed text-muted-foreground"><p class="font-medium text-foreground">来源标记</p><p><span class="inline-flex items-center gap-1"><span class="size-2 bg-acid-lime"></span> runtime</span> 运行时覆盖</p><p><span class="inline-flex items-center gap-1"><span class="size-2 bg-acid-cyan"></span> env</span> 环境变量</p><p><span class="inline-flex items-center gap-1"><span class="size-2 bg-line"></span> default</span> 默认值</p></div></div></div><div class="min-w-0 space-y-4"><div class="grid gap-4 lg:grid-cols-2"><div class="border border-line bg-card/40 p-4"><h4 class="flex items-center gap-2 text-sm font-semibold">SFU 状态(只读)</h4><div class="mt-3 space-y-2 text-sm"><div class="flex items-center justify-between border border-line bg-background px-3 py-2.5"><span class=text-muted-foreground>HTTP</span><span class="font-mono text-xs">8088</span></div><div class="flex items-center justify-between border border-line bg-background px-3 py-2.5"><span class=text-muted-foreground>gRPC</span><span class="font-mono text-xs">9090</span></div></div></div><div class="border border-line bg-card/40 p-4"><h4 class="flex items-center gap-2 text-sm font-semibold">说明</h4><div class="mt-3 space-y-2 text-xs leading-relaxed text-muted-foreground"><p>保存即热生效:Cloudflare/SRS/CDN/分发开关等无需重启。</p><p>密钥字段默认以 <span class=font-mono>••••••••</span> 脱敏回显;不修改则保持原值。</p><p>重置会删除运行时覆盖,回落至环境变量或默认值。`),nt=_(`<button type=button><span class="min-w-0 flex-1 truncate">`),rt=_(`<div class="border border-line bg-card/40 px-4 py-12 text-center text-sm text-muted-foreground">加载中...`),it=_(`<div class="border border-line bg-card/60"><div class="flex items-center justify-between gap-3 border-b border-line/80 px-4 py-3"><span class="text-sm font-semibold"></span><span class="text-xs text-muted-foreground"> 项</span></div><div class="divide-y divide-line/60">`),at=_(`<p class="mt-1 text-xs text-muted-foreground">`),ot=_(`<p class="mt-0.5 font-mono text-[11px] text-muted-foreground/70">示例:`),st=_(`<div class="flex flex-col gap-2 px-4 py-3 sm:flex-row sm:items-start sm:gap-4"><div class="min-w-0 flex-1"><div class="flex flex-wrap items-center gap-2"><span class="font-mono text-xs font-medium"></span><span><span></span></span></div></div><div class="w-full shrink-0 sm:w-[min(420px,55%)]">`),ct=_(`<div class="flex items-center justify-between border border-line bg-background px-3 py-2.5"><span class="flex items-center gap-2">`),lt=[{title:`分发与 SFU`,icon:j,keys:[{key:`SFU_PROVIDER`,label:`SFU_PROVIDER`,placeholder:`cloudflare,srs`,hint:`后端顺序,逗号分隔`},{key:`DISTRIBUTORS`,label:`DISTRIBUTORS`,placeholder:`srs-hls,cf,cdn`,hint:`启用的分发方式`},{key:`CDN_RTMP_URL`,label:`CDN_RTMP_URL`,placeholder:`rtmp://cdn.example.com/live`,hint:`启用 cdn 时必填`},{key:`CDN_NAME`,label:`CDN 名称`,placeholder:`cdn`}]},{title:`SRS 主干`,icon:j,keys:[{key:`SRS_API_BASE`,label:`SRS_API_BASE`,placeholder:`http://localhost:1985`},{key:`SRS_HTTP_BASE`,label:`SRS_HTTP_BASE`,placeholder:`http://localhost:8080`},{key:`SRS_APP`,label:`SRS_APP`,placeholder:`live`},{key:`SRS_SECRET`,label:`SRS_SECRET`,placeholder:`留空则不鉴权`,hint:`推流鉴权密钥`},{key:`SRS_CANDIDATE`,label:`SRS_CANDIDATE`,placeholder:`127.0.0.1`,hint:`ICE candidate IP`},{key:`SFU_TOKEN_REQUIRED`,label:`SFU_TOKEN_REQUIRED`,type:`bool`}]},{title:`Cloudflare Realtime`,icon:D,keys:[{key:`CF_APP_ID`,label:`CF_APP_ID`},{key:`CF_APP_SECRET`,label:`CF_APP_SECRET`,hint:`保存后自动脱敏显示`},{key:`CF_BASE_URL`,label:`CF_BASE_URL`,placeholder:`https://rtc.live.cloudflare.com/v1`},{key:`CF_STUN_URL`,label:`CF_STUN_URL`,placeholder:`stun:stun.cloudflare.com:3478`}]},{title:`鉴权与注册`,icon:P,keys:[{key:`ALLOW_REGISTER`,label:`ALLOW_REGISTER`,type:`bool`,hint:`是否允许自助注册`},{key:`JWT_TTL`,label:`JWT_TTL`,placeholder:`2h`,hint:`例如 30m / 2h / 24h`}]},{title:`邮件与验证`,icon:K,keys:[{key:`SMTP_ENABLED`,label:`SMTP_ENABLED`,type:`bool`},{key:`SMTP_HOST`,label:`SMTP_HOST`,placeholder:`smtp.example.com`},{key:`SMTP_PORT`,label:`SMTP_PORT`,placeholder:`587`},{key:`SMTP_USER`,label:`SMTP_USER`},{key:`SMTP_PASS`,label:`SMTP_PASS`,hint:`脱敏存储`},{key:`SMTP_FROM`,label:`SMTP_FROM`},{key:`SMTP_FROM_NAME`,label:`SMTP_FROM_NAME`,placeholder:`SyncLive`},{key:`SMTP_TLS`,label:`SMTP_TLS`,type:`bool`},{key:`EMAIL_VERIFY_REQUIRED`,label:`EMAIL_VERIFY_REQUIRED`,type:`bool`},{key:`EMAIL_VERIFY_TTL`,label:`EMAIL_VERIFY_TTL`,placeholder:`24h`},{key:`EMAIL_VERIFY_BASE_URL`,label:`EMAIL_VERIFY_BASE_URL`}]},{title:`OAuth 登录`,icon:R,keys:[{key:`OAUTH_ENABLED`,label:`OAUTH_ENABLED`,type:`bool`},{key:`OAUTH_CALLBACK_BASE`,label:`OAUTH_CALLBACK_BASE`,placeholder:`http://localhost:8088`},{key:`OAUTH_GOOGLE_CLIENT_ID`,label:`GOOGLE_CLIENT_ID`},{key:`OAUTH_GOOGLE_CLIENT_SECRET`,label:`GOOGLE_CLIENT_SECRET`},{key:`OAUTH_GITHUB_CLIENT_ID`,label:`GITHUB_CLIENT_ID`},{key:`OAUTH_GITHUB_CLIENT_SECRET`,label:`GITHUB_CLIENT_SECRET`},{key:`OAUTH_GITLAB_CLIENT_ID`,label:`GITLAB_CLIENT_ID`},{key:`OAUTH_GITLAB_CLIENT_SECRET`,label:`GITLAB_CLIENT_SECRET`},{key:`OAUTH_GENERIC_URL`,label:`GENERIC_URL`},{key:`OAUTH_GENERIC_CLIENT_ID`,label:`GENERIC_CLIENT_ID`},{key:`OAUTH_GENERIC_CLIENT_SECRET`,label:`GENERIC_CLIENT_SECRET`},{key:`OAUTH_GENERIC_NAME`,label:`GENERIC_NAME`,placeholder:`generic`}]}];function ut(a){let s=()=>b.can(`config:write`)||b.can(`system:manage`)||b.isAdminOrAbove(),[u,p]=o(null),[m,_]=o({}),[v,T]=o(!1),[E,O]=o(null),[k,ne]=o(!1),[A,M]=o(0),N=async()=>{try{let e=await g.manageRuntimeConfig();p(e),_({...e.values})}catch(e){O({tone:`error`,text:String(e?.message||e)})}};f(N),r(()=>{b.check()});let P=()=>{let e=u();if(!e)return!1;let t=m();return Object.keys(t).some(n=>(t[n]??``)!==(e.values[n]??``))},F=(e,t)=>_(n=>({...n,[e]:t})),I=async()=>{if(!s()){O({tone:`error`,text:`无权限:需要 admin/root`});return}let e=u();if(!e)return;let t={},n=m();for(let r of Object.keys(n))if((n[r]??``)!==(e.values[r]??``)){if(e.masked[r]&&n[r]===`••••••••`)continue;t[r]=n[r]??``}if(Object.keys(t).length===0){O({tone:`info`,text:`没有变更`});return}T(!0);try{let e=await g.saveRuntimeConfig(t);O({tone:`success`,text:`已保存 ${e.changed?.length??0} 项,已热生效,无需重启`});let n=await g.manageRuntimeConfig();p(n),_({...n.values})}catch(e){O({tone:`error`,text:String(e?.message||e)})}finally{T(!1)}},re=async()=>{if(!s()||!confirm(`将当前分组的运行时覆盖重置为环境/默认值?`))return;let e=lt[A()];try{await g.resetRuntimeConfig(e.keys.map(e=>e.key)),O({tone:`success`,text:`已重置,已热生效`}),await N()}catch(e){O({tone:`error`,text:String(e?.message||e)})}},L=async()=>{if(!(!s()||!confirm(`重置所有运行时覆盖?将回落至环境变量/默认值并立即生效。`)))try{await g.resetRuntimeConfig([]),O({tone:`success`,text:`已重置全部,已热生效`}),await N()}catch(e){O({tone:`error`,text:String(e?.message||e)})}};return(()=>{var r=tt(),o=r.firstChild,f=o.firstChild,p=f.firstChild,g=p.firstChild,_=f.nextSibling,b=o.nextSibling.firstChild,T=b.firstChild,R=b.nextSibling,z=R.firstChild,B=z.firstChild,V=B.firstChild,ie=V.firstChild,H=V.nextSibling,U=H.firstChild,G=B.nextSibling.firstChild,oe=G.firstChild,q=G.nextSibling;return q.firstChild.nextSibling.nextSibling,l(r,e(i,{get when(){return E()},get children(){return e(S,{get tone(){return n(()=>E().tone===`error`)()?`error`:E().tone===`success`?`success`:`info`},class:`flex items-center justify-between gap-3`,get children(){return[(()=>{var t=$e();return l(t,e(w,{class:`size-4`}),null),l(t,()=>E().text,null),t})(),(()=>{var e=et();return e.$$click=()=>O(null),e})()]}})}}),o),l(p,e(K,{class:`size-4`}),g),l(_,e(i,{get when(){return!s()},get children(){return e(y,{variant:`warning`,children:`只读`})}}),null),l(_,e(i,{get when(){return s()},get children(){return e(x,{variant:`ghost`,class:`h-9 gap-1.5`,onClick:()=>ne(e=>!e),get children(){return[n(()=>n(()=>!!k())()?e(te,{class:`size-4`}):e(ee,{class:`size-4`})),n(()=>k()?`隐藏密钥`:`显示密钥`)]}})}}),null),l(_,e(x,{variant:`outline`,class:`h-9 gap-1.5`,onClick:N,get disabled(){return v()},children:`刷新`}),null),l(_,e(x,{variant:`ghost`,class:`h-9 gap-1.5`,onClick:re,get disabled(){return!s()||v()},get children(){return[e(ae,{class:`size-4`}),`重置分组`]}}),null),l(_,e(x,{variant:`ghost`,class:`h-9 gap-1.5`,onClick:L,get disabled(){return!s()||v()},children:`重置全部`}),null),l(_,e(x,{class:`h-9 gap-1.5`,onClick:I,get disabled(){return!s()||v()||!P()},get children(){return[e(W,{class:`size-4`}),n(()=>n(()=>!!v())()?`保存中...`:P()?`保存并生效`:`已是最新`)]}}),null),l(b,e(c,{each:lt,children:(n,r)=>{let i=n.icon,a=()=>r()===A();return(()=>{var o=nt(),s=o.firstChild;return o.$$click=()=>M(r()),l(o,e(i,{class:`size-3.5 shrink-0`}),s),l(s,()=>n.title),d(()=>t(o,`flex items-center gap-2 border px-3 py-2.5 text-left text-xs font-medium transition-colors ${a()?`border-line bg-acid-lime text-black`:`border-transparent bg-card text-muted-foreground hover:bg-accent hover:text-foreground`}`)),o})()}}),T),l(R,e(i,{get when(){return u()},get fallback(){return rt()},get children(){return(()=>{let n=lt[A()];return(()=>{var r=it(),a=r.firstChild,o=a.firstChild,f=o.nextSibling,p=f.firstChild,g=a.nextSibling;return l(o,()=>n.title),l(f,()=>n.keys.length,p),l(g,e(c,{get each(){return n.keys},children:n=>{let r=()=>u().source[n.key]||`default`,a=()=>!!u().masked[n.key],o=()=>m()[n.key]??``,c=()=>r()===`runtime`?`bg-acid-lime`:r()===`env`?`bg-acid-cyan`:`bg-line`;return(()=>{var u=st(),f=u.firstChild,p=f.firstChild,m=p.firstChild,g=m.nextSibling,_=g.firstChild,v=f.nextSibling;return l(m,()=>n.label),l(g,r,null),l(p,e(i,{get when(){return a()},get children(){return e(y,{variant:`outline`,class:`text-[10px]`,children:`secret`})}}),null),l(f,e(i,{get when(){return n.hint},get children(){var e=at();return l(e,()=>n.hint),e}}),null),l(f,e(i,{get when(){return n.placeholder},get children(){var e=ot();return e.firstChild,l(e,()=>n.placeholder,null),e}}),null),l(v,e(i,{get when(){return n.type===`bool`},get fallback(){return e(h,{get value(){return o()},onInput:e=>F(n.key,e),get placeholder(){return n.placeholder||``},get type(){return a()&&!k()?`password`:`text`},get disabled(){return!s()},class:`h-9 font-mono text-xs`})},get children(){return e(C,{get value(){return o()||`0`},onChange:e=>F(n.key,e),options:[{value:`0`,label:`关闭 (0)`},{value:`1`,label:`开启 (1)`}],get disabled(){return!s()}})}})),d(e=>{var n=`inline-flex items-center gap-1 border px-1.5 py-0.5 text-[10px] font-medium uppercase tracking-widest ${r()===`runtime`?`border-acid-lime/40 bg-acid-lime/15 text-foreground`:r()===`env`?`border-acid-cyan/40 bg-acid-cyan/10 text-foreground`:`border-line bg-muted text-muted-foreground`}`,i=`size-1.5 ${c()}`;return n!==e.e&&t(g,e.e=n),i!==e.t&&t(_,e.t=i),e},{e:void 0,t:void 0}),u})()}})),r})()})()}}),z),l(V,e(j,{class:`size-4`}),ie),l(H,e(c,{get each(){return a.overview?.backends||[]},children:t=>(()=>{var n=ct(),r=n.firstChild;return l(r,e(j,{class:`size-4 text-muted-foreground`}),null),l(r,()=>t.name||t.kind,null),l(n,e(y,{get variant(){return t.configured?`success`:`muted`},get children(){return t.configured?`已配置`:`未配置`}}),null),n})()}),U),l(G,e(w,{class:`size-4`}),oe),l(q,e(x,{variant:`ghost`,class:`mt-2 h-8 gap-1.5 text-xs`,onClick:()=>window.open(`/api/manage/config?raw=1`,`_blank`),get children(){return[e(D,{class:`size-4`}),`查看原始 JSON`]}}),null),r})()}T([`click`]);var dt=_(`<div class="border border-line bg-card/50"><div class="flex items-center justify-between border-b border-line/80 px-4 py-3"><h3 class=font-semibold>系统用户与全局角色</h3><span class="mono-label text-muted-foreground"> users`),ft=_(`<p class="px-5 py-6 text-sm text-muted-foreground">暂无用户`),pt=_(`<div>`),mt=_(`<span class="text-[10px] px-1.5 py-0.5 border border-destructive/30 bg-destructive/10 text-destructive">banned`),ht=_(`<div><div class="flex min-w-0 items-center gap-3"><span></span><div class=min-w-0><p class="truncate font-mono text-sm font-medium flex items-center gap-2"> </p><p class="micro-label text-muted-foreground"> · </p></div></div><div class="flex flex-wrap items-center gap-2">`),gt=_(`<span class="text-xs text-muted-foreground/60">无权变更`);function _t(n){let r=e=>n.actorRole===`root`?[`viewer`,`publisher`,`admin`,`root`]:n.actorRole===`admin`?e===`admin`||e===`root`?[]:[`viewer`,`publisher`]:[],a=e=>n.actorRole===`root`?e.role!==`root`:n.actorRole===`admin`?e.role===`viewer`||e.role===`publisher`:!1;return(()=>{var o=dt(),s=o.firstChild.firstChild.nextSibling,u=s.firstChild;return l(s,()=>n.users.length,u),l(o,e(i,{get when(){return!n.canList},get fallback(){return(()=>{var o=pt();return l(o,e(c,{get each(){return n.users},children:o=>{let s=o.role,c=$[s]||$.viewer,u=o.status===`banned`,f=r(s),p=f.length>0;return(()=>{var r=ht(),m=r.firstChild,h=m.firstChild,g=h.nextSibling.firstChild,_=g.firstChild,v=g.nextSibling,b=v.firstChild,S=m.nextSibling;return t(r,`flex flex-wrap items-center justify-between gap-3 border-b border-line/60 px-5 py-3 last:border-0 ${u?`bg-destructive/5`:``}`),l(h,()=>(o.username[0]||`?`).toUpperCase()),l(g,()=>o.username,_),l(g,e(i,{when:u,get children(){return mt()}}),null),l(v,s,b),l(v,u?`已封禁`:`active`,null),l(S,e(y,{get class(){return c.color},children:s}),null),l(S,e(i,{when:p,get fallback(){return gt()},get children(){return e(C,{class:`w-28`,value:s,get"aria-label"(){return`调整 ${o.username} 的角色`},get disabled(){return!!n.busy||u},onChange:async e=>n.onRoleChange(o,e),get options(){return f.map(e=>({value:e,label:e}))}})}}),null),l(S,e(i,{get when(){return a(o)},get children(){return e(x,{variant:u?`outline`:`ghost`,class:`h-7 px-2 text-xs ${u?`border-success/30 text-success`:`text-destructive`}`,get disabled(){return n.busy===o.username},onClick:()=>n.onToggleBan(o),children:u?`解封`:`封禁`})}}),null),d(()=>t(h,`flex size-8 shrink-0 items-center justify-center border font-mono text-xs font-bold ${c.color}`)),r})()}}),null),l(o,e(i,{get when(){return n.users.length===0},get children(){return ft()}}),null),o})()},get children(){return e(S,{tone:`warning`,class:`m-4`,children:`无权限查看:需要 user:list(管理员及以上)`})}}),null),o})()}var vt=_(`<span class="flex items-center gap-2">`),yt=_(`<button class="text-xs underline">关闭`),bt=()=>{let[t,a]=o(`overview`),[s,c]=o(null),[u,d]=o([]),[f,p]=o(null),[m,h]=o(``),[_,C]=o([]),[w,T]=o(``),[ee,te]=o(!1),[E,D]=o(``),[O,k]=o(``),[ne,A]=o(!0),[j,N]=o(`100`),[F,I]=o(``),[re,L]=o(!1),[R,z]=o(null),[B,V]=o(``),[H,ae]=o(``),[U,W]=o(null),[G,K]=o(null),[oe,q]=o([]),[se,J]=o(``),Y=async()=>{try{let e=await g.manageOverview();c(e)}catch(e){T(String(e?.message||e))}},X=async()=>{try{let e=await g.manageRooms();d(e.rooms||[]),!m()&&e.rooms?.length&&h(e.rooms[0].room.name)}catch(e){T(String(e?.message||e))}},ce=async()=>{try{let e=await g.managePermMatrix();p(e)}catch{}},le=async()=>{try{let e=await g.listUsers();q(e.users||[])}catch{}},Z=async e=>{if(e)try{let t=await g.manageMembers(e);C(t.members||[]);let n=await g.manageRoomDetail(e);z(n.room),V(n.room.description||``),ae(String(n.room.max_members||100)),W(n.room.settings||null);try{let t=await g.manageRoomDistribution(e);K(t)}catch{K(null)}}catch(e){T(String(e?.message||e))}};r(()=>{Y(),X(),ce(),le()}),r(()=>{let e=m();e&&(t()===`rooms`||t()===`permissions`)&&Z(e)});let de=async()=>{let e=E().trim();if(e){te(!0);try{await g.manageCreateRoom({name:e,description:O().trim()||void 0,is_public:ne(),max_members:parseInt(j())||100,password:F().trim()||void 0}),D(``),k(``),I(``),await X(),await Y()}catch(e){T(String(e?.message||e))}finally{te(!1)}}},fe=async()=>{let e=m();if(!(!e||!R()))try{await g.manageUpdateRoom(e,{description:B(),max_members:parseInt(H())||void 0,is_public:R().is_public}),await X(),await Z(e)}catch(e){T(String(e?.message||e))}},pe=async e=>{if(confirm(`删除房间 ${e} ?`))try{await g.manageDeleteRoom(e),await X(),await Y()}catch(e){T(String(e?.message||e))}},me=async(e,t,n)=>{try{await g.manageUpdateMemberRole(e,t,n),await Z(e)}catch(e){T(String(e?.message||e))}},_e=async(e,t)=>{if(confirm(`踢出 ${t} ?`))try{await g.manageKickMember(e,t),await Z(e)}catch(e){T(String(e?.message||e))}},ve=async(e,t)=>{try{await g.manageBanMember(e,t),await Z(e)}catch(e){T(String(e?.message||e))}},ye=async(e,t)=>{try{await g.manageApproveMember(e,t),await Z(e)}catch(e){T(String(e?.message||e))}},be=async(e,t)=>{try{await g.manageRejectMember(e,t),await Z(e)}catch(e){T(String(e?.message||e))}},xe=async(e,t)=>{try{await g.manageTransferOwnership(e,t),await Z(e),await X()}catch(e){T(String(e?.message||e))}},Se=async(e,t,n,r)=>{let i=1<<we.indexOf(n),a=_().find(e=>e.username===t);if(!a)return;let o=Number(a.added||0),s=Number(a.removed||0);r?(o&=~i,s|=i):(o|=i,s&=~i);try{await g.manageUpdateMemberPerms(e,t,o,s,!1),await Z(e)}catch(e){T(String(e?.message||e))}},Q=async()=>{let e=m();if(!(!e||!U()))try{await g.manageUpdateRoomSettings(e,U()),await Z(e)}catch(e){T(String(e?.message||e))}},Te=async(e,t)=>{let n=m();if(!n)return;let r=new Set(G()?.effective||[]);t?r.add(e):r.delete(e);let i=Array.from(r);try{let e=await g.manageUpdateRoomDistributionList(n,i);K(t=>({...t||{},effective:e.effective,custom:e.distributors,has_custom:!0,custom_list:e.effective})),await Z(n)}catch(e){T(String(e?.message||e))}},$=async()=>{let e=m();if(e)try{let t=await g.manageClearRoomDistribution(e);K(e=>({...e||{},effective:t.effective,has_custom:!1,custom:null,custom_list:[]})),await Z(e)}catch(e){T(String(e?.message||e))}},Ee=async(e,t)=>{J(e.username);try{await g.updateUserRole(e.username,t),q(n=>n.map(n=>n.username===e.username?{...n,role:t}:n)),await b.refresh()}catch(e){T(String(e?.message||e))}finally{J(``)}},De=async e=>{let t=e.status===`banned`;if(confirm(t?`解封 ${e.username}?`:`封禁 ${e.username}?封禁后无法登录`)){J(e.username);try{t?await g.unbanUser(e.username):await g.banUser(e.username),await le()}catch(e){T(String(e?.message||e))}finally{J(``)}}};return e(he,{get children(){return[e(ge,{title:`管理控制台`,description:`统一管理房间、角色与权限。房主全量,管理员/成员/访客基于角色默认值 + 个人覆盖计算生效权限。全局管理员(admin/root)可跨房间管理,无需加入房间。`,get actions(){return[e(y,{variant:`outline`,class:`gap-1.5`,get children(){return[e(P,{class:`size-3.5`}),n(()=>v.user()?.username||`guest`),` · `,n(()=>b.role())]}}),e(x,{variant:`ghost`,class:`h-9 gap-1.5`,onClick:()=>{Y(),X(),le(),m()&&Z(m())},get children(){return[e(ie,{class:`size-4`}),`刷新`]}})]}}),e(i,{get when(){return w()},get children(){return e(S,{tone:`error`,class:`flex items-center justify-between gap-3`,get children(){return[(()=>{var t=vt();return l(t,e(M,{class:`size-4`}),null),l(t,w,null),t})(),(()=>{var e=yt();return e.$$click=()=>T(``),e})()]}})}}),e(ue,{get value(){return t()},onChange:a}),e(i,{get when(){return t()===`overview`},get children(){return e(Ce,{get overview(){return s()},get rooms(){return u()}})}}),e(i,{get when(){return t()===`rooms`},get children(){return e(Be,{get rooms(){return u()},get selectedRoom(){return m()},onSelectRoom:h,get members(){return _()},get editingRoom(){return R()},get roomSettings(){return U()},setRoomSettings:W,get newRoom(){return{name:E(),desc:O(),isPublic:ne(),max:j(),pwd:F(),showPwd:re()}},setNewRoom:e=>{e.name!==void 0&&D(e.name),e.desc!==void 0&&k(e.desc),e.isPublic!==void 0&&A(e.isPublic),e.max!==void 0&&N(e.max),e.pwd!==void 0&&I(e.pwd),e.showPwd!==void 0&&L(e.showPwd)},get edit(){return{desc:B(),max:H()}},setEdit:e=>{e.desc!==void 0&&V(e.desc),e.max!==void 0&&ae(e.max)},get loading(){return ee()},onCreate:de,onSave:fe,onDelete:pe,onChangeRole:me,onKick:_e,onBan:ve,onApprove:ye,onReject:be,onTransfer:xe,onSaveSettings:Q,get distribution(){return G()},onToggleDistribution:Te,onClearDistribution:$})}}),e(i,{get when(){return t()===`permissions`},get children(){return e(Qe,{get rooms(){return u()},get selectedRoom(){return m()},onSelectRoom:h,get members(){return _()},get permDefs(){return f()},onTogglePerm:Se})}}),e(i,{get when(){return t()===`users`},get children(){return e(_t,{get users(){return oe()},onRoleChange:Ee,onToggleBan:De,get canList(){return b.can(`user:list`)},get actorRole(){return b.role()},get busy(){return se()}})}}),e(i,{get when(){return t()===`system`},get children(){return e(ut,{get overview(){return s()}})}})]}})};T([`click`]);export{bt as Manage}; |