mirror of
https://github.com/chylex/Discord-History-Tracker.git
synced 2025-04-12 05:15:42 +02:00
163 lines
26 KiB
HTML
163 lines
26 KiB
HTML
<!DOCTYPE html>
|
|
<html>
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<title>Discord Offline History</title>
|
|
|
|
<script type="text/javascript">
|
|
var e=function(){var e,n,a,i,s,o,l,u,d,f,p={i:/\*\*([\s\S]+?)\*\*(?!\*)/g,s:/(.)?\*([\s\S]+?)\*(?!\*)/g,o:/__([\s\S]+?)__(?!_)/g,l:/~~([\s\S]+?)~~(?!~)/g,p:/(`+)\s*([\s\S]*?[^`])\s*\1(?!`)/g,g:/```(?:([A-z0-9\-]+?)\n+)?\n*([^]+?)\n*```/g,v:/(\b(?:https?|ftp|file):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/gi,h:/<(\b(?:https?|ftp|file):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])>/gi,L:/\\`/g,C:/\\([*\\])/g,j:/\\__|_\\_|\\_\\_|\\~~|~\\~|\\~\\~/g,M:/([*_~\\])/g,U:/<@&(\d+?)>/g,k:/<@!?(\d+?)>/g,T:/<#(\d+?)>/g,R:/<:([^:]+):(\d+?)>/g,S:/<a:([^:]+):(\d+?)>/g},m=function(e){var t=e.url.lastIndexOf("."),n=-1===t?"":e.url.substring(t).toLowerCase();return".png"===n||".gif"===n||".jpg"===n||".jpeg"===n},g=function(e){var t=new Date(e);return t.toLocaleDateString()+", "+t.toLocaleTimeString()},v=function(e){var n=t.P(e.replace(p.h,"$1"));if(r.A.enableFormatting){var a=(e,t)=>"&#"+t.charCodeAt(0)+";";n=n.replace(p.L,"`").replace(p.g,(e,t,n)=>"<code class='block'>"+n.replace(p.M,a)+"</code>").replace(p.p,(e,t,n)=>"<code class='inline'>"+n.replace(p.M,a)+"</code>").replace(p.C,a).replace(p.j,e=>e.replace(/\\/g,"").replace(/(.)/g,a)).replace(p.i,"<b>$1</b>").replace(p.s,(e,t,n)=>"\\"===t?e:(t||"")+"<i>"+n+"</i>").replace(p.o,"<u>$1</u>").replace(p.l,"<s>$1</s>")}var i=r.A.enableAnimatedEmoji?"gif":"png";return"<p>"+(n=n.replace(p.v,"<a href='$1' target='_blank' rel='noreferrer'>$1</a>").replace(p.T,(e,t)=>"<span class='link mention-chat'>#"+r.O(t)+"</span>").replace(p.k,(e,t)=>"<span class='link mention-user' title='#"+(r.F(t)||"????")+"'>@"+r.I(t)+"</span>").replace(p.R,"<img src='https://cdn.discordapp.com/emojis/$2.png' alt=':$1:' title=':$1:' class='emoji'>").replace(p.S,"<img src='https://cdn.discordapp.com/emojis/$2."+i+"' alt=':$1:' title=':$1:' class='emoji'>"))+"</p>"};return{N:function(){e=new c(["<div data-channel='{id}'>","<div class='info' title='{topic}'><strong class='name'>#{name}</strong>{nsfw}<span class='tag'>{msgcount}</span></div>","<span class='server'>{server.name} ({server.type})</span>","</div>"].join("")),n=new c(["<div data-channel='{id}'>","<div class='info'><strong class='name'>{name}</strong><span class='tag'>{msgcount}</span></div>","<span class='server'>({server.type})</span>","</div>"].join("")),a=new c(["<div>","<div class='reply-message'>{reply}</div>","<h2><strong class='username' title='#{user.tag}'>{user.name}</strong><span class='info time'>{timestamp}</span>{edit}{jump}</h2>","<div class='message'>{contents}{embeds}{attachments}</div>","<div class='reactions'>{reactions}</div>","</div>"].join("")),i=new c(["<div>","<div class='reply-message reply-message-with-avatar'>{reply}</div>","<div class='avatar-wrapper'>","<div class='avatar'>{avatar}</div>","<div>","<h2><strong class='username' title='#{user.tag}'>{user.name}</strong><span class='info time'>{timestamp}</span>{edit}{jump}</h2>","<div class='message'>{contents}{embeds}{attachments}</div>","<div class='reactions'>{reactions}</div>","</div>","</div>","</div>"].join("")),s=new c(["<img src='https://cdn.discordapp.com/avatars/{id}/{path}.webp?size=128'>"].join("")),o=new c(["<a href='{url}' class='embed thumbnail'><img src='{url}' alt='(image attachment not found)'></a><br>"].join("")),l=new c(["<div class='embed download'><a href='{url}' class='title'>{t}</a><p class='desc'>{d}</p></div>"].join("")),u=new c(["<div class='embed download'><a href='{url}' class='title'>{t}</a></div>"].join("")),d=new c(["<div class='embed download'><p>(Formatted embeds are currently not supported)</p></div>"].join("")),f=new c(["<a href='{url}' class='embed download'>Download {filename}</a>"].join("")),templateReaction=new c(["<span class='reaction-wrapper'><span class='reaction-emoji'>{n}</span><span class='count'>{c}</span></span>"].join("")),templateReactionCustom=new c(["<span class='reaction-wrapper'><img src='https://cdn.discordapp.com/emojis/{id}.{ext}' alt=':{n}:' title=':{n}:' class='reaction-emoji-custom'><span class='count'>{c}</span></span>"].join(""))},B:m,H:function(t){return("SERVER"===t.server.type?e:n).apply(t,(e,t)=>{if("server.type"===e)switch(t){case"SERVER":return"server";case"GROUP":return"group";case"DM":return"user"}else if("nsfw"===e)return t?"<span class='tag'>NSFW</span>":""})},_:function(e){return(r.A.enableUserAvatars?i:a).apply(e,(e,t)=>{if("avatar"===e)return t?s.apply(t):"";if("user.tag"===e)return t||"????";if("timestamp"===e)return g(t);if("contents"===e)return null==t||0===t.length?"":v(t);if("embeds"===e)return t?t.map(e=>{switch(e.type){case"image":return r.A.enableImagePreviews?o.apply(e):"";case"rich":return(e.t?e.d?l:u:d).apply(e)}}).join(""):"";if("attachments"===e)return t?t.map(e=>{if(m(e)&&r.A.enableImagePreviews)return o.apply(e);var t=e.url.split("/");return f.apply({url:e.url,filename:t[t.length-1]})}).join(""):"";if("edit"===e)return t?"<span class='info edited'>Edited"+(t>1?" "+g(t):"")+"</span>":"";if("jump"===e)return r.D?"<span class='info jump' data-jump='"+t+"'>Jump to message</span>":"";if("reply"===e){if(null===t)return"";var n="<span class='reply-username' title='#"+(t.user.tag?t.user.tag:"????")+"'>"+t.user.name+"</span>",a=r.A.enableUserAvatars&&t.avatar?"<span class='reply-avatar'>"+s.apply(t.avatar)+"</span>":"",i=t.contents?"<span class='reply-contents'>"+v(t.contents)+"</span>":"";return"<span class='jump' data-jump='"+t.id+"'>Jump to reply</span><span class='user'>"+a+n+"</span>"+i}if("reactions"===e)return null===t?"":t.map(e=>"id"in e?(e.ext=e.an&&r.A.enableAnimatedEmoji?"gif":"png",templateReactionCustom.apply(e)):templateReaction.apply(e)).join("")})}}}(),t=function(){var e=(e,t)=>{var n=document.createElement(e);t.appendChild(n);return n},t={"&":"&","<":"<",">":">",'"':""","'":"'"},n=/[&<>"']/g;return{id:(e,t)=>(t||document).getElementById(e),$:(e,t)=>Array.prototype.slice.call((t||document).getElementsByClassName(e)),tag:(e,t)=>Array.prototype.slice.call((t||document).getElementsByTagName(e)),J:(e,t)=>(t||document).getElementsByClassName(e)[0],createElement:(t,n)=>e(t,n),V:e=>e.parentNode.removeChild(e),P:e=>String(e).replace(n,e=>t[e]),Z:(t,n)=>{var a=new Blob([n],{type:"octet/stream"});if("msSaveBlob"in window.navigator)return window.navigator.msSaveBlob(a,t);var i=window.URL.createObjectURL(a);var s=e("a",document.body);s.href=i;s.download=t;s.style.display="none";s.click();document.body.removeChild(s);window.URL.revokeObjectURL(i)}}}(),n=function(){var e,n,a=!1,i=function(e,n){var a=new Blob([n],{type:"octet/stream"});if("msSaveBlob"in window.navigator)return window.navigator.msSaveBlob(a,e);var i=window.URL.createObjectURL(a),s=t.createElement("a",document.body);s.href=i,s.download=e,s.style.display="none",s.click(),document.body.removeChild(s),window.URL.revokeObjectURL(i)},s=function(e){return window.btoa(unescape(encodeURIComponent(e)))},r=function(e){return decodeURIComponent(escape(window.atob(e)))};return{N:function(){a=!0,e="<!DOCTYPE html>\n"+document.documentElement.outerHTML,t.id("btn-upload-file").insertAdjacentHTML("afterend",`<button id="btn-embed-file" disabled>Embed File</button>`),t.id("btn-embed-file").addEventListener("click",()=>i("embed.html",n))},q:function(i){a&&(t.id("btn-embed-file").disabled=!1,n=e.replace("</title>",`</title>\n<script type="text/javascript">window.DHT_EMBEDDED = "${s(i)}";<\/script>`).replace(`<${document.body.tagName.toLowerCase()}>`,`<body class="embedded">`))},G:function(){var e=window.DHT_EMBEDDED;return e?r(e):null}}}();document.addEventListener("DOMContentLoaded",()=>{var t=n.G();"?embed"!==location.search||t||n.N();e.N();a.N();a.W(()=>{r.Y(a.K())});r.Y(a.K());a.X(e=>{r.ee(e)});a.ne(e=>{r.ae(e)});r.ie(e=>{a.se(e)});r.oe((e,t)=>{a.ce(e,t,r.le)});r.ue(e=>{a.de(r.fe(),r.pe());a.me(e);a.ge()});var i=function(e,t,a){var i;try{i=JSON.parse(e),n.q(e)}catch(e){return console.error(e),void alert(t)}s.ve(i)?r.he(new s(i)):alert(a)};t?i(t,"Could not parse embedded file, see console for details.","Embedded file has an invalid format."):a.be(e=>{if(1===e.length){var t=e[0],n=new FileReader;r.we(t.name),n.onload=(()=>i(n.result,"Could not parse '"+t.name+"', see console for details.","File '"+t.name+"' has an invalid format.")),n.readAsText(t,"UTF-8")}else alert("Please, select only one file.");return!0})});var a=function(){var n,a,i,s,o=function(){var e=t.J("active",t.id("opt-filter-list"));return e&&""!==e.value?{type:e.getAttribute("data-filter-type"),value:e.value}:null},c=function(){var e=o();t.id("opt-save-filtered").classList.toggle("active",null!=e),i&&i(e)},l=function(e,n){var a=t.id("dialog");return a.innerHTML=n,a.style.width=e+"px",a.style.marginLeft=-e/2+"px",t.id("modal").classList.add("visible"),a},u=function(){l(560,`\r\n<label><input id='dht-cfg-imgpreviews' type='checkbox'> Image Previews</label><br>\r\n<label><input id='dht-cfg-formatting' type='checkbox'> Message Formatting</label><br>\r\n<label><input id='dht-cfg-useravatars' type='checkbox'> User Avatars</label><br>\r\n<label><input id='dht-cfg-animemoji' type='checkbox'> Animated Emoji</label><br>`);var e=function(e,n){var a=t.id(e);a.checked=r.A[n],a.addEventListener("change",()=>r.A[n]=a.checked)};e("dht-cfg-imgpreviews","enableImagePreviews"),e("dht-cfg-formatting","enableFormatting"),e("dht-cfg-useravatars","enableUserAvatars"),e("dht-cfg-animemoji","enableAnimatedEmoji")},d=function(){var e="https://github.com/chylex/Discord-History-Tracker";l(560,`\r\n<p>Discord History Tracker is developed by <a href='https://chylex.com'>chylex</a> as an <a href='${e}/blob/master/LICENSE.md'>open source</a> project.</p>\r\n<sub>v.31, released 3 April 2021</sub>\r\n<p>Please, report any issues and suggestions to the <a href='${e}/issues'>tracker</a>. If you want to support the development, please spread the word and consider <a href='https://www.patreon.com/chylex'>becoming a patron</a> or <a href='https://ko-fi.com/chylex'>buying me a coffee</a>. Any support is appreciated!</p>\r\n<p><a href='${e}/issues'>Issue Tracker</a> — <a href='${e}'>GitHub Repository</a> — <a href='https://twitter.com/chylexmc'>Developer's Twitter</a></p>`)};return{N:function(){var e=t.id("uploaded-file"),i=t.id("opt-messages-filter"),o=t.id("opt-filter-list"),l=function(){i.value="",i.dispatchEvent(new Event("change")),t.id("opt-filter-contents").value="",t.id("opt-save-filtered").classList.remove("active")};t.id("btn-upload-file").addEventListener("click",()=>{e.click()}),e.addEventListener("change",()=>{n&&n(e.files)&&(e.value=null,l())}),i.value="",i.addEventListener("change",()=>{t.$("active",o).forEach(e=>e.classList.remove("active"));i.value&&o.querySelector("[data-filter-type='"+i.value+"']").classList.add("active");c()}),Array.prototype.forEach.call(o.children,e=>{e.addEventListener("SELECT"===e.tagName?"change":"input",e=>c())}),t.id("opt-messages-per-page").addEventListener("change",()=>{a&&a()}),t.id("btn-save-filtered").addEventListener("click",()=>{confirm("Filtering only removes messages, all users and servers will remain in the new archive. Continue?")&&r.ye()}),t.tag("button",t.J("nav")).forEach(e=>{e.disabled=!0;e.addEventListener("click",()=>{s&&s(e.getAttribute("data-nav"))})}),t.id("btn-settings").addEventListener("click",()=>{u()}),t.id("btn-about").addEventListener("click",()=>{d()}),t.id("messages").addEventListener("click",e=>{var n=e.target.getAttribute("data-jump");if(n){l();var a=r.Le(n);t.id("messages").children[a].scrollIntoView()}}),t.id("overlay").addEventListener("click",()=>{t.id("modal").classList.remove("visible");t.id("dialog").innerHTML=""})},be:function(e){n=e},W:function(e){a=e},X:function(e){i=e},ne:function(e){s=e},K:function(){return parseInt(t.id("opt-messages-per-page").value,10)},de:function(e,n){t.id("nav-page-current").innerHTML=e,t.id("nav-page-total").innerHTML=n||"?",t.id("nav-first").disabled=1===e,t.id("nav-prev").disabled=1===e,t.id("nav-pick").disabled=(n||0)<=1,t.id("nav-next").disabled=e===(n||1),t.id("nav-last").disabled=e===(n||1)},ce:function(n,a,i){var s=t.id("channels");if(n){if(null!=o()&&(n=n.filter(e=>e.msgcount>0)),s.innerHTML=n.map(t=>e.H(t)).join(""),Array.prototype.forEach.call(s.children,e=>{e.addEventListener("click",n=>{var a=t.J("active",s);a&&a.classList.remove("active");e.classList.add("active");i(e.getAttribute("data-channel"))})}),a){var r=s.querySelector("[data-channel='"+a+"']");r&&r.classList.add("active")}}else s.innerHTML=""},me:function(n){t.id("messages").innerHTML=n?n.map(t=>e._(t)).join(""):""},se:function(e){for(var n=t.id("opt-filter-user");n.length>1;)n.remove(1);var a=[];for(var i of Object.keys(e)){var s=document.createElement("option");s.value=i,s.text=e[i].name,a.push(s)}a.sort((e,t)=>e.text.toLocaleLowerCase().localeCompare(t.text.toLocaleLowerCase())),a.forEach(e=>n.add(e))},ge:function(){t.id("messages").scrollTop=0}}}(),i={};i.Ee={Ce:e=>t=>t.u===e,je:(e,t)=>n=>n.t>=e&&n.t<=t,Me:e=>t=>-1!==("m"in t?t.m:"").indexOf(e),Ue:e=>t=>e.test("m"in t?t.m:""),ke:()=>t=>t.e&&t.e.some(e=>"image"===e.type)||t.a&&t.a.some(e.B),Te:()=>t=>t.a&&t.a.some(t=>!e.B(t)),Re:()=>e=>e.e&&e.e.length>0,Se:()=>e=>e.a&&e.a.length>0,Pe:()=>e=>"te"in e?e.te:1==(1&e.f)},i.Ae={Oe:(e,t)=>e.length===t.length?e>t?1:e<t?-1:0:e.length>t.length?1:-1,Fe:(e,t)=>e.length===t.length?e>t?-1:e<t?1:0:e.length>t.length?-1:1};class s{constructor(e){var t=this;t.meta=e.meta,t.data=e.data,t.meta.users=t.meta.users||{},t.meta.userindex=t.meta.userindex||[],t.meta.servers=t.meta.servers||[],t.meta.channels=t.meta.channels||{}}static ve(e){return e&&"object"==typeof e.meta&&"object"==typeof e.data}Ie(e){return this.meta.servers[e]||{name:"<unknown>",type:"ERROR"}}xe(){return this.meta.channels}Ne(e){return this.meta.channels[e]||{id:e,name:e}}Be(){return this.meta.users}He(e){return this.meta.users[this.meta.userindex[e]]||{name:"<unknown>"}}_e(e){return this.meta.userindex[e]}De(e){return this.meta.users[e]||{name:e}}$e(e){return this.meta.userindex.indexOf(e)}Je(e){return this.data[e]||{}}Ve(e){var t=JSON.parse(JSON.stringify(this.meta)),n={};for(let r of Object.keys(this.xe())){var a=this.Je(r),i={};for(let t of Object.keys(a)){var s=a[t];e(s)&&(i[t]=s)}Object.keys(i).length>0?n[r]=i:delete t.channels[r]}return JSON.stringify({meta:t,data:n})}}var r=function(){var e,n,a,s,r,o,c,l,u,d,f={},p=function(e){l&&l(f.Ze(),e)},m=function(){u&&u(f.qe())},g=function(){d&&d(f.ze())};f.oe=function(e){l=e},f.ue=function(e){u=e},f.ie=function(e){d=e},f.he=function(t){e=t,n=null,r=null,o=1,g(),p(),m()},f.we=function(e){a=e},f.O=function(t){return e.Ne(t).name},f.I=function(t){return e.De(t).name},f.F=function(t){return e.De(t).tag};var v=function(t){var n=e.Je(t),a=Object.keys(n);return s&&(a=a.filter(e=>s(n[e]))),a};f.Ze=function(){if(!e)return[];var t=e.xe();return Object.keys(t).map(n=>({id:n,name:t[n].name,server:e.Ie(t[n].server),msgcount:v(n).length,topic:t[n].topic||"",nsfw:t[n].nsfw||!1,position:t[n].position||-1})).sort((e,t)=>{var n=e.server;var a=t.server;return n.type.localeCompare(a.type,"en")||n.name.toLocaleLowerCase().localeCompare(a.name.toLocaleLowerCase(),void 0,{Ge:!0})||e.position-t.position||e.name.toLocaleLowerCase().localeCompare(t.name.toLocaleLowerCase(),void 0,{Ge:!0})})},f.le=function(e){o=1,r=e,n=v(e).sort(i.Ae.Oe),m()},f.We=function(){return r},f.qe=function(){if(!n)return[];var t=e.Je(r),a=c*(f.fe()-1);return n.slice(a,c?a+c:void 0).map(n=>{var a=t[n];var i=e.He(a.u);var s=i.avatar?{id:e._e(a.u),path:i.avatar}:null;var r="r"in a&&a.r in t?t[a.r]:null;var o=r?e.He(r.u):null;var c=o&&o.avatar?{id:e._e(r.u),path:o.avatar}:null;var l=r?{id:a.r,user:o,avatar:c,contents:r.m}:null;return{user:i,avatar:s,timestamp:a.t,contents:"m"in a?a.m:null,embeds:a.e,attachments:a.a,edit:"te"in a?a.te:1==(1&a.f),jump:n,reply:l,reactions:"re"in a?a.re:null}})},f.Le=function(e){if(!n)return 0;var t=n.indexOf(e);return-1==t?0:(o=Math.max(1,Math.min(f.pe(),1+Math.floor(t/c))),m(),t%c)},f.D=!1,f.ee=function(t){switch(t?t.type:""){case"user":s=i.Ee.Ce(e.$e(t.value));break;case"contents":s=i.Ee.Me(t.value);break;case"withimages":s=i.Ee.ke();break;case"withdownloads":s=i.Ee.Te();break;case"edited":s=i.Ee.Pe();break;default:s=null}f.D=null!=s,p(r),r&&f.le(r)},f.ye=function(){var n="dht-filtered.txt";a&&(n=a.includes("filtered")?a:a.replace(".","-filtered.")),t.Z(n,e.Ve(s))},f.ze=function(){return e?e.Be():[]},f.Y=function(e){c=e,m()},f.ae=function(e){switch(e){case"first":o=1;break;case"prev":o=Math.max(1,o-1);break;case"next":o=Math.min(f.pe(),o+1);break;case"last":o=f.pe();break;case"pick":var t=parseInt(prompt("Select page:",o),10);if(!t&&0!==t)return;o=Math.max(1,Math.min(f.pe(),t))}m()},f.fe=function(){var e=f.pe();return o>e&&e>0&&(o=e),o||1},f.pe=function(){return n?c?Math.ceil(n.length/c):1:0},f.A={};var h=e=>{try{return localStorage.getItem(e)}catch(e){return console.error(e),null}},b=(e,t)=>{try{localStorage.setItem(e,t)}catch(e){console.error(e)}},w=(e,t,n)=>{var a="_"+e;Object.defineProperty(f.A,e,{get:()=>f.A[a],set:t=>{f.A[a]=t;m();b(e,t)}});var i=h(e);null!==i&&(i=n(i));f.A[a]=null===i?t:i},y=e=>{if("true"===e)return!0;if("false"===e)return!1;return null};return w("enableImagePreviews",!0,y),w("enableFormatting",!0,y),w("enableUserAvatars",!0,y),w("enableAnimatedEmoji",!0,y),f}(),o=/{([^{}]+?)}/g;class c{constructor(e){this.contents=e}apply(e,n){return this.contents.replace(o,(a,i)=>{var s=i.split(".").reduce((e,t)=>e[t],e);if(n){var r=n(i,s);return void 0===r?t.P(s):r}return t.P(s)})}} </script>
|
|
<style type="text/css">
|
|
#channels {width:15vw;min-width:215px;max-width:300px;overflow-y:auto;background-color:#1C1E22}
|
|
#channels > div {cursor:pointer;padding:10px 12px;color:#eee;font-size:15px;border-bottom:1px solid #333333}
|
|
#channels > div:hover, #channels > div.active {background-color:#282B30}
|
|
#channels .info {display:flex;height:16px;margin-bottom:4px}
|
|
#channels .name {flex-grow:1;text-overflow:ellipsis;white-space:nowrap;overflow:hidden}
|
|
#channels .tag {flex-shrink:1;background-color:rgba(255,255,255,0.08);border-radius:4px;margin-left:4px;margin-top:1px;padding:2px 5px;font-size:11px}
|
|
body {font-family:Whitney, "Helvetica Neue", Helvetica, Verdana, "Lucida Grande", sans-serif;line-height:1;margin:0;padding:0;overflow:hidden}
|
|
body.embedded .hide-embedded {display:none}
|
|
#menu {width:100%;height:48px;display:flex;flex-direction:row}
|
|
#app {height:calc(100vh - 48px);display:flex;flex-direction:row}
|
|
#menu {background-color:#17181C;border-bottom:1px dotted #5D626B}
|
|
#menu .splitter {width:1px;margin:9px 4px;background-color:#5D626B}
|
|
#menu .separator {flex:1 1 0}
|
|
#menu :disabled {background-color:#555;cursor:default}
|
|
#menu button, #menu select, #menu input[type="text"] {margin:8px;background-color:#7289DA;color:#FFF;text-shadow:1px 1px 2px rgba(0,0,0,0.75)}
|
|
#menu button {font-size:17px;padding:0 12px;border:0;cursor:pointer}
|
|
#menu select {font-size:14px;padding:6px;border:0;cursor:pointer}
|
|
#menu input[type="text"] {font-size:14px;padding:7px 12px;border:0}
|
|
#menu .nav {display:flex;flex-direction:row;margin:0 8px}
|
|
#menu .nav > button {font-size:14px}
|
|
#menu .nav > button.icon {font-family:Lucida Console, monospace;font-size:17px;padding:0 8px}
|
|
#menu .nav > button, #menu .nav > p {margin:8px 1px}
|
|
#opt-filter-list > select, #opt-filter-list > input {display:none}
|
|
#opt-filter-list > .active {display:block}
|
|
#opt-save-filtered {display:flex}
|
|
#opt-save-filtered:not(.active) {display:none}
|
|
#messages {flex:1 1 0;overflow-y:auto;background-color:#36393E}
|
|
#messages > div {margin:0 24px;padding:4px 0 12px;border-bottom:1px solid rgba(255,255,255,0.04)}
|
|
#messages h2 {margin:0;padding:0;display:block}
|
|
#messages .avatar-wrapper {display:flex;flex-direction:row;align-items:flex-start;align-content:flex-start}
|
|
#messages .avatar-wrapper > div {flex:1 1 auto}
|
|
#messages .avatar {flex:0 0 38px!important;margin:8px 14px 0 0}
|
|
#messages .avatar img {width:38px;border-radius:50%}
|
|
#messages .username {color:#FFF;font-size:15px;font-weight:600;margin-right:3px;letter-spacing:0}
|
|
#messages .info {color:rgba(255,255,255,0.4);font-size:12px;font-weight:500;letter-spacing:0}
|
|
#messages .info::before {content:"\2022";text-align:center;display:inline-block;width:14px}
|
|
#messages .jump {cursor:pointer;text-decoration:underline;text-underline-offset:2px}
|
|
.message {margin-top:6px;color:rgba(255,255,255,0.7);font-size:15px;line-height:1.1em;white-space:pre-wrap;word-wrap:break-word}
|
|
.message .link, .reply-message .link {color:#7289DA;background-color:rgba(115,139,215,0.1)}
|
|
.message a, .reply-message a {color:#0096CF;text-decoration:none}
|
|
.message a:hover {text-decoration:underline}
|
|
.message p {margin:0}
|
|
.message .embed {display:inline-block;margin-top:8px}
|
|
.message .embed .title {font-weight:bold;display:inline-block}
|
|
.message .embed .desc {margin-top:4px}
|
|
.message .thumbnail {max-width:calc(100% - 20px);max-height:320px}
|
|
.message .thumbnail img {max-width:100%;max-height:320px;border-radius:3px}
|
|
.message .download {margin-right:8px;padding:8px 9px;border:1px solid rgba(255,255,255,0.5);border-radius:3px}
|
|
.message .embed:first-child, .message .download + .download {margin-top:0}
|
|
.message code {background-color:#2E3136;border-radius:5px;font-family:Menlo, Consolas, Monaco, monospace;font-size:14px}
|
|
.message code.inline {display:inline;padding:2px}
|
|
.message code.block {display:block;border:2px solid #282B30;margin-top:6px;padding:7px}
|
|
.message .emoji {width:22px;height:22px;margin:0 1px;vertical-align:-30%;object-fit:contain}
|
|
.reply-message {display:flex;align-items:baseline;flex-wrap:wrap;line-height:120%;white-space:nowrap}
|
|
.reply-message-with-avatar {margin:0 0 -2px 52px}
|
|
.reply-message .jump {color:rgba(255,255,255,0.4);font-size:12px;text-underline-offset:1px;margin-right:7px}
|
|
.reply-message .emoji {width:16px;height:16px;vertical-align:-20%;object-fit:contain}
|
|
.reply-message .user {margin-right:5px}
|
|
.reply-avatar {margin-right:4px}
|
|
.reply-avatar img {width:16px;border-radius:50%;vertical-align:middle}
|
|
.reply-username {color:#FFF;font-size:12px;font-weight:600;letter-spacing:0}
|
|
.reply-contents {display:inline-block;color:rgba(255,255,255,0.7);font-size:12px;max-width:calc(80%)}
|
|
.reply-contents p {margin:0;overflow:hidden;text-overflow:ellipsis}
|
|
.reply-contents code {background-color:#2E3136;font-family:Menlo, Consolas, Monaco, monospace;padding:1px 2px}
|
|
.reactions {margin-top:4px}
|
|
.reactions .reaction-wrapper {display:inline-block;border-radius:4px;margin:3px 2px 0 0;padding:3px 6px;background:#42454a;cursor:default}
|
|
.reactions .reaction-emoji {margin-right:5px;font-size:16px;display:inline-block;text-align:center;vertical-align:-5%}
|
|
.reactions .reaction-emoji-custom {height:15px;margin-right:5px;vertical-align:-10%}
|
|
.reactions .count {color:rgba(255,255,255,0.45);font-size:14px}
|
|
#modal div {position:absolute;display:none}
|
|
#modal.visible div {display:block}
|
|
#modal #overlay {left:0;top:0;width:100%;height:100%;background-color:#000}
|
|
#modal.visible #overlay {opacity:0.5}
|
|
#dialog {left:50%;top:50%;padding:16px;background-color:#fff;transform:translateY(-50%)}
|
|
#dialog p {line-height:1.2}
|
|
#dialog p:first-child, #dialog p:last-child {margin-top:1px;margin-bottom:1px}
|
|
#dialog sub {color:#999;font-size:12px}
|
|
#dialog a {color:#0096CF;text-decoration:none}
|
|
#dialog a:hover {text-decoration:underline}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<div id="menu">
|
|
<input id="uploaded-file" type="file" style="display:none">
|
|
<button id="btn-upload-file" class="hide-embedded">Load File</button>
|
|
|
|
<div class="splitter hide-embedded"></div>
|
|
|
|
<button id="btn-settings">Settings</button>
|
|
|
|
<div> <!-- needed to stop the select from messing up -->
|
|
<select id="opt-messages-per-page">
|
|
<option value="50">50 messages per page </option>
|
|
<option value="100">100 messages per page </option>
|
|
<option value="250">250 messages per page </option>
|
|
<option value="500">500 messages per page </option>
|
|
<option value="1000">1000 messages per page </option>
|
|
<option value="0">All messages </option>
|
|
</select>
|
|
</div>
|
|
|
|
<div class="nav">
|
|
<button id="nav-first" data-nav="first" class="icon">«</button>
|
|
<button id="nav-prev" data-nav="prev" class="icon">‹</button>
|
|
<button id="nav-pick" data-nav="pick">Page <span id="nav-page-current">1</span>/<span id="nav-page-total">?</span></button>
|
|
<button id="nav-next" data-nav="next" class="icon">›</button>
|
|
<button id="nav-last" data-nav="last" class="icon">»</button>
|
|
</div>
|
|
|
|
<div class="splitter"></div>
|
|
|
|
<div> <!-- needed to stop the select from messing up -->
|
|
<select id="opt-messages-filter">
|
|
<option value="">No filter </option>
|
|
<option value="user">Filter messages by user </option>
|
|
<option value="contents">Filter messages by contents </option>
|
|
<option value="withimages">Only messages with images </option>
|
|
<option value="withdownloads">Only messages with downloads </option>
|
|
<option value="edited">Only edited messages </option>
|
|
</select>
|
|
</div>
|
|
|
|
<div id="opt-filter-list">
|
|
<select id="opt-filter-user" data-filter-type="user">
|
|
<option value="">Select user...</option>
|
|
</select>
|
|
<input id="opt-filter-contents" type="text" data-filter-type="contents" placeholder="Messages containing...">
|
|
<input type="hidden" data-filter-type="withimages" value="1">
|
|
<input type="hidden" data-filter-type="withdownloads" value="1">
|
|
<input type="hidden" data-filter-type="edited" value="1">
|
|
</div>
|
|
|
|
<div id="opt-save-filtered">
|
|
<div class="splitter"></div>
|
|
<button id="btn-save-filtered">Save Filtered Messages</button>
|
|
</div>
|
|
|
|
<div class="separator"></div>
|
|
|
|
<button id="btn-about">About</button>
|
|
</div>
|
|
|
|
<div id="app">
|
|
<div id="channels"></div>
|
|
<div id="messages"></div>
|
|
</div>
|
|
|
|
<div id="modal">
|
|
<div id="overlay"></div>
|
|
<div id="dialog"></div>
|
|
</div>
|
|
</body>
|
|
</html>
|