Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8473520eb3 |
No files matched your search
Vendored
+2
-2
@@ -1,2 +1,2 @@
|
||||
var _e,k,$e,it,q,Ee,Ae,He,Oe,he,fe,de,ct,X={},Re=[],at=/acit|ex(?:s|g|n|p|$)|rph|grid|ows|mnc|ntw|ine[ch]|zoo|^ord|itera/i,se=Array.isArray;function F(e,t){for(var n in t)e[n]=t[n];return e}function me(e){e&&e.parentNode&&e.parentNode.removeChild(e)}function y(e,t,n){var r,i,_,c={};for(_ in t)_=="key"?r=t[_]:_=="ref"?i=t[_]:c[_]=t[_];if(arguments.length>2&&(c.children=arguments.length>3?_e.call(arguments,2):n),typeof e=="function"&&e.defaultProps!=null)for(_ in e.defaultProps)c[_]===void 0&&(c[_]=e.defaultProps[_]);return ne(e,c,r,i,null)}function ne(e,t,n,r,i){var _={type:e,props:t,key:n,ref:r,__k:null,__:null,__b:0,__e:null,__c:null,constructor:void 0,__v:i??++$e,__i:-1,__u:0};return i==null&&k.vnode!=null&&k.vnode(_),_}function ie(e){return e.children}function oe(e,t){this.props=e,this.context=t}function z(e,t){if(t==null)return e.__?z(e.__,e.__i+1):null;for(var n;t<e.__k.length;t++)if((n=e.__k[t])!=null&&n.__e!=null)return n.__e;return typeof e.type=="function"?z(e):null}function De(e){var t,n;if((e=e.__)!=null&&e.__c!=null){for(e.__e=e.__c.base=null,t=0;t<e.__k.length;t++)if((n=e.__k[t])!=null&&n.__e!=null){e.__e=e.__c.base=n.__e;break}return De(e)}}function Pe(e){(!e.__d&&(e.__d=!0)&&q.push(e)&&!re.__r++||Ee!=k.debounceRendering)&&((Ee=k.debounceRendering)||Ae)(re)}function re(){for(var e,t,n,r,i,_,c,u=1;q.length;)q.length>u&&q.sort(He),e=q.shift(),u=q.length,e.__d&&(n=void 0,r=void 0,i=(r=(t=e).__v).__e,_=[],c=[],t.__P&&((n=F({},r)).__v=r.__v+1,k.vnode&&k.vnode(n),ve(t.__P,n,r,t.__n,t.__P.namespaceURI,32&r.__u?[i]:null,_,i??z(r),!!(32&r.__u),c),n.__v=r.__v,n.__.__k[n.__i]=n,Fe(_,n,c),r.__e=r.__=null,n.__e!=i&&De(n)));re.__r=0}function Ue(e,t,n,r,i,_,c,u,m,a,v){var s,p,h,w,P,T,g,b=r&&r.__k||Re,A=t.length;for(m=lt(n,t,b,m,A),s=0;s<A;s++)(h=n.__k[s])!=null&&(p=h.__i==-1?X:b[h.__i]||X,h.__i=s,T=ve(e,h,p,i,_,c,u,m,a,v),w=h.__e,h.ref&&p.ref!=h.ref&&(p.ref&&ye(p.ref,null,h),v.push(h.ref,h.__c||w,h)),P==null&&w!=null&&(P=w),(g=!!(4&h.__u))||p.__k===h.__k?m=Le(h,m,e,g):typeof h.type=="function"&&T!==void 0?m=T:w&&(m=w.nextSibling),h.__u&=-7);return n.__e=P,m}function lt(e,t,n,r,i){var _,c,u,m,a,v=n.length,s=v,p=0;for(e.__k=new Array(i),_=0;_<i;_++)(c=t[_])!=null&&typeof c!="boolean"&&typeof c!="function"?(typeof c=="string"||typeof c=="number"||typeof c=="bigint"||c.constructor==String?c=e.__k[_]=ne(null,c,null,null,null):se(c)?c=e.__k[_]=ne(ie,{children:c},null,null,null):c.constructor===void 0&&c.__b>0?c=e.__k[_]=ne(c.type,c.props,c.key,c.ref?c.ref:null,c.__v):e.__k[_]=c,m=_+p,c.__=e,c.__b=e.__b+1,u=null,(a=c.__i=ut(c,n,m,s))!=-1&&(s--,(u=n[a])&&(u.__u|=2)),u==null||u.__v==null?(a==-1&&(i>v?p--:i<v&&p++),typeof c.type!="function"&&(c.__u|=4)):a!=m&&(a==m-1?p--:a==m+1?p++:(a>m?p--:p++,c.__u|=4))):e.__k[_]=null;if(s)for(_=0;_<v;_++)(u=n[_])!=null&&(2&u.__u)==0&&(u.__e==r&&(r=z(u)),je(u,u));return r}function Le(e,t,n,r){var i,_;if(typeof e.type=="function"){for(i=e.__k,_=0;i&&_<i.length;_++)i[_]&&(i[_].__=e,t=Le(i[_],t,n,r));return t}e.__e!=t&&(r&&(t&&e.type&&!t.parentNode&&(t=z(e)),n.insertBefore(e.__e,t||null)),t=e.__e);do t=t&&t.nextSibling;while(t!=null&&t.nodeType==8);return t}function ut(e,t,n,r){var i,_,c,u=e.key,m=e.type,a=t[n],v=a!=null&&(2&a.__u)==0;if(a===null&&u==null||v&&u==a.key&&m==a.type)return n;if(r>(v?1:0)){for(i=n-1,_=n+1;i>=0||_<t.length;)if((a=t[c=i>=0?i--:_++])!=null&&(2&a.__u)==0&&u==a.key&&m==a.type)return c}return-1}function Ne(e,t,n){t[0]=="-"?e.setProperty(t,n??""):e[t]=n==null?"":typeof n!="number"||at.test(t)?n:n+"px"}function te(e,t,n,r,i){var _,c;e:if(t=="style")if(typeof n=="string")e.style.cssText=n;else{if(typeof r=="string"&&(e.style.cssText=r=""),r)for(t in r)n&&t in n||Ne(e.style,t,"");if(n)for(t in n)r&&n[t]==r[t]||Ne(e.style,t,n[t])}else if(t[0]=="o"&&t[1]=="n")_=t!=(t=t.replace(Oe,"$1")),c=t.toLowerCase(),t=c in e||t=="onFocusOut"||t=="onFocusIn"?c.slice(2):t.slice(2),e.l||(e.l={}),e.l[t+_]=n,n?r?n.u=r.u:(n.u=he,e.addEventListener(t,_?de:fe,_)):e.removeEventListener(t,_?de:fe,_);else{if(i=="http://www.w3.org/2000/svg")t=t.replace(/xlink(H|:h)/,"h").replace(/sName$/,"s");else if(t!="width"&&t!="height"&&t!="href"&&t!="list"&&t!="form"&&t!="tabIndex"&&t!="download"&&t!="rowSpan"&&t!="colSpan"&&t!="role"&&t!="popover"&&t in e)try{e[t]=n??"";break e}catch{}typeof n=="function"||(n==null||n===!1&&t[4]!="-"?e.removeAttribute(t):e.setAttribute(t,t=="popover"&&n==1?"":n))}}function Me(e){return function(t){if(this.l){var n=this.l[t.type+e];if(t.t==null)t.t=he++;else if(t.t<n.u)return;return n(k.event?k.event(t):t)}}}function ve(e,t,n,r,i,_,c,u,m,a){var v,s,p,h,w,P,T,g,b,A,D,J,U,Q,V,H,K,N=t.type;if(t.constructor!==void 0)return null;128&n.__u&&(m=!!(32&n.__u),_=[u=t.__e=n.__e]),(v=k.__b)&&v(t);e:if(typeof N=="function")try{if(g=t.props,b="prototype"in N&&N.prototype.render,A=(v=N.contextType)&&r[v.__c],D=v?A?A.props.value:v.__:r,n.__c?T=(s=t.__c=n.__c).__=s.__E:(b?t.__c=s=new N(g,D):(t.__c=s=new oe(g,D),s.constructor=N,s.render=dt),A&&A.sub(s),s.state||(s.state={}),s.__n=r,p=s.Line truncated
|
||||
`):"",f={id:o.id,ts:o.ts,from:o.from,to:o.to,command:o.command};switch(o.command){case"PRIVMSG":case"NOTICE":{let d={...f,text:l,system:!1},S=o.to;if(S&&S.startsWith("#"))O(S,d);else{let x=o.from===N.current?o.to:o.from;_(Y=>Y.find(xe=>xe.type==="dm"&&xe.name===x)?Y:[...Y,{type:"dm",name:x}]),O(x,d)}break}case"JOIN":{let d=`${o.from} has joined ${o.to}`;o.to&&O(o.to,{...f,text:d,system:!0}),o.to&&o.to.startsWith("#")&&B(o.to);break}case"PART":{let d=l?": "+l:"",S=`${o.from} has left ${o.to}${d}`;o.to&&O(o.to,{...f,text:S,system:!0}),o.to&&o.to.startsWith("#")&&B(o.to);break}case"QUIT":{let d=l?": "+l:"",S=`${o.from} has quit${d}`;H.current.forEach(x=>{x.type==="channel"&&O(x.name,{...f,text:S,system:!0})});break}case"NICK":{let d=Array.isArray(o.body)?o.body[0]:l,S=`${o.from} is now known as ${d}`;H.current.forEach(x=>{x.type==="channel"&&O(x.name,{...f,text:S,system:!0})}),o.from===N.current&&d&&r(d),H.current.forEach(x=>{x.type==="channel"&&B(x.name)});break}case"TOPIC":{let d=`${o.from} set the topic: ${l}`;o.to&&(O(o.to,{...f,text:d,system:!0}),h(S=>({...S,[o.to]:l})));break}case"375":case"372":case"376":O("Server",{...f,text:l,system:!0});break;default:O("Server",{...f,text:l||o.command,system:!0})}},[O,B]);$(()=>{if(!e)return;let o=!0;return(async()=>{for(;o;)try{let f=new AbortController;V.current=f;let d=await M(`/messages?after=${U.current}&timeout=${yt}`,{signal:f.signal});if(!o)break;if(J(!0),d.messages)for(let S of d.messages)ae(S);d.last_id>U.current&&(U.current=d.last_id)}catch(f){if(!o)break;if(f.name==="AbortError")continue;J(!1),await new Promise(d=>setTimeout(d,bt))}})(),()=>{o=!1,V.current?.abort()}},[e,ae]),$(()=>{if(!e)return;let o=i[c];if(!o||o.type!=="channel")return;B(o.name);let l=setInterval(()=>B(o.name),gt);return()=>clearInterval(l)},[e,c,i,B]),$(()=>{L.current?.scrollIntoView({behavior:"smooth"})},[m,c]),$(()=>{Se.current?.focus()},[c]),$(()=>{if(!e)return;let o=i[c];!o||o.type!=="channel"||M("/channels").then(l=>{let f=l.find(d=>d.name===o.name);f&&f.topic&&h(d=>({...d,[o.name]:f.topic}))}).catch(()=>{})},[e,c,i]);let rt=G(async o=>{r(o),t(!0),W("Server",`Connected as ${o}`);let l=JSON.parse(localStorage.getItem("neoirc_channels")||"[]");for(let f of l)try{await M("/messages",{method:"POST",body:JSON.stringify({command:"JOIN",to:f})}),_(d=>d.find(S=>S.type==="channel"&&S.name===f)?d:[...d,{type:"channel",name:f}])}catch{}},[W]),le=async o=>{if(o){o=o.trim(),o.startsWith("#")||(o="#"+o);try{await M("/messages",{method:"POST",body:JSON.stringify({command:"JOIN",to:o})}),_(l=>l.find(f=>f.type==="channel"&&f.name===o)?l:[...l,{type:"channel",name:o}]),u(i.length);try{let l=await M(`/history?target=${encodeURIComponent(o)}&limit=50`);if(Array.isArray(l))for(let f of l)ae(f)}catch{}A("")}catch(l){W("Server",`Failed to join ${o}: ${l.data?.error||"error"}`)}}},we=async o=>{try{await M("/messages",{method:"POST",body:JSON.stringify({command:"PART",to:o})})}catch{}_(l=>l.filter(f=>!(f.type==="channel"&&f.name===o))),u(0)},_t=o=>{let l=i[o];l.type==="channel"?we(l.name):l.type==="dm"&&(_(f=>f.filter((d,S)=>S!==o)),c>=o&&u(Math.max(0,c-1)))},Ce=o=>{_(f=>f.find(d=>d.type==="dm"&&d.name===o)?f:[...f,{type:"dm",name:o}]);let l=i.findIndex(f=>f.type==="dm"&&f.name===o);u(l>=0?l:i.length)},Te=async()=>{let o=T.trim();if(!o)return;g("");let l=i[c];if(!(!l||l.type==="server")){if(o.startsWith("/")){let f=o.split(" "),d=f[0].toLowerCase();if(d==="/join"&&f[1]){le(f[1]);return}if(d==="/part"){l.type==="channel"&&we(l.name);return}if(d==="/msg"&&f[1]&&f.slice(2).join(" ")){let S=f[1],x=f.slice(2).join(" ");try{await M("/messages",{method:"POST",body:JSON.stringify({command:"PRIVMSG",to:S,body:[x]})}),Ce(S)}catch(Y){W("Server",`DM failed: ${Y.data?.error||"error"}`)}return}if(d==="/nick"&&f[1]){try{await M("/messages",{method:"POST",body:JSON.stringify({command:"NICK",body:[f[1]]})})}catch(S){W("Server",`Nick change failed: ${S.data?.error||"error"}`)}return}if(d==="/topic"&&l.type==="channel"){let S=f.slice(1).join(" ");try{await M("/messages",{method:"POST",body:JSON.stringify({command:"TOPIC",to:l.name,body:[S]})})}catch(x){W("Server",`Topic failed: ${x.data?.error||"error"}`)}return}W("Server",`Unknown command: ${d}`);return}try{await M("/messages",{method:"POST",body:JSON.stringify({command:"PRIVMSG",to:l.name,body:[o]})})}catch(f){W(l.name,`Send failed: ${f.data?.error||"error"}`)}}};if(!e)return y(kt,{onLogin:rt});let j=i[c]||i[0],st=m[j.name]||[],Ie=v[j.name]||[],ue=p[j.name]||"";return y("div",{class:"app"},y("div",{class:"tab-bar"},!D&&y("div",{class:"connection-status"},"\u26A0 Reconnecting..."),i.map((o,l)=>y("div",{class:`tab ${l===c?"active":""}`,onClick:()=>u(l)},o.type==="dm"?`\u2192${o.name}`:o.name,w[o.name]>0&&l!==c&&y("span",{class:"unread-badge"},w[o.name]),o.type!=="server"&&y("span",{class:"close-btn",onClick:f=>{f.stopPropagation(),_t(l)}},"\xD7"))),y("div",{class:"join-dialog"},y("input",{placeholder:"#channel",value:b,onInput:o=>A(o.target.value),onKeyDown:o=>o.key==="Ent
Line truncated
|
||||
var ae,S,He,ht,K,Ae,Re,De,Le,he,de,pe,yt,X={},je=[],vt=/acit|ex(?:s|g|n|p|$)|rph|grid|ows|mnc|ntw|ine[ch]|zoo|^ord|itera/i,_e=Array.isArray;function J(e,t){for(var n in t)e[n]=t[n];return e}function ye(e){e&&e.parentNode&&e.parentNode.removeChild(e)}function y(e,t,n){var r,a,s,c={};for(s in t)s=="key"?r=t[s]:s=="ref"?a=t[s]:c[s]=t[s];if(arguments.length>2&&(c.children=arguments.length>3?ae.call(arguments,2):n),typeof e=="function"&&e.defaultProps!=null)for(s in e.defaultProps)c[s]===void 0&&(c[s]=e.defaultProps[s]);return oe(e,c,r,a,null)}function oe(e,t,n,r,a){var s={type:e,props:t,key:n,ref:r,__k:null,__:null,__b:0,__e:null,__c:null,constructor:void 0,__v:a??++He,__i:-1,__u:0};return a==null&&S.vnode!=null&&S.vnode(s),s}function ce(e){return e.children}function re(e,t){this.props=e,this.context=t}function Q(e,t){if(t==null)return e.__?Q(e.__,e.__i+1):null;for(var n;t<e.__k.length;t++)if((n=e.__k[t])!=null&&n.__e!=null)return n.__e;return typeof e.type=="function"?Q(e):null}function We(e){var t,n;if((e=e.__)!=null&&e.__c!=null){for(e.__e=e.__c.base=null,t=0;t<e.__k.length;t++)if((n=e.__k[t])!=null&&n.__e!=null){e.__e=e.__c.base=n.__e;break}return We(e)}}function Oe(e){(!e.__d&&(e.__d=!0)&&K.push(e)&&!se.__r++||Ae!=S.debounceRendering)&&((Ae=S.debounceRendering)||Re)(se)}function se(){for(var e,t,n,r,a,s,c,u=1;K.length;)K.length>u&&K.sort(De),e=K.shift(),u=K.length,e.__d&&(n=void 0,r=void 0,a=(r=(t=e).__v).__e,s=[],c=[],t.__P&&((n=J({},r)).__v=r.__v+1,S.vnode&&S.vnode(n),ve(t.__P,n,r,t.__n,t.__P.namespaceURI,32&r.__u?[a]:null,s,a??Q(r),!!(32&r.__u),c),n.__v=r.__v,n.__.__k[n.__i]=n,Be(s,n,c),r.__e=r.__=null,n.__e!=a&&We(n)));se.__r=0}function Fe(e,t,n,r,a,s,c,u,v,l,b){var _,m,h,T,A,x,g,k=r&&r.__k||je,O=t.length;for(v=bt(n,t,k,v,O),_=0;_<O;_++)(h=n.__k[_])!=null&&(m=h.__i==-1?X:k[h.__i]||X,h.__i=_,x=ve(e,h,m,a,s,c,u,v,l,b),T=h.__e,h.ref&&m.ref!=h.ref&&(m.ref&&be(m.ref,null,h),b.push(h.ref,h.__c||T,h)),A==null&&T!=null&&(A=T),(g=!!(4&h.__u))||m.__k===h.__k?v=Je(h,v,e,g):typeof h.type=="function"&&x!==void 0?v=x:T&&(v=T.nextSibling),h.__u&=-7);return n.__e=A,v}function bt(e,t,n,r,a){var s,c,u,v,l,b=n.length,_=b,m=0;for(e.__k=new Array(a),s=0;s<a;s++)(c=t[s])!=null&&typeof c!="boolean"&&typeof c!="function"?(typeof c=="string"||typeof c=="number"||typeof c=="bigint"||c.constructor==String?c=e.__k[s]=oe(null,c,null,null,null):_e(c)?c=e.__k[s]=oe(ce,{children:c},null,null,null):c.constructor===void 0&&c.__b>0?c=e.__k[s]=oe(c.type,c.props,c.key,c.ref?c.ref:null,c.__v):e.__k[s]=c,v=s+m,c.__=e,c.__b=e.__b+1,u=null,(l=c.__i=kt(c,n,v,_))!=-1&&(_--,(u=n[l])&&(u.__u|=2)),u==null||u.__v==null?(l==-1&&(a>b?m--:a<b&&m++),typeof c.type!="function"&&(c.__u|=4)):l!=v&&(l==v-1?m--:l==v+1?m++:(l>v?m--:m++,c.__u|=4))):e.__k[s]=null;if(_)for(s=0;s<b;s++)(u=n[s])!=null&&(2&u.__u)==0&&(u.__e==r&&(r=Q(u)),qe(u,u));return r}function Je(e,t,n,r){var a,s;if(typeof e.type=="function"){for(a=e.__k,s=0;a&&s<a.length;s++)a[s]&&(a[s].__=e,t=Je(a[s],t,n,r));return t}e.__e!=t&&(r&&(t&&e.type&&!t.parentNode&&(t=Q(e)),n.insertBefore(e.__e,t||null)),t=e.__e);do t=t&&t.nextSibling;while(t!=null&&t.nodeType==8);return t}function kt(e,t,n,r){var a,s,c,u=e.key,v=e.type,l=t[n],b=l!=null&&(2&l.__u)==0;if(l===null&&u==null||b&&u==l.key&&v==l.type)return n;if(r>(b?1:0)){for(a=n-1,s=n+1;a>=0||s<t.length;)if((l=t[c=a>=0?a--:s++])!=null&&(2&l.__u)==0&&u==l.key&&v==l.type)return c}return-1}function $e(e,t,n){t[0]=="-"?e.setProperty(t,n??""):e[t]=n==null?"":typeof n!="number"||vt.test(t)?n:n+"px"}function ne(e,t,n,r,a){var s,c;e:if(t=="style")if(typeof n=="string")e.style.cssText=n;else{if(typeof r=="string"&&(e.style.cssText=r=""),r)for(t in r)n&&t in n||$e(e.style,t,"");if(n)for(t in n)r&&n[t]==r[t]||$e(e.style,t,n[t])}else if(t[0]=="o"&&t[1]=="n")s=t!=(t=t.replace(Le,"$1")),c=t.toLowerCase(),t=c in e||t=="onFocusOut"||t=="onFocusIn"?c.slice(2):t.slice(2),e.l||(e.l={}),e.l[t+s]=n,n?r?n.u=r.u:(n.u=he,e.addEventListener(t,s?pe:de,s)):e.removeEventListener(t,s?pe:de,s);else{if(a=="http://www.w3.org/2000/svg")t=t.replace(/xlink(H|:h)/,"h").replace(/sName$/,"s");else if(t!="width"&&t!="height"&&t!="href"&&t!="list"&&t!="form"&&t!="tabIndex"&&t!="download"&&t!="rowSpan"&&t!="colSpan"&&t!="role"&&t!="popover"&&t in e)try{e[t]=n??"";break e}catch{}typeof n=="function"||(n==null||n===!1&&t[4]!="-"?e.removeAttribute(t):e.setAttribute(t,t=="popover"&&n==1?"":n))}}function Ue(e){return function(t){if(this.l){var n=this.l[t.type+e];if(t.t==null)t.t=he++;else if(t.t<n.u)return;return n(S.event?S.event(t):t)}}}function ve(e,t,n,r,a,s,c,u,v,l){var b,_,m,h,T,A,x,g,k,O,j,V,H,te,B,R,q,$=t.type;if(t.constructor!==void 0)return null;128&n.__u&&(v=!!(32&n.__u),s=[u=t.__e=n.__e]),(b=S.__b)&&b(t);e:if(typeof $=="function")try{if(g=t.props,k="prototype"in $&&$.prototype.render,O=(b=$.contextType)&&r[b.__c],j=b?O?O.props.value:b.__:r,n.__c?x=(_=t.__c=n.__c).__=_.__E:(k?t.__c=_=new $(g,j):(t.__c=_=new re(g,j),_.constructor=$,_.render=St),O&&O.sub(_),_.state||(_.state={}),_.__n=r,m=_Line truncated
|
||||
`):"",f={id:o.id,ts:o.ts,from:o.from,to:o.to,command:o.command},d=o.meta&&o.meta.action;switch(o.command){case"PRIVMSG":case"NOTICE":{let p={...f,text:i,system:!1,action:d},w=o.to;if(w&&w.startsWith("#"))D(w,p);else{let N=o.from===le.current?o.to:o.from;s(fe=>fe.find(Ne=>Ne.type==="dm"&&Ne.name===N)?fe:[...fe,{type:"dm",name:N}]),D(N,p)}break}case"JOIN":{let p=`${o.from} has joined ${o.to}`;o.to&&D(o.to,{...f,text:p,system:!0}),o.to&&o.to.startsWith("#")&&G(o.to);break}case"PART":{let p=i?": "+i:"",w=`${o.from} has parted ${o.to}${p}`;o.to&&D(o.to,{...f,text:w,system:!0}),o.to&&o.to.startsWith("#")&&G(o.to);break}case"QUIT":{let p=i?": "+i:"",w=`${o.from} has quit${p}`;Y.current.forEach(N=>{N.type==="channel"&&D(N.name,{...f,text:w,system:!0})});break}case"NICK":{let p=Array.isArray(o.body)?o.body[0]:i,w=`${o.from} is now known as ${p}`;Y.current.forEach(N=>{N.type==="channel"&&D(N.name,{...f,text:w,system:!0})}),o.from===le.current&&p&&r(p),Y.current.forEach(N=>{N.type==="channel"&&G(N.name)});break}case"TOPIC":{let p=`${o.from} set the topic: ${i}`;o.to&&(D(o.to,{...f,text:p,system:!0}),A(w=>({...w,[o.to]:i})));break}case"332":{let p=Array.isArray(o.params)&&o.params.length>0?o.params[0]:o.to;p&&A(w=>({...w,[p]:i}));break}case"353":{let p=Array.isArray(o.params)&&o.params.length>1?o.params[1]:o.to;p&&i&&Ie(p,i);break}case"366":break;case"375":case"372":case"376":D("Server",{...f,text:i,system:!0});break;default:D("Server",{...f,text:i||o.command,system:!0})}},[D,G,Ie]);U(()=>{if(!e)return;let o=!0;return(async()=>{for(;o;)try{let f=new AbortController;W.current=f;let d=await M(`/messages?after=${q.current}&timeout=${It}`,{signal:f.signal});if(!o)break;if(V(!0),d.messages)for(let p of d.messages)ue(p);d.last_id>q.current&&(q.current=d.last_id)}catch(f){if(!o)break;if(f.name==="AbortError")continue;V(!1),await new Promise(d=>setTimeout(d,Pt))}})(),()=>{o=!1,W.current?.abort()}},[e,ue]),U(()=>{if(!e)return;let o=a[c];if(!o||o.type!=="channel")return;G(o.name);let i=setInterval(()=>G(o.name),Et);return()=>clearInterval(i)},[e,c,a,G]),U(()=>{Te.current?.scrollIntoView({behavior:"smooth"})},[v,c]),U(()=>{xe.current?.focus()},[c]),U(()=>{if(!e)return;let o=a[c];!o||o.type!=="channel"||M("/channels").then(i=>{let f=i.find(d=>d.name===o.name);f&&f.topic&&A(d=>({...d,[o.name]:f.topic}))}).catch(()=>{})},[e,c,a]);let _t=z(async o=>{r(o),t(!0),P("Server",`Connected as ${o}`);let i=JSON.parse(localStorage.getItem("neoirc_channels")||"[]");for(let f of i)try{await M("/messages",{method:"POST",body:JSON.stringify({command:"JOIN",to:f})}),s(d=>d.find(p=>p.type==="channel"&&p.name===f)?d:[...d,{type:"channel",name:f}])}catch{}},[P]),ct=async o=>{if(o){o=o.trim(),o.startsWith("#")||(o="#"+o);try{await M("/messages",{method:"POST",body:JSON.stringify({command:"JOIN",to:o})}),s(i=>i.find(f=>f.type==="channel"&&f.name===o)?i:[...i,{type:"channel",name:o}]),u(a.length);try{let i=await M(`/history?target=${encodeURIComponent(o)}&limit=50`);if(Array.isArray(i))for(let f of i)ue(f)}catch{}}catch(i){P("Server",`Failed to join ${o}: ${i.data?.error||"error"}`)}}},Pe=async(o,i)=>{try{let f={command:"PART",to:o};i&&(f.body=[i]),await M("/messages",{method:"POST",body:JSON.stringify(f)})}catch{}s(f=>f.filter(d=>!(d.type==="channel"&&d.name===o))),u(0)},it=o=>{let i=a[o];i.type==="channel"?Pe(i.name):i.type==="dm"&&(s(f=>f.filter((d,p)=>p!==o)),c>=o&&u(Math.max(0,c-1)))},Ee=o=>{s(f=>f.find(d=>d.type==="dm"&&d.name===o)?f:[...f,{type:"dm",name:o}]);let i=a.findIndex(f=>f.type==="dm"&&f.name===o);u(i>=0?i:a.length)},lt=async o=>{let i=o.split(" "),f=i[0].toLowerCase(),d=a[c];switch(f){case"/join":i[1]?ct(i[1]):P(d?.name||"Server","Usage: /join #channel");break;case"/part":{if(d?.type==="channel"){let p=i.slice(1).join(" ")||"";Pe(d.name,p)}else P(d?.name||"Server","Not in a channel");break}case"/msg":if(i[1]&&i.slice(2).join(" ")){let p=i[1],w=i.slice(2).join(" ");try{await M("/messages",{method:"POST",body:JSON.stringify({command:"PRIVMSG",to:p,body:[w]})}),Ee(p)}catch(N){P("Server",`DM failed: ${N.data?.error||"error"}`)}}else P(d?.name||"Server","Usage: /msg <nick> <message>");break;case"/me":if(d&&d.type!=="server"){let p=i.slice(1).join(" ");if(p)try{await M("/messages",{method:"POST",body:JSON.stringify({command:"PRIVMSG",to:d.name,body:[p],meta:{action:!0}})})}catch(w){P(d.name,`Action failed: ${w.data?.error||"error"}`)}else P(d.name,"Usage: /me <action>")}break;case"/nick":if(i[1])try{await M("/messages",{method:"POST",body:JSON.stringify({command:"NICK",body:[i[1]]})})}catch(p){P("Server",`Nick change failed: ${p.data?.error||"error"}`)}else P(d?.name||"Server","Usage: /nick <newnick>");break;case"/topic":if(d?.type==="channel"){let p=i.slice(1).join(" ");try{await M("/messages",{method:"POST",body:JSON.stringify({command:"TOPIC",to:d.name,body:[p]})})}catch(w){P(d.name,`Topic failed: ${w.data?.error||"error"}`)}}else P(d?.name||"Server","Not in a channel");break;case"/mode":if(d?.type==="channel"&&i.length>=2){let p=i[1].star
Line truncated
|
||||
Vendored
+216
-102
@@ -1,28 +1,40 @@
|
||||
* { margin: 0; padding: 0; box-sizing: border-box; }
|
||||
|
||||
:root {
|
||||
--bg: #1a1a2e;
|
||||
--bg-secondary: #16213e;
|
||||
--bg-input: #0f3460;
|
||||
--text: #e0e0e0;
|
||||
--text-muted: #888;
|
||||
--accent: #e94560;
|
||||
--accent2: #0f3460;
|
||||
--border: #2a2a4a;
|
||||
--nick: #53a8b6;
|
||||
--timestamp: #666;
|
||||
--tab-active: #e94560;
|
||||
--tab-bg: #16213e;
|
||||
--tab-hover: #1a1a3e;
|
||||
--topic-bg: #121a30;
|
||||
--unread-bg: #e94560;
|
||||
--warn: #f0ad4e;
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
html, body, #root {
|
||||
:root {
|
||||
--bg: #0a0e14;
|
||||
--bg-secondary: #0d1117;
|
||||
--bg-input: #161b22;
|
||||
--bg-highlight: #1a2030;
|
||||
--text: #c9d1d9;
|
||||
--text-muted: #6e7681;
|
||||
--accent: #58a6ff;
|
||||
--accent-dim: #1f6feb;
|
||||
--border: #21262d;
|
||||
--nick: #79c0ff;
|
||||
--timestamp: #484f58;
|
||||
--tab-active: #58a6ff;
|
||||
--tab-bg: #0d1117;
|
||||
--tab-hover: #161b22;
|
||||
--topic-bg: #0d1117;
|
||||
--unread-bg: #da3633;
|
||||
--warn: #d29922;
|
||||
--op-color: #f0883e;
|
||||
--voice-color: #3fb950;
|
||||
--action-color: #bc8cff;
|
||||
--system-color: #484f58;
|
||||
}
|
||||
|
||||
html,
|
||||
body,
|
||||
#root {
|
||||
height: 100%;
|
||||
font-family: 'Courier New', Courier, monospace;
|
||||
font-size: 14px;
|
||||
font-family: 'JetBrains Mono', 'Fira Code', 'Cascadia Code', 'Courier New',
|
||||
Courier, monospace;
|
||||
font-size: 13px;
|
||||
background: var(--bg);
|
||||
color: var(--text);
|
||||
}
|
||||
@@ -57,15 +69,19 @@ html, body, #root {
|
||||
padding: 10px 24px;
|
||||
font-size: 16px;
|
||||
font-family: inherit;
|
||||
background: var(--accent);
|
||||
background: var(--accent-dim);
|
||||
border: none;
|
||||
color: white;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.login-screen button:hover {
|
||||
background: var(--accent);
|
||||
}
|
||||
|
||||
.login-screen .error {
|
||||
color: var(--accent);
|
||||
color: var(--unread-bg);
|
||||
}
|
||||
|
||||
.login-screen .motd {
|
||||
@@ -89,36 +105,63 @@ html, body, #root {
|
||||
border-bottom: 1px solid var(--border);
|
||||
overflow-x: auto;
|
||||
flex-shrink: 0;
|
||||
align-items: center;
|
||||
align-items: stretch;
|
||||
min-height: 32px;
|
||||
}
|
||||
|
||||
.tab-bar::-webkit-scrollbar {
|
||||
height: 2px;
|
||||
}
|
||||
|
||||
.tab-bar::-webkit-scrollbar-thumb {
|
||||
background: var(--border);
|
||||
}
|
||||
|
||||
.tab {
|
||||
padding: 8px 16px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 6px 12px;
|
||||
cursor: pointer;
|
||||
border-bottom: 2px solid transparent;
|
||||
white-space: nowrap;
|
||||
color: var(--text-muted);
|
||||
user-select: none;
|
||||
position: relative;
|
||||
font-size: 12px;
|
||||
gap: 6px;
|
||||
transition:
|
||||
background 0.1s,
|
||||
color 0.1s;
|
||||
}
|
||||
|
||||
.tab:hover {
|
||||
background: var(--tab-hover);
|
||||
color: var(--text);
|
||||
}
|
||||
|
||||
.tab.active {
|
||||
color: var(--text);
|
||||
border-bottom-color: var(--tab-active);
|
||||
background: var(--bg-highlight);
|
||||
}
|
||||
|
||||
.tab.server {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.tab .tab-name {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.tab .close-btn {
|
||||
margin-left: 8px;
|
||||
color: var(--text-muted);
|
||||
font-size: 12px;
|
||||
font-size: 14px;
|
||||
line-height: 1;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.tab .close-btn:hover {
|
||||
color: var(--accent);
|
||||
color: var(--unread-bg);
|
||||
}
|
||||
|
||||
.tab .unread-badge {
|
||||
@@ -127,19 +170,22 @@ html, body, #root {
|
||||
color: white;
|
||||
font-size: 10px;
|
||||
font-weight: bold;
|
||||
padding: 1px 5px;
|
||||
padding: 0 5px;
|
||||
border-radius: 8px;
|
||||
margin-left: 6px;
|
||||
min-width: 16px;
|
||||
text-align: center;
|
||||
line-height: 16px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
/* Connection status */
|
||||
.connection-status {
|
||||
padding: 4px 12px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 0 12px;
|
||||
background: var(--warn);
|
||||
color: #1a1a2e;
|
||||
font-size: 12px;
|
||||
color: var(--bg);
|
||||
font-size: 11px;
|
||||
font-weight: bold;
|
||||
white-space: nowrap;
|
||||
flex-shrink: 0;
|
||||
@@ -147,7 +193,7 @@ html, body, #root {
|
||||
|
||||
/* Topic bar */
|
||||
.topic-bar {
|
||||
padding: 6px 12px;
|
||||
padding: 4px 12px;
|
||||
background: var(--topic-bg);
|
||||
border-bottom: 1px solid var(--border);
|
||||
color: var(--text-muted);
|
||||
@@ -158,6 +204,11 @@ html, body, #root {
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.topic-bar .topic-label {
|
||||
color: var(--accent);
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
/* Content area */
|
||||
.content {
|
||||
display: flex;
|
||||
@@ -171,147 +222,210 @@ html, body, #root {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.messages {
|
||||
flex: 1;
|
||||
overflow-y: auto;
|
||||
padding: 8px 12px;
|
||||
padding: 4px 0;
|
||||
}
|
||||
|
||||
.messages::-webkit-scrollbar {
|
||||
width: 6px;
|
||||
}
|
||||
|
||||
.messages::-webkit-scrollbar-thumb {
|
||||
background: var(--border);
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.message {
|
||||
padding: 2px 0;
|
||||
line-height: 1.4;
|
||||
padding: 1px 12px;
|
||||
line-height: 1.5;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
|
||||
.message:hover {
|
||||
background: var(--bg-highlight);
|
||||
}
|
||||
|
||||
.message .timestamp {
|
||||
color: var(--timestamp);
|
||||
font-size: 12px;
|
||||
margin-right: 8px;
|
||||
font-size: 11px;
|
||||
margin-right: 6px;
|
||||
}
|
||||
|
||||
.message .nick {
|
||||
color: var(--nick);
|
||||
font-weight: bold;
|
||||
margin-right: 8px;
|
||||
margin-right: 6px;
|
||||
}
|
||||
|
||||
.message .nick::before { content: '<'; }
|
||||
.message .nick::after { content: '>'; }
|
||||
.message .nick::before {
|
||||
content: '<';
|
||||
color: var(--text-muted);
|
||||
}
|
||||
|
||||
.message .nick::after {
|
||||
content: '>';
|
||||
color: var(--text-muted);
|
||||
}
|
||||
|
||||
.message.system {
|
||||
color: var(--text-muted);
|
||||
color: var(--system-color);
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.message.system .nick {
|
||||
color: var(--text-muted);
|
||||
.message.system .timestamp {
|
||||
color: var(--timestamp);
|
||||
}
|
||||
|
||||
.message.system .nick::before,
|
||||
.message.system .nick::after { content: ''; }
|
||||
.message.system .content::before {
|
||||
content: '*** ';
|
||||
}
|
||||
|
||||
/* Input */
|
||||
.message.action {
|
||||
color: var(--action-color);
|
||||
}
|
||||
|
||||
.message.action .timestamp {
|
||||
color: var(--timestamp);
|
||||
}
|
||||
|
||||
.message.action .action-nick {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
/* Input bar — full width at bottom */
|
||||
.input-bar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
border-top: 1px solid var(--border);
|
||||
background: var(--bg-secondary);
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.input-bar .input-nick {
|
||||
padding: 0 8px 0 12px;
|
||||
color: var(--accent);
|
||||
font-weight: bold;
|
||||
white-space: nowrap;
|
||||
flex-shrink: 0;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.input-bar .input-nick::after {
|
||||
content: '>';
|
||||
color: var(--text-muted);
|
||||
margin-left: 1px;
|
||||
}
|
||||
|
||||
.input-bar input {
|
||||
flex: 1;
|
||||
padding: 10px 12px;
|
||||
padding: 8px 8px;
|
||||
font-family: inherit;
|
||||
font-size: 14px;
|
||||
background: var(--bg-input);
|
||||
font-size: 13px;
|
||||
background: transparent;
|
||||
border: none;
|
||||
color: var(--text);
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.input-bar button {
|
||||
padding: 10px 16px;
|
||||
font-family: inherit;
|
||||
background: var(--accent);
|
||||
border: none;
|
||||
color: white;
|
||||
cursor: pointer;
|
||||
.input-bar input::placeholder {
|
||||
color: var(--text-muted);
|
||||
}
|
||||
|
||||
/* User list */
|
||||
.user-list {
|
||||
width: 160px;
|
||||
width: 170px;
|
||||
background: var(--bg-secondary);
|
||||
border-left: 1px solid var(--border);
|
||||
overflow-y: auto;
|
||||
padding: 8px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.user-list h3 {
|
||||
.user-list-header {
|
||||
padding: 6px 10px;
|
||||
color: var(--text-muted);
|
||||
font-size: 11px;
|
||||
text-transform: uppercase;
|
||||
margin-bottom: 8px;
|
||||
letter-spacing: 1px;
|
||||
letter-spacing: 0.5px;
|
||||
border-bottom: 1px solid var(--border);
|
||||
font-weight: bold;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.user-list-entries {
|
||||
overflow-y: auto;
|
||||
flex: 1;
|
||||
padding: 4px 0;
|
||||
}
|
||||
|
||||
.user-list-entries::-webkit-scrollbar {
|
||||
width: 4px;
|
||||
}
|
||||
|
||||
.user-list-entries::-webkit-scrollbar-thumb {
|
||||
background: var(--border);
|
||||
}
|
||||
|
||||
.user-list .user {
|
||||
padding: 3px 4px;
|
||||
color: var(--nick);
|
||||
font-size: 13px;
|
||||
padding: 2px 10px;
|
||||
font-size: 12px;
|
||||
cursor: pointer;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
color: var(--text);
|
||||
}
|
||||
|
||||
.user-list .user:hover {
|
||||
background: var(--tab-hover);
|
||||
}
|
||||
|
||||
/* Server tab */
|
||||
.user-list .user.op {
|
||||
color: var(--op-color);
|
||||
}
|
||||
|
||||
.user-list .user.voice {
|
||||
color: var(--voice-color);
|
||||
}
|
||||
|
||||
/* Server tab messages */
|
||||
.server-messages {
|
||||
color: var(--text-muted);
|
||||
padding: 12px;
|
||||
padding: 8px 12px;
|
||||
white-space: pre-wrap;
|
||||
overflow-y: auto;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
/* Channel join dialog */
|
||||
.join-dialog {
|
||||
padding: 12px;
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
background: var(--bg-secondary);
|
||||
border-bottom: 1px solid var(--border);
|
||||
margin-left: auto;
|
||||
.server-messages .message {
|
||||
padding: 1px 0;
|
||||
}
|
||||
|
||||
.join-dialog input {
|
||||
padding: 6px 10px;
|
||||
font-family: inherit;
|
||||
font-size: 13px;
|
||||
background: var(--bg-input);
|
||||
border: 1px solid var(--border);
|
||||
color: var(--text);
|
||||
border-radius: 3px;
|
||||
width: 200px;
|
||||
}
|
||||
|
||||
.join-dialog button {
|
||||
padding: 6px 14px;
|
||||
font-family: inherit;
|
||||
font-size: 13px;
|
||||
background: var(--accent2);
|
||||
border: none;
|
||||
color: var(--text);
|
||||
border-radius: 3px;
|
||||
cursor: pointer;
|
||||
.server-messages .message:hover {
|
||||
background: var(--bg-highlight);
|
||||
}
|
||||
|
||||
/* Responsive */
|
||||
@media (max-width: 600px) {
|
||||
.user-list { display: none; }
|
||||
.tab { padding: 6px 10px; font-size: 13px; }
|
||||
.user-list {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.tab {
|
||||
padding: 5px 8px;
|
||||
font-size: 11px;
|
||||
}
|
||||
|
||||
.input-bar .input-nick {
|
||||
padding-left: 8px;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.input-bar input {
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
+627
-219
File diff suppressed because it is too large.
Load diff
+216
-102
@@ -1,28 +1,40 @@
|
||||
* { margin: 0; padding: 0; box-sizing: border-box; }
|
||||
|
||||
:root {
|
||||
--bg: #1a1a2e;
|
||||
--bg-secondary: #16213e;
|
||||
--bg-input: #0f3460;
|
||||
--text: #e0e0e0;
|
||||
--text-muted: #888;
|
||||
--accent: #e94560;
|
||||
--accent2: #0f3460;
|
||||
--border: #2a2a4a;
|
||||
--nick: #53a8b6;
|
||||
--timestamp: #666;
|
||||
--tab-active: #e94560;
|
||||
--tab-bg: #16213e;
|
||||
--tab-hover: #1a1a3e;
|
||||
--topic-bg: #121a30;
|
||||
--unread-bg: #e94560;
|
||||
--warn: #f0ad4e;
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
html, body, #root {
|
||||
:root {
|
||||
--bg: #0a0e14;
|
||||
--bg-secondary: #0d1117;
|
||||
--bg-input: #161b22;
|
||||
--bg-highlight: #1a2030;
|
||||
--text: #c9d1d9;
|
||||
--text-muted: #6e7681;
|
||||
--accent: #58a6ff;
|
||||
--accent-dim: #1f6feb;
|
||||
--border: #21262d;
|
||||
--nick: #79c0ff;
|
||||
--timestamp: #484f58;
|
||||
--tab-active: #58a6ff;
|
||||
--tab-bg: #0d1117;
|
||||
--tab-hover: #161b22;
|
||||
--topic-bg: #0d1117;
|
||||
--unread-bg: #da3633;
|
||||
--warn: #d29922;
|
||||
--op-color: #f0883e;
|
||||
--voice-color: #3fb950;
|
||||
--action-color: #bc8cff;
|
||||
--system-color: #484f58;
|
||||
}
|
||||
|
||||
html,
|
||||
body,
|
||||
#root {
|
||||
height: 100%;
|
||||
font-family: 'Courier New', Courier, monospace;
|
||||
font-size: 14px;
|
||||
font-family: 'JetBrains Mono', 'Fira Code', 'Cascadia Code', 'Courier New',
|
||||
Courier, monospace;
|
||||
font-size: 13px;
|
||||
background: var(--bg);
|
||||
color: var(--text);
|
||||
}
|
||||
@@ -57,15 +69,19 @@ html, body, #root {
|
||||
padding: 10px 24px;
|
||||
font-size: 16px;
|
||||
font-family: inherit;
|
||||
background: var(--accent);
|
||||
background: var(--accent-dim);
|
||||
border: none;
|
||||
color: white;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.login-screen button:hover {
|
||||
background: var(--accent);
|
||||
}
|
||||
|
||||
.login-screen .error {
|
||||
color: var(--accent);
|
||||
color: var(--unread-bg);
|
||||
}
|
||||
|
||||
.login-screen .motd {
|
||||
@@ -89,36 +105,63 @@ html, body, #root {
|
||||
border-bottom: 1px solid var(--border);
|
||||
overflow-x: auto;
|
||||
flex-shrink: 0;
|
||||
align-items: center;
|
||||
align-items: stretch;
|
||||
min-height: 32px;
|
||||
}
|
||||
|
||||
.tab-bar::-webkit-scrollbar {
|
||||
height: 2px;
|
||||
}
|
||||
|
||||
.tab-bar::-webkit-scrollbar-thumb {
|
||||
background: var(--border);
|
||||
}
|
||||
|
||||
.tab {
|
||||
padding: 8px 16px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 6px 12px;
|
||||
cursor: pointer;
|
||||
border-bottom: 2px solid transparent;
|
||||
white-space: nowrap;
|
||||
color: var(--text-muted);
|
||||
user-select: none;
|
||||
position: relative;
|
||||
font-size: 12px;
|
||||
gap: 6px;
|
||||
transition:
|
||||
background 0.1s,
|
||||
color 0.1s;
|
||||
}
|
||||
|
||||
.tab:hover {
|
||||
background: var(--tab-hover);
|
||||
color: var(--text);
|
||||
}
|
||||
|
||||
.tab.active {
|
||||
color: var(--text);
|
||||
border-bottom-color: var(--tab-active);
|
||||
background: var(--bg-highlight);
|
||||
}
|
||||
|
||||
.tab.server {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.tab .tab-name {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.tab .close-btn {
|
||||
margin-left: 8px;
|
||||
color: var(--text-muted);
|
||||
font-size: 12px;
|
||||
font-size: 14px;
|
||||
line-height: 1;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.tab .close-btn:hover {
|
||||
color: var(--accent);
|
||||
color: var(--unread-bg);
|
||||
}
|
||||
|
||||
.tab .unread-badge {
|
||||
@@ -127,19 +170,22 @@ html, body, #root {
|
||||
color: white;
|
||||
font-size: 10px;
|
||||
font-weight: bold;
|
||||
padding: 1px 5px;
|
||||
padding: 0 5px;
|
||||
border-radius: 8px;
|
||||
margin-left: 6px;
|
||||
min-width: 16px;
|
||||
text-align: center;
|
||||
line-height: 16px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
/* Connection status */
|
||||
.connection-status {
|
||||
padding: 4px 12px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 0 12px;
|
||||
background: var(--warn);
|
||||
color: #1a1a2e;
|
||||
font-size: 12px;
|
||||
color: var(--bg);
|
||||
font-size: 11px;
|
||||
font-weight: bold;
|
||||
white-space: nowrap;
|
||||
flex-shrink: 0;
|
||||
@@ -147,7 +193,7 @@ html, body, #root {
|
||||
|
||||
/* Topic bar */
|
||||
.topic-bar {
|
||||
padding: 6px 12px;
|
||||
padding: 4px 12px;
|
||||
background: var(--topic-bg);
|
||||
border-bottom: 1px solid var(--border);
|
||||
color: var(--text-muted);
|
||||
@@ -158,6 +204,11 @@ html, body, #root {
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.topic-bar .topic-label {
|
||||
color: var(--accent);
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
/* Content area */
|
||||
.content {
|
||||
display: flex;
|
||||
@@ -171,147 +222,210 @@ html, body, #root {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.messages {
|
||||
flex: 1;
|
||||
overflow-y: auto;
|
||||
padding: 8px 12px;
|
||||
padding: 4px 0;
|
||||
}
|
||||
|
||||
.messages::-webkit-scrollbar {
|
||||
width: 6px;
|
||||
}
|
||||
|
||||
.messages::-webkit-scrollbar-thumb {
|
||||
background: var(--border);
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.message {
|
||||
padding: 2px 0;
|
||||
line-height: 1.4;
|
||||
padding: 1px 12px;
|
||||
line-height: 1.5;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
|
||||
.message:hover {
|
||||
background: var(--bg-highlight);
|
||||
}
|
||||
|
||||
.message .timestamp {
|
||||
color: var(--timestamp);
|
||||
font-size: 12px;
|
||||
margin-right: 8px;
|
||||
font-size: 11px;
|
||||
margin-right: 6px;
|
||||
}
|
||||
|
||||
.message .nick {
|
||||
color: var(--nick);
|
||||
font-weight: bold;
|
||||
margin-right: 8px;
|
||||
margin-right: 6px;
|
||||
}
|
||||
|
||||
.message .nick::before { content: '<'; }
|
||||
.message .nick::after { content: '>'; }
|
||||
.message .nick::before {
|
||||
content: '<';
|
||||
color: var(--text-muted);
|
||||
}
|
||||
|
||||
.message .nick::after {
|
||||
content: '>';
|
||||
color: var(--text-muted);
|
||||
}
|
||||
|
||||
.message.system {
|
||||
color: var(--text-muted);
|
||||
color: var(--system-color);
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.message.system .nick {
|
||||
color: var(--text-muted);
|
||||
.message.system .timestamp {
|
||||
color: var(--timestamp);
|
||||
}
|
||||
|
||||
.message.system .nick::before,
|
||||
.message.system .nick::after { content: ''; }
|
||||
.message.system .content::before {
|
||||
content: '*** ';
|
||||
}
|
||||
|
||||
/* Input */
|
||||
.message.action {
|
||||
color: var(--action-color);
|
||||
}
|
||||
|
||||
.message.action .timestamp {
|
||||
color: var(--timestamp);
|
||||
}
|
||||
|
||||
.message.action .action-nick {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
/* Input bar — full width at bottom */
|
||||
.input-bar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
border-top: 1px solid var(--border);
|
||||
background: var(--bg-secondary);
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.input-bar .input-nick {
|
||||
padding: 0 8px 0 12px;
|
||||
color: var(--accent);
|
||||
font-weight: bold;
|
||||
white-space: nowrap;
|
||||
flex-shrink: 0;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.input-bar .input-nick::after {
|
||||
content: '>';
|
||||
color: var(--text-muted);
|
||||
margin-left: 1px;
|
||||
}
|
||||
|
||||
.input-bar input {
|
||||
flex: 1;
|
||||
padding: 10px 12px;
|
||||
padding: 8px 8px;
|
||||
font-family: inherit;
|
||||
font-size: 14px;
|
||||
background: var(--bg-input);
|
||||
font-size: 13px;
|
||||
background: transparent;
|
||||
border: none;
|
||||
color: var(--text);
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.input-bar button {
|
||||
padding: 10px 16px;
|
||||
font-family: inherit;
|
||||
background: var(--accent);
|
||||
border: none;
|
||||
color: white;
|
||||
cursor: pointer;
|
||||
.input-bar input::placeholder {
|
||||
color: var(--text-muted);
|
||||
}
|
||||
|
||||
/* User list */
|
||||
.user-list {
|
||||
width: 160px;
|
||||
width: 170px;
|
||||
background: var(--bg-secondary);
|
||||
border-left: 1px solid var(--border);
|
||||
overflow-y: auto;
|
||||
padding: 8px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.user-list h3 {
|
||||
.user-list-header {
|
||||
padding: 6px 10px;
|
||||
color: var(--text-muted);
|
||||
font-size: 11px;
|
||||
text-transform: uppercase;
|
||||
margin-bottom: 8px;
|
||||
letter-spacing: 1px;
|
||||
letter-spacing: 0.5px;
|
||||
border-bottom: 1px solid var(--border);
|
||||
font-weight: bold;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.user-list-entries {
|
||||
overflow-y: auto;
|
||||
flex: 1;
|
||||
padding: 4px 0;
|
||||
}
|
||||
|
||||
.user-list-entries::-webkit-scrollbar {
|
||||
width: 4px;
|
||||
}
|
||||
|
||||
.user-list-entries::-webkit-scrollbar-thumb {
|
||||
background: var(--border);
|
||||
}
|
||||
|
||||
.user-list .user {
|
||||
padding: 3px 4px;
|
||||
color: var(--nick);
|
||||
font-size: 13px;
|
||||
padding: 2px 10px;
|
||||
font-size: 12px;
|
||||
cursor: pointer;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
color: var(--text);
|
||||
}
|
||||
|
||||
.user-list .user:hover {
|
||||
background: var(--tab-hover);
|
||||
}
|
||||
|
||||
/* Server tab */
|
||||
.user-list .user.op {
|
||||
color: var(--op-color);
|
||||
}
|
||||
|
||||
.user-list .user.voice {
|
||||
color: var(--voice-color);
|
||||
}
|
||||
|
||||
/* Server tab messages */
|
||||
.server-messages {
|
||||
color: var(--text-muted);
|
||||
padding: 12px;
|
||||
padding: 8px 12px;
|
||||
white-space: pre-wrap;
|
||||
overflow-y: auto;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
/* Channel join dialog */
|
||||
.join-dialog {
|
||||
padding: 12px;
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
background: var(--bg-secondary);
|
||||
border-bottom: 1px solid var(--border);
|
||||
margin-left: auto;
|
||||
.server-messages .message {
|
||||
padding: 1px 0;
|
||||
}
|
||||
|
||||
.join-dialog input {
|
||||
padding: 6px 10px;
|
||||
font-family: inherit;
|
||||
font-size: 13px;
|
||||
background: var(--bg-input);
|
||||
border: 1px solid var(--border);
|
||||
color: var(--text);
|
||||
border-radius: 3px;
|
||||
width: 200px;
|
||||
}
|
||||
|
||||
.join-dialog button {
|
||||
padding: 6px 14px;
|
||||
font-family: inherit;
|
||||
font-size: 13px;
|
||||
background: var(--accent2);
|
||||
border: none;
|
||||
color: var(--text);
|
||||
border-radius: 3px;
|
||||
cursor: pointer;
|
||||
.server-messages .message:hover {
|
||||
background: var(--bg-highlight);
|
||||
}
|
||||
|
||||
/* Responsive */
|
||||
@media (max-width: 600px) {
|
||||
.user-list { display: none; }
|
||||
.tab { padding: 6px 10px; font-size: 13px; }
|
||||
.user-list {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.tab {
|
||||
padding: 5px 8px;
|
||||
font-size: 11px;
|
||||
}
|
||||
|
||||
.input-bar .input-nick {
|
||||
padding-left: 8px;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.input-bar input {
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user