From 6998d40d8fa21eeea76991503be9563bce00eb40 Mon Sep 17 00:00:00 2001 From: 3r1s_s <127928354+3r1s-s@users.noreply.github.com> Date: Sun, 4 Aug 2024 23:29:18 -0700 Subject: [PATCH] BIG UPDATE Optimistic posting is back, new tooltips, post drafts, lots of bug fixes, more tweaks to improve load times, dynamic text sizes, non-binary theme, more language things. Co-authored-by: Tnix --- emoji.js | 2 +- glass.css | 20 +- lang.js | 40 +- markdown.js | 31 +- profile/script.js | 8 +- script.js | 901 +++++++++++++++++++--------------------------- share/script.js | 2 +- styles.css | 174 ++++++--- themes.css | 13 +- 9 files changed, 584 insertions(+), 607 deletions(-) diff --git a/emoji.js b/emoji.js index ffc9da9..d655d6f 100644 --- a/emoji.js +++ b/emoji.js @@ -1874,7 +1874,7 @@ function groupcat() { pageContainer.innerHTML = `

GROUP CAT ATTICU EDITION

- +
MEOW MEOW diff --git a/glass.css b/glass.css index 208e91b..0d32e7d 100644 --- a/glass.css +++ b/glass.css @@ -190,6 +190,18 @@ mask-image: linear-gradient(to bottom, rgba(0, 0, 0, .25) 0%, rgba(0, 0, 0, 0) 100%); } +.nonb-theme #page::after { + content: ''; + position: fixed; + top: 0; + z-index: -1; + width: 100%; + height: var(--grad-height); + background: linear-gradient(90deg, rgb(252, 244, 52) 0%, rgb(255, 255, 255) 50%, rgb(156, 89, 209) 100%); + -webkit-mask-image: linear-gradient(to bottom, rgba(0, 0, 0, .25) 0%, rgba(0, 0, 0, 0) 100%); + mask-image: linear-gradient(to bottom, rgba(0, 0, 0, .25) 0%, rgba(0, 0, 0, 0) 100%); +} + .theme-button.trans-theme { background: linear-gradient(90deg, rgb(27, 111, 133) 0%, rgb(138, 82, 93) 25%, rgb(113, 113, 113) 50%, rgb(138, 82, 93) 75%, rgb(27, 111, 133) 100%); background-size: cover; @@ -200,8 +212,14 @@ background-size: cover; } +.theme-button.nonb-theme { + background: linear-gradient(90deg, rgb(198, 192, 40) 0%, rgb(166, 166, 166) 50%, rgb(121, 68, 162) 100%); + background-size: cover; +} + .pride-theme .settings > h1, -.trans-theme .settings > h1 +.trans-theme .settings > h1, +.nonb-theme .settings > h1 { background: transparent; position: static; diff --git a/lang.js b/lang.js index 493d1a8..dacb07c 100644 --- a/lang.js +++ b/lang.js @@ -66,7 +66,7 @@ function setlang(lang) { const en = { "reh": "English, US", // future reference for people adding languages disregard the reh "language": "English, US", // Replace this with that the language is called in that language (ie: "EspaƱol" instead of "Spanish") - "page_home": "Home", + "page_home": "Home", // To update a language easier I suggest looking at the diff between en and the language you're editing (sorry I don't have a better solution) "page_start": "Start", "page_explore": "Explore", "page_inbox": "Inbox", @@ -217,11 +217,15 @@ const en = { "favorite": "Favorite", "download": "Download", "add": "Add", - "adduser": "Add Member", // update - "transfer": "Transfer Ownership", // update - "bug": "Report Bug", // update - "datarequest": "Request Data", // update - "discuss": "Discuss", // update + "adduser": "Add Member", + "transfer": "Transfer Ownership", + "bug": "Report Bug", + "datarequest": "Request Data", + "discuss": "Discuss", + "ping": "Ping", + "moddel": "Mod Delete", + "modpost": "Moderate Post", + "message": "Message", }, "info": { "accexists": "Username Already Taken!", @@ -1851,6 +1855,10 @@ const owo = { "bug": "Wepowt Bug~", // update "datarequest": "Wequest Data~", // update "discuss": "Discuss~", // update + "ping": "Pwing", + "moddel": "Mod Dewete", + "modpost": "Mod Powost", + "message": "Message~ >.<", }, "info": { "accexists": "Usename Awweady Taken! >w<", @@ -2072,11 +2080,15 @@ const eris = { "favorite": "favourite", "download": "download", "add": "add", - "adduser": "add someone (mistake)", // update - "transfer": "make someone else owner (mistake)", // update - "bug": "i found a problem", // update - "datarequest": "i love collecting infomation", // update - "discuss": "discuss", // update + "adduser": "add someone (mistake)", + "transfer": "make someone else owner (mistake)", + "bug": "i found a problem", + "datarequest": "i love collecting infomation", + "discuss": "discuss", + "ping": "@everyone", + "moddel": "banish post", + "modpost": "banish", + "message": "annoy", }, "info": { "accexists": "someone already sniped that one", @@ -2139,7 +2151,7 @@ const eris = { "profilecolor": "colour", "profilepic": "pfp", }, - "chats": { // update + "chats": { "owner": "owner", "members": "members" } @@ -2303,6 +2315,10 @@ const goobert = { "bug": "goobert", "datarequest": "goobert", "discuss": "goobert", + "ping": "goobert", + "moddel": "goobert", + "modpost": "goobert", + "message": "goobert", }, "info": { "accexists": "goobert", diff --git a/markdown.js b/markdown.js index b5e5c0e..adeef15 100644 --- a/markdown.js +++ b/markdown.js @@ -49,7 +49,7 @@ function erimd(content) { function meowerEmojis(content, emojis) { for (const emoji of emojis) { - content = content.replaceAll(`<:${emoji._id}>`, `${emoji.name}`); + content = content.replaceAll(`<:${emoji._id}>`, `
${emoji.name}
`); } return content; } @@ -59,6 +59,8 @@ function loadinputs() { setTop() let textin + pendingAttachments = []; + textin = ` ` @@ -186,7 +188,7 @@ function attach(attachment) { let embeddedElement; - if (attachment.mime.includes("image")) { + if (attachment.mime.includes("image/") && attachment.size < (10 << 20)) { if (whitelist.some(source => link.includes(source))) { const element = document.createElement("div"); element.classList.add("image-outer"); @@ -204,7 +206,7 @@ function attach(attachment) { element.appendChild(imgElement); embeddedElement = element; } - } else if (attachment.mime.includes("video")) { + } else if (attachment.mime.includes("video/")) { const element = document.createElement("div"); element.classList.add("media-outer"); @@ -219,7 +221,7 @@ function attach(attachment) { element.appendChild(mediaElement); embeddedElement = element; - } else if (attachment.mime.includes("audio")) { + } else if (attachment.mime.includes("audio/")) { const element = document.createElement("div"); element.classList.add("media-outer"); @@ -390,28 +392,30 @@ function createButtonContainer(p) { } buttonContainer.innerHTML = `
-
+
-
+ ${p.post_origin !== 'inbox' ? `
-
+
-
+
-
+
` : ''}
`; let nwbtn - if (p.u === localStorage.getItem("username")) { + if (p.u === localStorage.getItem("username") && p.post_origin !== "inbox") { nwbtn = document.createElement("div"); nwbtn.classList.add("toolButton"); nwbtn.setAttribute("onclick", `editPost('${p.post_origin}', '${p._id}')`); nwbtn.setAttribute("title", `edit`); nwbtn.setAttribute("aria-label", `edit post`); nwbtn.setAttribute("tabindex", "0"); + nwbtn.classList.add("tooltip"); + nwbtn.setAttribute("data-tooltip", `${lang().action.edit}`); nwbtn.innerHTML = ` `; @@ -421,6 +425,9 @@ function createButtonContainer(p) { nwbtn.setAttribute("onclick", `deletePost("${p._id}")`); nwbtn.setAttribute("title", `delete`); nwbtn.setAttribute("aria-label", `delete post`); + nwbtn.setAttribute("tabindex", "0"); + nwbtn.classList.add("tooltip"); + nwbtn.setAttribute("data-tooltip", `${lang().action.delete}`); nwbtn.innerHTML = ` `; @@ -432,6 +439,8 @@ function createButtonContainer(p) { nwbtn.setAttribute("title", `mod delete`); nwbtn.setAttribute("aria-label", `mod delete`); nwbtn.setAttribute("tabindex", "0"); + nwbtn.classList.add("tooltip"); + nwbtn.setAttribute("data-tooltip", `${lang().action.moddel}`); nwbtn.innerHTML = ` `; @@ -445,6 +454,8 @@ function createButtonContainer(p) { nwbtn.setAttribute("title", `moderate`); nwbtn.setAttribute("aria-label", `moderate post`); nwbtn.setAttribute("tabindex", "0"); + nwbtn.classList.add("tooltip"); + nwbtn.setAttribute("data-tooltip", `${lang().action.modpost}`); nwbtn.innerHTML = ` `; diff --git a/profile/script.js b/profile/script.js index e5ea29e..4088a60 100644 --- a/profile/script.js +++ b/profile/script.js @@ -1,3 +1,5 @@ +let meourl = 'https://eris.pages.dev/meo' + function fetchprofile() { const urlParams = new URLSearchParams(window.location.search); const username = urlParams.get('u'); @@ -56,7 +58,7 @@ This message was created by meo. if (data._id === localStorage.getItem('username')) { profilecont.innerHTML += `
-

${data._id}

+

${data._id}


` @@ -76,7 +78,7 @@ This message was created by meo. if (localStorage.getItem('permissions') === "1") { profilecont.innerHTML += `
-

${data._id}

+

${data._id}

@@ -89,7 +91,7 @@ This message was created by meo. } else { profilecont.innerHTML += `
-

${data._id}

+

${data._id}

diff --git a/script.js b/script.js index 5a097c6..08ed16b 100644 --- a/script.js +++ b/script.js @@ -9,7 +9,6 @@ // Discord mode where posts are on the bottom // Notification managment // Custom video and audio player, similar style as the file download preview -// Add tooltips to icon buttons, emojis, and maybe some other things // make @Tnix have tnix colour ect // Plugins options and API @@ -37,7 +36,7 @@ let ipBlocked = false; let openprofile = false; const communityDiscordLink = "https://discord.com/invite/THgK9CgyYJ"; -const server = "wss://server.meower.org/"; +const server = "wss://server.meower.org/?v=1"; const pfpCache = {}; const postCache = { livechat: [] }; // {chatId: [post, post, ...]} (up to 25 posts for inactive chats) @@ -163,43 +162,50 @@ function main() { Notification.requestPermission(); } } - + + meowerConnection.onopen = () => { + if (localStorage.getItem("token") != undefined && localStorage.getItem("username") != undefined) { + meowerConnection.send(JSON.stringify({ + cmd: "authpswd", + val: { + username: localStorage.getItem("username"), + pswd: localStorage.getItem("token"), + }, + listener: "auth", + })); + } else { + loadLogin(); + }; + }; + meowerConnection.onmessage = (event) => { console.log("INC: " + event.data); const sentdata = JSON.parse(event.data); let data - if (sentdata.val == "I:112 | Trusted Access enabled") { - if (localStorage.getItem("token") != undefined && localStorage.getItem("username") != undefined) { - meowerConnection.send(JSON.stringify({ - cmd: "authpswd", - val: { - username: localStorage.getItem("username"), - pswd: localStorage.getItem("token"), - }, - listener: "auth", - })); - } else { - loadLogin(); - }; - } else if (sentdata.listener == "auth") { - if (sentdata.val.mode && sentdata.val.mode == "auth") { - sentdata.val.payload.relationships.forEach((relationship) => { + if (sentdata.listener === "auth") { + if (sentdata.cmd === "auth") { + sentdata.val.relationships.forEach((relationship) => { if (relationship.state === 2) { blockedUsers[relationship.username] = true; } }); - localStorage.setItem("username", sentdata.val.payload.username); - localStorage.setItem("token", sentdata.val.payload.token); - localStorage.setItem("permissions", sentdata.val.payload.account.permissions); - favoritedChats = sentdata.val.payload.account.favorited_chats; + sentdata.val.chats.forEach((chat) => { + chatCache[chat._id] = chat; + }); + localStorage.setItem("username", sentdata.val.username); + localStorage.setItem("token", sentdata.val.token); + localStorage.setItem("permissions", sentdata.val.account.permissions); + favoritedChats = sentdata.val.account.favorited_chats; loggedin = true; + loadPfp(sentdata.val.username, sentdata.val.account); sidebars(); + renderChats(); // work on this if (pre !== "") { if (pre === "home") { - loadhome(); + loadchat('home'); } else if (pre === "explore") { loadexplore(); } else if (pre === "start") { @@ -222,48 +228,33 @@ function main() { console.error(`Failed logging in to Cloudlink: ${sentdata.val}`); logout(false); } - } else if (loggedin && sentdata.val.post_origin) { - let postOrigin = sentdata.val.post_origin; - if (postCache[postOrigin]) { - postCache[postOrigin].push(sentdata.val); - if (page === postOrigin) { - loadpost(sentdata.val); - } else if (postCache[postOrigin].length >= 24) { - postCache[postOrigin].shift(); - } - } - if (settingsstuff().notifications) { - if (page !== sentdata.val.post_origin || document.hidden) { - notify(sentdata.val.u, sentdata.val.p, sentdata.val.post_origin, sentdata.val); - } - } - } else if (sentdata.val.mode === "inbox_message") { - let post = sentdata.val.payload; - if (postCache["inbox"]) { - postCache["inbox"].push(post); - if (page === "inbox") { - loadpost(post); - } else if (postCache["inbox"].length >= 24) { - postCache["inbox"].shift(); - } + } else if (sentdata.cmd === "post" || sentdata.cmd === "inbox_message") { + let post = sentdata.val; + let postOrigin = post.post_origin; + if (!(postOrigin in postCache)) postCache[postOrigin] = []; + postCache[postOrigin].unshift(post); + if (page === postOrigin) { + loadpost(Object.assign(structuredClone(post), { _top: true })); + } else { + if (postCache[postOrigin].length > 25) postCache[postOrigin].length = 25; } if (settingsstuff().notifications) { - if (page !== "inbox" || document.hidden) { - notify(post.u === "Server" ? "Announcement" : "Notification", post.p, "inbox", post); + if (page !== postOrigin || document.hidden) { + notify(postOrigin === "inbox" ? "Inbox Message" : post.u, post.p, postOrigin, post); } } } else if (end) { return 0; - } else if (sentdata.val.mode == "update_config") { - if (sentdata.val.payload.favorited_chats) { - favoritedChats = sentdata.val.payload.favorited_chats; + } else if (sentdata.cmd == "update_config") { + if (sentdata.val.favorited_chats) { + favoritedChats = sentdata.val.favorited_chats; renderChats(); } - } else if (sentdata.val.mode == "update_profile") { - let username = sentdata.val.payload._id; + } else if (sentdata.cmd == "update_profile") { + let username = sentdata.val._id; if (pfpCache[username]) { delete pfpCache[username]; - loadPfp(username, 0) + loadPfp(username, null, 0) .then(pfpElement => { if (pfpElement) { pfpCache[username] = pfpElement.cloneNode(true); @@ -274,52 +265,85 @@ function main() { } }); } - } else if (sentdata.val.mode == "update_post") { - let postOrigin = sentdata.val.payload.post_origin; + } else if (sentdata.cmd == "update_post") { + let postOrigin = sentdata.val.post_origin; if (postCache[postOrigin]) { - index = postCache[postOrigin].findIndex(post => post._id === sentdata.val.payload._id); + index = postCache[postOrigin].findIndex(post => post._id === sentdata.val._id); if (index !== -1) { postCache[postOrigin][index] = Object.assign( postCache[postOrigin][index], - sentdata.val.payload + sentdata.val ); } } - if (document.getElementById(sentdata.val.payload.post_id)) { - loadpost(sentdata.val.payload); + if (document.getElementById(sentdata.val.post_id)) { + loadpost(sentdata.val); + } + } else if (sentdata.cmd === "delete_post") { + if (sentdata.val.chat_id in postCache) { + const index = postCache[sentdata.val.chat_id].findIndex(post => post._id === sentdata.val.post_id); + if (index !== -1) { + postCache[sentdata.val.chat_id].splice(index, 1); + } } - } else if (sentdata.val.mode == "create_chat") { - chatCache[sentdata.val.payload._id] = sentdata.val.payload; + + const divToDelete = document.getElementById(sentdata.val.post_id); + if (divToDelete) { + divToDelete.parentNode.removeChild(divToDelete); + } + + const replies = document.querySelectorAll(`#reply-${sentdata.val.post_id}`); + for (const reply of replies) { + reply.replaceWith(loadreplyv(null)); + } + } else if (sentdata.cmd == "create_chat") { + chatCache[sentdata.val._id] = sentdata.val; renderChats(); - } else if (sentdata.val.mode == "update_chat") { - const chatId = sentdata.val.payload._id; + } else if (sentdata.cmd == "update_chat") { + const chatId = sentdata.val._id; if (chatId in chatCache) { chatCache[chatId] = Object.assign( chatCache[chatId], - sentdata.val.payload + sentdata.val ); renderChats(); } - } else if (sentdata.val.mode == "create_emoji") { - const chatId = sentdata.val.payload.chat_id; + } else if (sentdata.cmd === "delete_chat") { + if (chatCache[sentdata.val.chat_id]) { + delete chatCache[sentdata.val.chat_id]; + } + if (postCache[sentdata.val.chat_id]) { + delete postCache[sentdata.val.chat_id]; + renderChats(); + } + if (page === sentdata.val.chat_id) { + openUpdate(lang().info.chatremoved); + if (!settingsstuff().homepage) { + loadstart(); + } else { + loadchat('home'); + } + } + } else if (sentdata.cmd == "create_emoji") { + const chatId = sentdata.val.chat_id; if (chatId in chatCache) { - chatCache[chatId].emojis.push(sentdata.val.payload); + chatCache[chatId].emojis.push(sentdata.val); } - } else if (sentdata.val.mode == "update_emoji") { - const chatId = sentdata.val.payload.chat_id; + } else if (sentdata.cmd == "update_emoji") { + const chatId = sentdata.val.chat_id; if (chatId in chatCache) { - const emojiI = chatCache[chatId].emojis.findIndex(emoji => emoji._id === sentdata.val.payload._id); + const emojiI = chatCache[chatId].emojis.findIndex(emoji => emoji._id === sentdata.val._id); if (emojiI && emojiI !== -1) { chatCache[chatId].emojis[emojiI] = Object.assign( chatCache[chatId].emojis[emojiI], - sentdata.val.payload, + sentdata.val, ); } } - } else if (sentdata.val.mode == "delete_emoji") { - const chatId = sentdata.val.payload.chat_id; + } else if (sentdata.cmd == "delete_emoji") { + const chatId = sentdata.val.chat_id; if (chatId in chatCache) { - chatCache[chatId].emojis = chatCache[chatId].emojis.filter(emoji => emoji._id !== sentdata.val.payload._id); + chatCache[chatId].emojis = chatCache[chatId].emojis.filter(emoji => emoji._id !== sentdata.val._id); } } else if (sentdata.cmd == "ulist") { const iul = sentdata.val; @@ -336,43 +360,6 @@ function main() { if (page == "home") { document.getElementById("info").innerText = lul + " users online (" + sul + ")"; } - } else if (sentdata.val.mode == "delete") { - console.log("Received delete command for ID:", sentdata.val.id); - - if (chatCache[sentdata.val.id]) { - delete chatCache[sentdata.val.id]; - } - if (postCache[sentdata.val.id]) { - delete postCache[sentdata.val.id]; - } - for (const key in postCache) { - const index = postCache[key].findIndex(post => post._id === sentdata.val.id); - if (index !== -1) { - postCache[key].splice(index, 1); - break; - } - } - - const replies = document.querySelectorAll(`#reply-${sentdata.val.id}`); - for (const reply of replies) { - reply.replaceWith(loadreplyv(null)); - } - - const divToDelete = document.getElementById(sentdata.val.id); - if (divToDelete) { - divToDelete.parentNode.removeChild(divToDelete); - if (page === sentdata.val.id) { - openUpdate(lang().info.chatremoved); - if (!settingsstuff().homepage) { - loadstart(); - } else { - loadhome(); - } - } - console.log(sentdata.val.id, "deleted successfully."); - } else { - console.warn(sentdata.val.id, "not found."); - } } }; document.addEventListener("keydown", function(event) { @@ -427,7 +414,7 @@ function main() { }); addEventListener("DOMContentLoaded", () => { document.onpaste = (event) => { - if (!document.getElementById("msg")) return; + if (!document.getElementById("msg") || page === "livechat") return; for (const file of event.clipboardData.files) { addAttachment(file); } @@ -435,14 +422,13 @@ function main() { const mainEl = document.getElementById("main"); mainEl.addEventListener("scroll", async (event) => { + if (!(page in postCache)) return; const skeletonHeight = document.getElementById("skeleton-msgs").scrollHeight; if (mainEl.scrollHeight - mainEl.scrollTop - skeletonHeight - mainEl.clientHeight < 1) { const msgs = document.getElementById("msgs"); if (msgs.hasAttribute("data-loading-more")) return; msgs.setAttribute("data-loading-more", ""); - const scrollTop = mainEl.scrollTop; - await loadmore(); - mainEl.scrollTop = scrollTop; + await loadposts(Math.floor(msgs.childElementCount / 25) + 1); msgs.removeAttribute("data-loading-more"); } }); @@ -463,7 +449,7 @@ function main() { if (postCache[page]) { event.preventDefault(); - const post = [...postCache[page]].reverse().find(post => post.u === localStorage.getItem("username")); + const post = [...postCache[page]].find(post => post.u === localStorage.getItem("username")); if (post) { editPost(page, post._id); } @@ -515,6 +501,7 @@ function loadLogin() { + @@ -614,22 +601,23 @@ function loadpost(p) { const pfpDiv = document.createElement("div"); pfpDiv.classList.add("pfp"); - wrapperDiv.appendChild(createButtonContainer(p)); - - const mobileButtonContainer = document.createElement("div"); - mobileButtonContainer.classList.add("mobileContainer"); - mobileButtonContainer.innerHTML = ` -
-
- -
-
- + if (p.post_origin !== "livechat") { + postContainer.appendChild(createButtonContainer(p)); + + const mobileButtonContainer = document.createElement("div"); + mobileButtonContainer.classList.add("mobileContainer"); + mobileButtonContainer.innerHTML = ` +
+ ${p.post_origin !== 'inbox' ? `
+ +
` : ''} +
+ +
-
- `; - - wrapperDiv.appendChild(mobileButtonContainer); + `; + postContainer.appendChild(mobileButtonContainer); + } const pstdte = document.createElement("i"); pstdte.classList.add("date"); @@ -735,7 +723,7 @@ function loadpost(p) { postContainer.appendChild(wrapperDiv); - loadPfp(user, 0) + loadPfp(user, p.author, 0) .then(pfpElement => { if (pfpElement) { pfpDiv.appendChild(pfpElement); @@ -744,109 +732,114 @@ function loadpost(p) { } }); + const placeholder = document.getElementById(`placeholder-${p.nonce}`); + if (placeholder) placeholder.remove(); + const pageContainer = document.getElementById("msgs"); const existingPost = document.getElementById(p._id); postContainer.id = p._id; if (existingPost) { existingPost.replaceWith(postContainer); - } else if (pageContainer.firstChild && !p._reverse) { + } else if (pageContainer.firstChild && p._top) { pageContainer.insertBefore(postContainer, pageContainer.firstChild); } else { pageContainer.appendChild(postContainer); } } -function loadPfp(username, button) { - return new Promise((resolve, reject) => { +function loadPfp(username, userData, button) { + return new Promise(async (resolve, reject) => { if (pfpCache[username]) { resolve(pfpCache[username].cloneNode(true)); } else { let pfpElement; - fetch(`https://api.meower.org/users/${username}`) - .then(userResp => userResp.json()) - .then(userData => { - if (userData.avatar) { - const pfpurl = `https://uploads.meower.org/icons/${userData.avatar}`; + if (!userData) { + try { + const resp = await fetch(`https://api.meower.org/users/${username}`); + userData = await resp.json(); + } catch (e) { + console.error("Failed to fetch:", error); + resolve(null); + } + } + + if (userData.avatar) { + const pfpurl = `https://uploads.meower.org/icons/${userData.avatar}`; - - pfpElement = document.createElement("div"); - pfpElement.style.backgroundImage = `url(${pfpurl})`; - pfpElement.classList.add("pfp-inner"); - pfpElement.setAttribute("alt", username); - pfpElement.setAttribute("data-username", username); - pfpElement.classList.add("avatar"); - if (!button) { - pfpElement.setAttribute("onclick", `openUsrModal('${username}')`); - } - - if (userData.avatar_color) { + + pfpElement = document.createElement("div"); + pfpElement.style.backgroundImage = `url(${pfpurl})`; + pfpElement.classList.add("pfp-inner"); + pfpElement.setAttribute("alt", username); + pfpElement.setAttribute("data-username", username); + pfpElement.classList.add("avatar"); + if (!button) { + pfpElement.setAttribute("onclick", `openUsrModal('${username}')`); + } + + if (userData.avatar_color) { // if (userData.avatar_color === "!color") { // pfpElement.style.border = `3px solid #f00`; // pfpElement.style.backgroundColor = `#f00`; // } else { // } - pfpElement.style.border = `3px solid #${userData.avatar_color}`; - pfpElement.style.backgroundColor = `#${userData.avatar_color}`; - } - - pfpElement.addEventListener('error', function pngFallback() { - pfpElement.removeEventListener('error', pngFallback); - pfpElement.setAttribute("src", `${pfpurl}.png`); - pfpCache[username].setAttribute("src", `${pfpurl}.png`); - }); + pfpElement.style.border = `3px solid #${userData.avatar_color}`; + pfpElement.style.backgroundColor = `#${userData.avatar_color}`; + } + + pfpElement.addEventListener('error', function pngFallback() { + pfpElement.removeEventListener('error', pngFallback); + pfpElement.setAttribute("src", `${pfpurl}.png`); + pfpCache[username].setAttribute("src", `${pfpurl}.png`); + }); - } else if (userData.pfp_data) { - let pfpurl; - if (userData.pfp_data > 0 && userData.pfp_data <= 37) { - pfpurl = `images/avatars/icon_${userData.pfp_data - 1}.svg`; - } else { - pfpurl = `images/avatars/icon_err.svg`; - } - - pfpElement = document.createElement("div"); - pfpElement.style.backgroundImage = `url(${pfpurl})`; - pfpElement.classList.add("pfp-inner"); - pfpElement.setAttribute("alt", username); - pfpElement.setAttribute("data-username", username); - pfpElement.classList.add("avatar"); - if (!button) { - pfpElement.setAttribute("onclick", `openUsrModal('${username}')`); - } - pfpElement.classList.add("svg-avatar"); + } else if (userData.pfp_data) { + let pfpurl; + if (userData.pfp_data > 0 && userData.pfp_data <= 37) { + pfpurl = `images/avatars/icon_${userData.pfp_data - 1}.svg`; + } else { + pfpurl = `images/avatars/icon_err.svg`; + } + + pfpElement = document.createElement("div"); + pfpElement.style.backgroundImage = `url(${pfpurl})`; + pfpElement.classList.add("pfp-inner"); + pfpElement.setAttribute("alt", username); + pfpElement.setAttribute("data-username", username); + pfpElement.classList.add("avatar"); + if (!button) { + pfpElement.setAttribute("onclick", `openUsrModal('${username}')`); + } + pfpElement.classList.add("svg-avatar"); - if (userData.avatar_color) { - pfpElement.style.border = `3px solid #${userData.avatar_color}`; - } - - } else { - const pfpurl = `images/avatars/icon_-4.svg`; - - pfpElement = document.createElement("div"); - pfpElement.style.backgroundImage = `url(${pfpurl})`; - pfpElement.classList.add("pfp-inner"); - pfpElement.setAttribute("alt", username); - pfpElement.setAttribute("data-username", username); - if (!button) { - pfpElement.setAttribute("onclick", `openUsrModal('${username}')`); - } - pfpElement.classList.add("avatar"); - pfpElement.classList.add("svg-avatar"); - - pfpElement.style.border = `3px solid #fff`; - pfpElement.style.backgroundColor = `#fff`; - } + if (userData.avatar_color) { + pfpElement.style.border = `3px solid #${userData.avatar_color}`; + } + + } else { + const pfpurl = `images/avatars/icon_-4.svg`; + + pfpElement = document.createElement("div"); + pfpElement.style.backgroundImage = `url(${pfpurl})`; + pfpElement.classList.add("pfp-inner"); + pfpElement.setAttribute("alt", username); + pfpElement.setAttribute("data-username", username); + if (!button) { + pfpElement.setAttribute("onclick", `openUsrModal('${username}')`); + } + pfpElement.classList.add("avatar"); + pfpElement.classList.add("svg-avatar"); + + pfpElement.style.border = `3px solid #fff`; + pfpElement.style.backgroundColor = `#fff`; + } - if (pfpElement) { - pfpCache[username] = pfpElement.cloneNode(true); - } + if (pfpElement) { + pfpCache[username] = pfpElement.cloneNode(true); + } - resolve(pfpElement); - }) - .catch(error => { - console.error("Failed to fetch:", error); - resolve(null); - }); + resolve(pfpElement); } }); } @@ -964,9 +957,15 @@ function loadreplyv(item) { const replycontainer = document.createElement("div"); if (item.author.avatar_color && item.author.avatar_color !== "!color") { - replycontainer.style.setProperty('--reply-accent', `${darkenColour(item.author.avatar_color, 3)}`); - replycontainer.style.setProperty('--reply-border', `${lightenColour(item.author.avatar_color, 3)}`); - replycontainer.style.setProperty('--reply-color', `${lightenColour(item.author.avatar_color, 1.5)}`); + if (getComputedStyle(document.documentElement).getPropertyValue('--color-scheme').trim() === 'light') { + replycontainer.style.setProperty('--reply-accent', `${lightenColour(item.author.avatar_color, 3)}`); + replycontainer.style.setProperty('--reply-border', `${lightenColour(item.author.avatar_color, 5)}`); + replycontainer.style.setProperty('--reply-color', `${darkenColour(item.author.avatar_color, 1.5)}`); + } else { + replycontainer.style.setProperty('--reply-accent', `${darkenColour(item.author.avatar_color, 3)}`); + replycontainer.style.setProperty('--reply-border', `${lightenColour(item.author.avatar_color, 3)}`); + replycontainer.style.setProperty('--reply-color', `${lightenColour(item.author.avatar_color, 1.5)}`); + } replycontainer.classList.add("custom"); } else { replycontainer.style.setProperty('--reply-accent', `var(--accent-down)`); @@ -1002,14 +1001,22 @@ function loadreplyv(item) { } } - replycontainer.innerHTML = `

${escapeHTML(user)}

${content ? escapeHTML(content) : 'Deleted post'}

`; + replycontainer.innerHTML = `

${escapeHTML(user)}

${content ? escapeHTML(content) : 'Deleted post'}

`; const full = document.createElement("div"); full.classList.add("reply-outer"); - full.addEventListener('click', (e) => { + full.addEventListener('click', async (e) => { e.preventDefault(); + const index = postCache[page].findIndex(post => post._id === item._id); + if (index === -1) return; + const desiredPage = Math.floor(index / 25) + 1; + const currentPages = Math.floor(document.getElementById("msgs").childElementCount / 25) + 1; + for (var i = currentPages; i <= desiredPage; i++) { + await loadposts(i); + } + const targetElement = document.getElementById(`${item._id}`); const outer = document.getElementById("main"); targetElement.style.backgroundColor = 'var(--hov-accent-color)'; @@ -1188,6 +1195,7 @@ async function sendpost() { const message = msgbox.value; msgbox.value = ""; autoresize(); + localStorage.removeItem(`draft-${page}`); const editIndicator = document.getElementById("edit-indicator"); @@ -1203,7 +1211,7 @@ async function sendpost() { const old = match[1]; const newtx = match[2]; - const repst = [...postCache[page]].reverse().find(post => post.u === localStorage.getItem("username")); + const repst = [...postCache[page]].find(post => post.u === localStorage.getItem("username")); if (repst) { const newCont = repst.p.replace(new RegExp(old, 'g'), newtx); @@ -1221,22 +1229,6 @@ async function sendpost() { return; } - // Create a placeholder post element - const placeholder = document.createElement("div"); - placeholder.classList.add("post"); - placeholder.style.opacity = "0.5"; - - placeholder.innerHTML = ` -
-
-
- ${localStorage.getItem("username")}sending... -

-

${message}

-

-
- ` - if (editIndicator.hasAttribute("data-postid")) { fetch(`https://api.meower.org/posts?id=${editIndicator.getAttribute("data-postid")}`, { method: "PATCH", @@ -1269,6 +1261,32 @@ async function sendpost() { const replyToIds = Array.from(replies.childNodes).map(replyContainer => replyContainer.getAttribute("data-reply-id")); replies.innerHTML = ""; + // Create post nonce + const nonce = Math.random().toString(); + + // Create a placeholder post element + const placeholder = document.createElement("div"); + placeholder.id = `placeholder-${nonce}`; + placeholder.classList.add("post"); + placeholder.style.opacity = "0.5"; + placeholder.innerHTML = ` +
+
+
+ ${localStorage.getItem("username")}sending... +

+

${message}

+

+
+ `; + loadPfp(localStorage.getItem("username"), null, 0) + .then(pfpElement => { + if (pfpElement) { + placeholder.querySelector(".pfp").appendChild(pfpElement); + } + }); + document.getElementById("msgs").prepend(placeholder); + const response = await fetch(`https://api.meower.org/${page === "home" ? "home" : `posts/${page}`}`, { method: "POST", headers: { @@ -1279,6 +1297,7 @@ async function sendpost() { reply_to: replyToIds, content: message, attachments: attachmentIds.reverse(), + nonce, }) }); } @@ -1287,82 +1306,6 @@ async function sendpost() { closepicker(); } -function loadhome() { - page = "home"; - pre = "home"; - setTop(); - let pageContainer - pageContainer = document.getElementById("main"); - pageContainer.innerHTML = ` -

${lang().page_home}

-
` + loadinputs(); - document.getElementById("info").innerText = lul + " users online (" + sul + ")"; - - sidebars(); - - if (postCache["home"]) { - postCache["home"].forEach(post => { - if (page !== "home") { - return; - } - loadpost(post); - }); - //document.getElementById("skeleton-msgs").style.display = "none"; - } else { - const xhttpPosts = new XMLHttpRequest(); - xhttpPosts.open("GET", "https://api.meower.org/home?autoget"); - xhttpPosts.onload = () => { - const postsData = JSON.parse(xhttpPosts.response); - const postsarray = postsData.autoget || []; - - postsarray.reverse(); - postCache["home"] = postsarray; - postsarray.forEach(post => { - if (page !== "home") { - return; - } - loadpost(post); - }); - //document.getElementById("skeleton-msgs").style.display = "none"; - }; - xhttpPosts.send(); - } - - const attachButton = document.getElementById('attach') - attachButton.addEventListener('dragover', function(e) { - e.preventDefault(); - e.stopPropagation(); - attachButton.classList.add('dragover'); - }); - - attachButton.addEventListener('dragleave', function(e) { - e.preventDefault(); - e.stopPropagation(); - attachButton.classList.remove('dragover'); - }); - - attachButton.addEventListener('drop', function(e) { - e.preventDefault(); - e.stopPropagation(); - attachButton.classList.remove('dragover'); - for (const file of e.dataTransfer.files) { - addAttachment(file); - } - }); - - const jumpButton = document.querySelector('.jump'); - const navbarOffset = document.querySelector('.message-container').offsetHeight; - const main = document.getElementById("main"); - - main.addEventListener('scroll', function() { - if (main.scrollTop > navbarOffset) { - jumpButton.classList.add('visible'); - } else { - jumpButton.classList.remove('visible'); - } - }); -} - function sidebars() { let pageContainer pageContainer = document.getElementById("nav"); @@ -1382,7 +1325,7 @@ function sidebars() { let navlist = ` - +
@@ -1462,13 +1391,13 @@ function renderChats() { `; gcdiv.innerHTML += ` - - - +
@@ -1635,6 +1564,14 @@ function loadstart() { } function opendm(username) { + for (const chat of Object.values(chatCache)) { + if (chat.type === 1 && chat.members.includes(username)) { + parent.loadchat(chat._id); + parent.closemodal(); + return; + } + } + fetch(`https://api.meower.org/users/${username}/dm`, { method: 'GET', headers: { @@ -1660,8 +1597,7 @@ function opendm(username) { function loadchat(chatId) { page = chatId; pre = chatId; - setTop(); - if (!chatCache[chatId]) { + if (!["home", "inbox", "livechat"].includes(chatId) && !chatCache[chatId]) { fetch(`https://api.meower.org/chats/${chatId}`, { headers: {token: localStorage.getItem("token")} }) @@ -1684,7 +1620,7 @@ function loadchat(chatId) { if (!settingsstuff().homepage) { loadstart(); } else { - loadhome(); + loadchat('home'); } }); return; @@ -1695,202 +1631,65 @@ function loadchat(chatId) { const data = chatCache[chatId]; const mainContainer = document.getElementById("main"); - if (data.nickname) { - mainContainer.innerHTML = `

${escapeHTML(data.nickname)}

${chatId}
-

` + loadinputs(); - } else { - mainContainer.innerHTML = `

${data.members.find(v => v !== localStorage.getItem("username"))}

${chatId}

` + loadinputs(); - } - - if (postCache[chatId]) { - postCache[chatId].forEach(post => { - if (page !== chatId) { - return; - } - loadpost(post); - }); - //document.getElementById("skeleton-msgs").style.display = "none"; + if (chatId === "home") { + pageContainer.innerHTML = ` +

${lang().page_home}

+
` + loadinputs(); + document.getElementById("info").innerText = lul + " users online (" + sul + ")"; + } else if (chatId === "inbox") { + mainContainer.innerHTML = `
+

${lang().page_inbox}

+

${lang().inbox_sub.desc}

+
` + loadinputs(); + } else if (chatId === "livechat") { + mainContainer.innerHTML = ` +
+

${lang().title_live}

+

${lang().live_sub.desc}

+
+ ${loadinputs()} + `; } else { - const xhttpPosts = new XMLHttpRequest(); - xhttpPosts.open("GET", `https://api.meower.org/posts/${chatId}?autoget`); - xhttpPosts.setRequestHeader("token", localStorage.getItem('token')); - xhttpPosts.onload = () => { - const postsData = JSON.parse(xhttpPosts.response); - const postsarray = postsData.autoget || []; - - postsarray.reverse(); - postCache[chatId] = postsarray; - postsarray.forEach(post => { - if (page !== chatId) { - return; - } - loadpost(post); - }); - //document.getElementById("skeleton-msgs").style.display = "none"; - }; - xhttpPosts.send(); - } - - const attachButton = document.getElementById('attach') - attachButton.addEventListener('dragover', function(e) { - e.preventDefault(); - e.stopPropagation(); - attachButton.classList.add('dragover'); - }); - - attachButton.addEventListener('dragleave', function(e) { - e.preventDefault(); - e.stopPropagation(); - attachButton.classList.remove('dragover'); - }); - - attachButton.addEventListener('drop', function(e) { - e.preventDefault(); - e.stopPropagation(); - attachButton.classList.remove('dragover'); - for (const file of e.dataTransfer.files) { - addAttachment(file); - } - }); - - const jumpButton = document.querySelector('.jump'); - const navbarOffset = document.querySelector('.message-container').offsetHeight; - const main = document.getElementById("main"); - - main.addEventListener('scroll', function() { - if (main.scrollTop > navbarOffset) { - jumpButton.classList.add('visible'); - } else { - jumpButton.classList.remove('visible'); - } - }); -} - -function loadlive() { - page = 'livechat'; - pre = 'livechat'; - setTop(); - const mainContainer = document.getElementById("main"); - mainContainer.innerHTML = ` -
-

${lang().title_live}

-

${lang().live_sub.desc}

-
- ${loadinputs()} - `; - - document.getElementById("skeleton-msgs").style.display = "none"; - sidebars(); - - if (!postCache["livechat"]) postCache["livechat"] = []; - postCache["livechat"].forEach(post => { - if (page !== "livechat") { - return; - } - loadpost(post); - }); - - const attachButton = document.getElementById('attach') - attachButton.addEventListener('dragover', function(e) { - e.preventDefault(); - e.stopPropagation(); - attachButton.classList.add('dragover'); - }); - - attachButton.addEventListener('dragleave', function(e) { - e.preventDefault(); - e.stopPropagation(); - attachButton.classList.remove('dragover'); - }); - - attachButton.addEventListener('drop', function(e) { - e.preventDefault(); - e.stopPropagation(); - attachButton.classList.remove('dragover'); - for (const file of e.dataTransfer.files) { - addAttachment(file); - } - }); - - const jumpButton = document.querySelector('.jump'); - const navbarOffset = document.querySelector('.message-container').offsetHeight; - const main = document.getElementById("main"); - - main.addEventListener('scroll', function() { - if (main.scrollTop > navbarOffset) { - jumpButton.classList.add('visible'); + if (data.nickname) { + mainContainer.innerHTML = `

${escapeHTML(data.nickname)}

${chatId}
+

` + loadinputs(); } else { - jumpButton.classList.remove('visible'); + mainContainer.innerHTML = `

${data.members.find(v => v !== localStorage.getItem("username"))}

${chatId}

` + loadinputs(); } - }); -} - -function loadinbox() { - page = "inbox" - pre = "inbox" - setTop(); + } - const mainContainer = document.getElementById("main"); - mainContainer.innerHTML = ` -
-

${lang().page_inbox}

-

${lang().inbox_sub.desc}

-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- `; + loadposts(1); - sidebars(); + const attachButton = document.getElementById('attach'); + if (attachButton && chatId !== "livechat") { + attachButton.addEventListener('dragover', function(e) { + e.preventDefault(); + e.stopPropagation(); + attachButton.classList.add('dragover'); + }); - const sidedivs = document.querySelectorAll(".side"); - sidedivs.forEach(sidediv => sidediv.classList.remove("hidden")); + attachButton.addEventListener('dragleave', function(e) { + e.preventDefault(); + e.stopPropagation(); + attachButton.classList.remove('dragover'); + }); - if (postCache["inbox"]) { - postCache["inbox"].forEach(post => { - if (page !== "inbox") { - return; + attachButton.addEventListener('drop', function(e) { + e.preventDefault(); + e.stopPropagation(); + attachButton.classList.remove('dragover'); + for (const file of e.dataTransfer.files) { + addAttachment(file); } - loadpost(post); }); } else { - const xhttpPosts = new XMLHttpRequest(); - xhttpPosts.open("GET", "https://api.meower.org/inbox?autoget"); - xhttpPosts.setRequestHeader("token", localStorage.getItem('token')); - xhttpPosts.onload = () => { - const postsData = JSON.parse(xhttpPosts.response); - const postsarray = postsData.autoget || []; - - postsarray.reverse(); - postCache["inbox"] = postsarray; - postsarray.forEach(post => { - if (page !== "inbox") { - return; - } - loadpost(post); - }); - }; - xhttpPosts.send(); + if (attachButton) attachButton.remove(); } + const messageContainer = document.querySelector('.message-container'); const jumpButton = document.querySelector('.jump'); - const navbarOffset = document.querySelector('.message-container').offsetHeight; + const navbarOffset = messageContainer.offsetHeight; const main = document.getElementById("main"); - main.addEventListener('scroll', function() { if (main.scrollTop > navbarOffset) { jumpButton.classList.add('visible'); @@ -1898,30 +1697,58 @@ function loadinbox() { jumpButton.classList.remove('visible'); } }); + + if (chatId === "inbox") { + messageContainer.innerHTML = ""; + } else { + const msg = messageContainer.querySelector("#msg"); + msg.value = localStorage.getItem(`draft-${chatId}`) || ""; + autoresize(); + msg.addEventListener("change", () => { + localStorage.setItem(`draft-${chatId}`, msg.value); + }); + } } -async function loadmore() { +async function loadposts(pageNo) { + // Set up cache const chatId = page.valueOf(); - if (!postCache[chatId]) return; + if (!(chatId in postCache)) postCache[chatId] = []; + + // Fetch from cache + const cacheSkip = (pageNo-1) * 25; + const cachedPosts = postCache[chatId].slice(cacheSkip, (cacheSkip+25)+1); + for (const post of cachedPosts) { + loadpost(post); + } + if (cachedPosts.length >= 25 || chatId === "livechat") { + document.getElementById("skeleton-msgs").style.display = "none"; + return; + } + // Get path var path; if (chatId === "home") path = "/home" else if (chatId === "inbox") path = "/inbox" else path = `/posts/${chatId}`; - const pageNo = Math.floor(postCache[chatId].length / 25) + 1; - if (pageNo < 2) return; - + // Get posts from API const response = await fetch(`https://api.meower.org${path}?page=${pageNo}`, { headers: { token: localStorage.getItem("token") } }); const postsData = await response.json(); + + // Block loading more if we've hit the end if (postsData["page#"] === postsData.pages && postsData.autoget.length < 25) { document.getElementById("skeleton-msgs").style.display = "none"; document.getElementById("msgs").setAttribute("data-loading-more", ""); } + + // Cache and load posts + const mainEl = document.getElementById("main"); + const scrollTop = mainEl.scrollTop; const postsarray = postsData.autoget || []; postsarray.forEach(post => { if (page !== chatId) { @@ -1930,11 +1757,10 @@ async function loadmore() { if (postCache[chatId].findIndex(_post => _post._id === post._id) !== -1) { return } - postCache[chatId].unshift(post); - post._reverse = true; + postCache[chatId].push(post); loadpost(post); - post._reverse = false; }); + mainEl.scrollTop = scrollTop; } function logout(iskl) { @@ -2443,6 +2269,7 @@ function loadAppearance() {
+

${lang().appearance_sub.cstheme}

@@ -3031,6 +2858,8 @@ function openModal(postId) { document.documentElement.style.overflow = "hidden"; const mdlbck = document.querySelector('.modal-back'); + const post = postCache[page].find(_post => _post._id === postId); + if (mdlbck) { mdlbck.style.display = 'flex'; @@ -3045,17 +2874,18 @@ function openModal(postId) { } const mdlt = mdl.querySelector('.modal-top'); if (mdlt) { - mdlt.innerHTML = ` + mdlt.innerHTML = `${post.post_origin !== 'inbox' ? ` + ` : ''} `; const postDiv = document.getElementById(postId); const usernameElement = postDiv.querySelector('#username').innerText; - if (usernameElement === localStorage.getItem("username")) { + if (usernameElement === localStorage.getItem("username") && post.post_origin !== 'inbox') { mdlt.innerHTML += ` @@ -3299,7 +3129,7 @@ async function loadreports() { `; - loadPfp(report.content.u, 1) + loadPfp(report.content.u, report.content.author, 1) .then(pfpElement => { if (pfpElement) { const rpfp = rprtbx.querySelector('.avatar'); @@ -4157,6 +3987,9 @@ function addAttachment(file) { element.classList.add("attach-pre-outer"); element.title = file.name; + if (getComputedStyle(document.documentElement).getPropertyValue('--color-scheme').trim() === 'light') { + element.classList.add(`lightpre`); + } element.innerHTML = `
@@ -4171,7 +4004,7 @@ function addAttachment(file) {
`; element.querySelector(".attachment-wrapper").querySelector(".delete-attach").onclick = () => { attachment.cancel(""); }; - if (['image/png', 'image/jpeg', 'image/webp', 'image/gif'].includes(file.type)) { + if (file.type.includes("image/") && file.size < (10 << 20)) { const reader = new FileReader(); reader.onloadend = () => { const img = document.createElement("img"); @@ -4294,7 +4127,7 @@ function goTo() { } else if (place.charAt(0) === "!") { openUsrModal(place.substring(1)); } else if (place === "home") { - loadhome(); + loadchat('home'); } else if (place === "start") { loadstart(); } else if (place === "settings") { @@ -4315,9 +4148,9 @@ function goTo() { } else if (place === "explore") { loadexplore(); } else if (place === "inbox") { - loadinbox(); + loadchat('inbox'); } else if (place === "livechat") { - loadlive(); + loadchat('livechat'); } else if (place === "groupcat" || place === "atticus") { groupcat(); } @@ -5193,13 +5026,13 @@ function notify(u, p, location, val) { notification.addEventListener('click', () => { switch (location) { case "home": - loadhome(); + loadchat('home'); break; case "livechat": - loadlive(); + loadchat('livechat'); break; case "inbox": - loadinbox(); + loadchat('inbox'); break; default: loadchat(location); diff --git a/share/script.js b/share/script.js index 8954f41..8a30dc2 100644 --- a/share/script.js +++ b/share/script.js @@ -11,7 +11,7 @@ async function loadsharedpost() { const api = `https://api.meower.org/posts?id=${id}`; console.debug(api); try { - const response = await fetch(api); + const response = await fetch(api, { headers: { token: localStorage.getItem("token") } }); const data = await response.json(); loadpost(data); } catch (error) { diff --git a/styles.css b/styles.css index 31097b4..b0b23f5 100644 --- a/styles.css +++ b/styles.css @@ -39,6 +39,7 @@ button { font-family: var(--font); font-weight: 400; transition: var(--transition); + font-size: 0.813em; } .trans { @@ -96,7 +97,7 @@ pre { padding: var(--padding); border-radius: var(--border-radius); overflow: auto; - font-size: 12px; + font-size: 0.75em; color: #fff; white-space: preserve; max-height: 300px; @@ -112,7 +113,7 @@ pre > code { } i { - font-size: 13px; + font-size: 0.677em; font-weight: normal; } @@ -165,7 +166,7 @@ li::marker, code, kbd, samp, pre { bridge { background-color: var(--primary); border-radius: 25px; - font-size: 12px; + font-size: 0.625em; padding-left: 5px; padding-right: 5px; padding-bottom: 1px; @@ -197,6 +198,10 @@ tr:nth-child(odd) { background-color: var(--accent-down); } +video { + background-color: var(--background); +} + ::-webkit-scrollbar { width: 12px; } @@ -323,7 +328,7 @@ tr:nth-child(odd) { .user-header { font-weight: 700; - font-size: 19px; + font-size: 1.2em; display: flex; margin: var(--text-margin) 0 10px 0; text-wrap: nowrap; @@ -373,14 +378,15 @@ tr:nth-child(odd) { } .reply { - font-size: 16px; + font-size: 1em; background-color: var(--accent-down); border: 3px solid var(--accent-down); padding-left: 10px; padding-right: 10px; border-radius: var(--border-radius); max-height: 100px; - overflow: hidden; + overflow-x: auto; /* Allows horizontal scrolling if content exceeds width */ + overflow-y: visible; /* Ensures vertical overflow is visible */ margin: var(--text-margin) 0; display: flex; @@ -388,6 +394,7 @@ tr:nth-child(odd) { gap: 10px; align-items: center; height: 42px; + white-space: nowrap; /* Prevents text from wrapping */ } .reply.custom { @@ -543,7 +550,7 @@ tr:nth-child(odd) { #replies { display: flex; flex-direction: column; - font-size: 16px; + font-size: 1em; } .replyinner > span { @@ -629,7 +636,7 @@ tr:nth-child(odd) { } .other-in { - font-size: 24px; + font-size: 1.5em; font-weight: bold; } @@ -681,7 +688,6 @@ tr:nth-child(odd) { .attachment-name { padding: 4px; - font-size: 12px; margin-top: auto; } @@ -691,6 +697,7 @@ tr:nth-child(odd) { text-overflow: ellipsis; width: 100%; display: inline-block; + font-size: 0.857em; } .edit-info { @@ -720,7 +727,7 @@ tr:nth-child(odd) { .sub-msg-cnt { padding: 0 calc(var(--margin) / 2); - font-size: 14px; + font-size: 0.875em; height: auto; transition: all 0.1s ease-out; position: sticky; @@ -742,6 +749,10 @@ tr:nth-child(odd) { overflow-y: hidden; } +.message-input:first-child { + border-top-left-radius: var(--br); +} + .message-send { flex: 0.2; min-width: 60px; @@ -782,6 +793,7 @@ tr:nth-child(odd) { border: var(--border); display: flex; animation: var(--animation); + position: relative; } .post:hover { @@ -795,7 +807,9 @@ tr:nth-child(odd) { .buttonContainer { display: none; - float: right; + position: absolute; + right: 0; + margin: 8px; } .visibleButtonContainer { @@ -1083,7 +1097,7 @@ possible future styling } .big { - font-size: 64px; + font-size: 4em; } .nav-top { @@ -1303,7 +1317,7 @@ possible future styling align-items: center; box-sizing: border-box; transition: var(--transition); - font-size: 16px; + font-size: 1em; } .big-mdl-inp:focus { @@ -1315,7 +1329,7 @@ possible future styling } .mdl-lb { - font-size: 12px; + font-size: 0.75em; opacity: 0.8; } @@ -1555,7 +1569,7 @@ possible future styling } .desc { - font-size: 12px; + font-size: 0.75em; } .editor { @@ -1644,13 +1658,19 @@ possible future styling } .edit-txt { - font-size: 16px; + font-size: 1em; display: flex; align-items: center; } .emoji { - height: 16px; + height: 1em; +} + +.emoji-outer { + width: 1em; + height: 1em; + display: inline-block; } .emoji:hover { @@ -1665,7 +1685,7 @@ possible future styling display: flex; flex-direction: column; max-height: 500px; - overflow: scroll; + overflow-y: scroll; scrollbar-width: none; } @@ -1735,7 +1755,7 @@ possible future styling .emojibuttonside { background-color: var(--modal-button-color); - font-size: 16px; + font-size: 1em; padding: var(--padding); margin: calc(var(--margin)/2); width: 42px; @@ -1900,7 +1920,7 @@ possible future styling background-color: var(--modal-button-color); border-radius: var(--border-radius); margin-bottom: 5px; - font-size: 12px; + font-size: 0.75em; text-align: left; } @@ -1961,7 +1981,7 @@ possible future styling color: var(--color); border: none; font-family: var(--font); - font-size: 16px; + font-size: 1em; width: 100px; } @@ -2102,7 +2122,7 @@ possible future styling } .subsubheader { - font-size: 12px; + font-size: 0.75em; -webkit-user-select: none; user-select: none; opacity: 0.8; @@ -2180,7 +2200,7 @@ possible future styling .plugintoggle.checked svg { opacity: 1; - color: var(--color-on); + color: var(--color-on) !important; } .plugintoggle.checked { @@ -2197,7 +2217,7 @@ possible future styling } .pluginsub { - font-size: 12px; + font-size: 0.75em; -webkit-user-select: none; user-select: none; opacity: 0.8; @@ -2212,13 +2232,13 @@ possible future styling background: var(--accent-color); border-radius: var(--border-radius); margin-top: 5px; - font-size: 12px; + font-size: 0.75em; text-align: center; min-width: 80px; } .custom-label { - font-size: 14px; + font-size: 0.875; width: 100%; margin: 5px; } @@ -2289,7 +2309,7 @@ possible future styling background: var(--accent-color); border-radius: var(--border-radius); margin-bottom: 5px; - font-size: 12px; + font-size: 0.75em; text-align: left; color: var(--color); text-decoration: none; @@ -2339,7 +2359,7 @@ possible future styling border: 3px solid var(--accent-color); border-radius: var(--border-radius); margin-bottom: 5px; - font-size: 16px; + font-size: 1em; display: flex; align-items: center; gap: 10px; @@ -2352,7 +2372,7 @@ possible future styling .language-r { flex: 1; text-align: right; - font-size: 12px; + font-size: 0.75em; opacity: 0.8; } @@ -2384,7 +2404,7 @@ possible future styling .skeleton-header { font-weight: 700; - font-size: 19px; + font-size: 1.188em; display: flex; gap: var(--margin); margin: var(--text-margin) 0 10px 0; @@ -2500,7 +2520,7 @@ possible future styling } .file-pre { - font-size: 12px; + font-size: 0.75em; } .fileicon { @@ -2570,6 +2590,10 @@ possible future styling text-shadow: 0 0 5px black; } +.lightpre .attachment-progress span { + text-shadow: none; +} + .attachment-progress::before { content: ''; position: absolute; @@ -2650,7 +2674,7 @@ possible future styling .owner { margin: 5px 0; - font-size: 14px; + font-size: 0.875em; } .ow-btn { @@ -2662,7 +2686,7 @@ possible future styling background: var(--modal-button-color); border-radius: var(--border-radius); margin-bottom: 5px; - font-size: 12px; + font-size: 0.75em; text-align: left; } @@ -2709,7 +2733,7 @@ possible future styling .key { padding: 2px 5px; - font-size: 12px; + font-size: 0.75em; background: var(--hov-accent-color); border-radius: 3px; box-shadow: 0 0 1px var(--color-on); @@ -2726,11 +2750,75 @@ possible future styling border-bottom: none; } +.tooltip { + position: relative; +} + +.tooltip::before, .tooltip::after { + position: absolute; + left: 50%; + opacity: 0; + transition: all 0.1s ease-in-out; + pointer-events: none; +} + +.tooltip::before { + content: ""; + border-width: 10px 8px 0 8px; + border-style: solid; + border-color: #111 transparent transparent transparent; + top: -20px; + margin-left: -8px; + z-index: 1; +} + +.tooltip::after { + content: attr(data-tooltip); + background: #111; + top: -20px; + transform: translateY(-100%) translateX(-50%); + font-size: 12px; + width: 80px; + border-radius: 10px; + color: var(--color-on); + padding: 12px; + z-index: 1; + display: flex; + justify-content: center; + align-items: center; +} + +.tooltip.left::after, .tooltip:last-child::after { + transform: translateY(-100%) translateX(-80%); +} + +.tooltip.bottom::before { + border-width: 0 8px 10px 8px; + border-color: transparent transparent #111 transparent; + top: 40px; +} + +.tooltip.bottom::after { + transform: translateY(185%) translateX(-55%); +} + +.tooltip:hover::before, .tooltip:hover::after{ + opacity: 1; +} + @media screen and (max-width: 720px) { html { scrollbar-gutter: none; } + .wrapper { + overflow: hidden; + } + + .tooltip::before, .tooltip::after { + display: none; + } + .modal { width: 100%; max-width: 100%; @@ -2841,14 +2929,6 @@ possible future styling .settings { margin-bottom: 60px; } - - #skeleton-msgs { - margin-top: -60px; - } - - #msgs { - margin-bottom: 60px; - } .navigation { margin-left: 10px; @@ -2883,7 +2963,9 @@ possible future styling .mobileContainer { display: flex; - float: right; + position: absolute; + right: 0; + margin: 8px; } .post:hover { @@ -2891,7 +2973,7 @@ possible future styling } .date { - font-size: 12px; + font-size: 0.75em; } .image-outer, .embed { @@ -3165,6 +3247,10 @@ button:focus-visible { outline: auto; } +input[type="button"] { + font-size: 0.813em; +} + input[type="button"]:focus-visible { outline: auto; } diff --git a/themes.css b/themes.css index dd7da5c..38957b7 100644 --- a/themes.css +++ b/themes.css @@ -367,7 +367,7 @@ /*Gradients*/ -.pride-theme, .trans-theme, .teb-theme, .fabloo-theme { +.pride-theme, .trans-theme, .teb-theme, .fabloo-theme, .nonb-theme { --background: #000; --color: #fefefe; --accent-color: #4749502f; @@ -381,16 +381,27 @@ --modal-button-color: #0d0e0f; --hov-modal-button-color: #16191e; + --accent-tint: #000; + --accent-down: #000; + --color-scheme: dark; } .trans-theme { --primary: #1aa6ca; + --color-on: #abeeff; --grad-height: 150px; } .pride-theme { --primary: #9443d1; + --color-on: #e3bdff; + --grad-height: 150px; +} + +.nonb-theme { + --primary: rgb(252, 244, 52); + --color-on: #000000; --grad-height: 150px; }