Changes:
All checks were successful
Android Build / publish (push) Successful in 46s
Linux Build / publish (push) Successful in 50s

- add replies
- add reactions
- add message redacting
- fix chat height when opening mobile keyboard
This commit is contained in:
olcxja 2026-06-12 16:51:32 +02:00
commit 4016975900
10 changed files with 1286 additions and 310 deletions

View file

@ -120,7 +120,6 @@
"title.back.to.register": "back to registration",
"placeholder.username": "cat name",
"placeholder.captcha.code": "captcha code",
"placeholder.message.input": "meow...",
"desc.messages.loading": "loading meows...",
"desc.no.dms": "no direct meowchats :c",
"action.dm.opening": "opening meowchat...",
@ -128,5 +127,18 @@
"keys.local.server.mismatch": "this device has different nametags than server :c use the device u first logged in on",
"keys.server.decrypt.failed": "wrong password for ur secret nametag bundle :c",
"dm.messages.fetch.failed": "failed to fetch meows :c",
"messages.decrypt.failed": "failed to decrypt meow :c"
"messages.decrypt.failed": "failed to decrypt meow :c",
"title.reply.message": "meow back",
"title.react.message": "purr",
"title.delete.message": "hiss away",
"title.replied.to": "meowed back to",
"action.message.deleting": "hissing message away...",
"action.message.sending": "sending meow...",
"action.message.reacting": "adding purr...",
"error:message.delete.failed": "failed to hiss away meow",
"error:message.send.failed": "failed to send meow",
"error:message.react.failed": "failed to add purr",
"info.sending.message": "sending...",
"placeholder.message.input": "meow...",
"larp.redacted": "this meow was hissed away."
}

View file

@ -127,5 +127,17 @@
"keys.local.server.mismatch": "This device has different encryption keys than the server. Use the device where you first logged in, or restore server keys from backup.",
"keys.server.decrypt.failed": "Could not decrypt your account keys with this password.",
"dm.messages.fetch.failed": "Failed to fetch messages",
"messages.decrypt.failed": "Failed to decrypt message"
"messages.decrypt.failed": "Failed to decrypt message",
"title.reply.message": "Reply",
"title.react.message": "React",
"title.delete.message": "Delete",
"title.replied.to": "Replied to",
"action.message.deleting": "Deleting message...",
"action.message.sending": "Sending message...",
"action.message.reacting": "Adding reaction...",
"error:message.delete.failed": "Failed to delete message",
"error:message.send.failed": "Failed to send message",
"error:message.react.failed": "Failed to add reaction",
"info.sending.message": "Sending...",
"larp.redacted": "This message was deleted."
}

File diff suppressed because it is too large Load diff

View file

@ -133,6 +133,14 @@ var chatScreen = `
<div style="display: flex; flex-direction: column; height: 100%; width: 100%;">
<div id="chat-messages" style="flex-grow: 1; overflow-y: auto; padding: 1rem; display: flex; flex-direction: column; gap: 0.5rem;">
</div>
<div id="replying-bar" style="display: none; padding: 0.5rem 1rem; border-top: var(--border-width) solid var(--light-border-color); font-size: 0.85rem; justify-content: space-between; align-items: center; background: var(--main-bg-color);">
<div style="overflow: hidden; text-overflow: ellipsis; white-space: nowrap; flex-grow: 1;">
<span style="opacity: 0.7;"><blah>title.replied.to</blah> </span><strong id="replying-to-name"></strong>: <span id="replying-to-text" style="opacity: 0.7;"></span>
</div>
<button onclick="cancelReply()" style="background: none; border: none; color: var(--text-color); cursor: pointer; padding: 0.2rem; margin-left: 0.5rem;">
<svg xmlns="http://www.w3.org/2000/svg" width="1.2rem" viewBox="0 -960 960 960" fill="currentColor"><path d="m256-200-56-56 224-224-224-224 56-56 224 224 224-224 56 56-224 224 224 224-56 56-224-224-224 224Z"/></svg>
</button>
</div>
<div style="padding: 1rem; border-top: var(--border-width) solid var(--light-border-color); display: flex; gap: 0.5rem;">
<textarea id="chat-input" class="forminput" style="flex-grow: 1; margin: 0; resize: none; min-height: 2.5rem; max-height: 8rem; padding: 0.5rem;" placeholder="{blah(placeholder.message.input)}" onkeydown="handleChatInputKey(event)" oninput="handleChatInputResize(this)"></textarea>
<button class="submit-button" onclick="sendMessage()" style="margin: 0; padding: 0; aspect-ratio: 1;">
@ -220,6 +228,20 @@ var addSpaceMenu = `
</button>
`;
var messageContextMenu = `
<button onclick="replyMessage(currentContextMenuMsgId)">
<svg xmlns="http://www.w3.org/2000/svg" width="1.4rem" viewBox="0 -960 960 960" fill="var(--text-color)"><path d="M760-200v-160q0-50-35-85t-85-35H273l144 144-57 56-240-240 240-240 57 56-144 144h367q83 0 141.5 58.5T840-360v160h-80Z"/></svg>
<span class="blah">title.reply.message</span>
</button>
<button onclick="reactMessagePrompt(currentContextMenuMsgId)">
<svg xmlns="http://www.w3.org/2000/svg" width="1.4rem" viewBox="0 -960 960 960" fill="var(--text-color)"><path d="M480-260q70 0 126.5-40.5T682-400H278q19 59 75.5 99.5T480-260Zm-160-220q25 0 42.5-17.5T380-540q0-25-17.5-42.5T320-600q-25 0-42.5 17.5T260-540q0 25 17.5 42.5T320-480Zm320 0q25 0 42.5-17.5T700-540q0-25-17.5-42.5T640-600q-25 0-42.5 17.5T580-540q0 25 17.5 42.5T640-480ZM480-80q-83 0-156-31.5T197-197q-54-54-85.5-127T80-480q0-83 31.5-156T197-763q54-54 127-85.5T480-880q83 0 156 31.5T763-763q54 54 85.5 127T880-480q0 83-31.5 156T763-197q-54 54-127 85.5T480-80Zm0-80q134 0 227-93t93-227q0-134-93-227t-227-93q-134 0-227 93t-93 227q0 134 93 227t227 93Zm0-320Z"/></svg>
<span class="blah">title.react.message</span>
</button>
<button id="context-delete-btn" onclick="deleteMessage(currentContextMenuMsgId)">
<svg xmlns="http://www.w3.org/2000/svg" height="1.4rem" viewBox="0 -960 960 960" fill="var(--big-red)"><path d="M280-120q-33 0-56.5-23.5T200-200v-520h-40v-80h200v-40h240v40h200v80h-40v520q0 33-23.5 56.5T680-120H280Zm400-600H280v520h400v-520ZM360-280h80v-360h-80v360Zm160 0h80v-360h-80v360ZM280-720v520-520Z"/></svg>
<span class="blah" style="color: var(--big-red)">title.delete.message</span>
</button>
`;
//elements
var detailsBtn = `<button class="mobile-nav-btn right" onclick="mobileNavDetails()"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 -960 960 960" fill="var(--text-color)"><path d="M120-240v-80h720v80H120Zm0-200v-80h720v80H120Zm0-200v-80h720v80H120Z"/></svg></button>`;

View file

@ -630,7 +630,18 @@ space{
.chat-message {
display: flex;
gap: 1rem;
padding: 0.2rem 0;
padding: 0.4rem 0.6rem;
margin: 0 -0.6rem;
border-radius: 0.8rem;
transition: background-color 0.15s ease;
}
@media (hover: hover) {
.chat-message:hover {
background-color: rgba(255, 255, 255, 0.04);
}
}
.chat-message:active, .chat-message.context-menu-open {
background-color: rgba(255, 255, 255, 0.04);
}
.chat-message.with-avatar {
margin-top: 0.8rem;

View file

@ -120,7 +120,6 @@
"title.back.to.register": "back to registration",
"placeholder.username": "cat name",
"placeholder.captcha.code": "captcha code",
"placeholder.message.input": "meow...",
"desc.messages.loading": "loading meows...",
"desc.no.dms": "no direct meowchats :c",
"action.dm.opening": "opening meowchat...",
@ -128,5 +127,18 @@
"keys.local.server.mismatch": "this device has different nametags than server :c use the device u first logged in on",
"keys.server.decrypt.failed": "wrong password for ur secret nametag bundle :c",
"dm.messages.fetch.failed": "failed to fetch meows :c",
"messages.decrypt.failed": "failed to decrypt meow :c"
"messages.decrypt.failed": "failed to decrypt meow :c",
"title.reply.message": "meow back",
"title.react.message": "purr",
"title.delete.message": "hiss away",
"title.replied.to": "meowed back to",
"action.message.deleting": "hissing message away...",
"action.message.sending": "sending meow...",
"action.message.reacting": "adding purr...",
"error:message.delete.failed": "failed to hiss away meow",
"error:message.send.failed": "failed to send meow",
"error:message.react.failed": "failed to add purr",
"info.sending.message": "sending...",
"placeholder.message.input": "meow...",
"larp.redacted": "this meow was hissed away."
}

View file

@ -127,5 +127,17 @@
"keys.local.server.mismatch": "This device has different encryption keys than the server. Use the device where you first logged in, or restore server keys from backup.",
"keys.server.decrypt.failed": "Could not decrypt your account keys with this password.",
"dm.messages.fetch.failed": "Failed to fetch messages",
"messages.decrypt.failed": "Failed to decrypt message"
"messages.decrypt.failed": "Failed to decrypt message",
"title.reply.message": "Reply",
"title.react.message": "React",
"title.delete.message": "Delete",
"title.replied.to": "Replied to",
"action.message.deleting": "Deleting message...",
"action.message.sending": "Sending message...",
"action.message.reacting": "Adding reaction...",
"error:message.delete.failed": "Failed to delete message",
"error:message.send.failed": "Failed to send message",
"error:message.react.failed": "Failed to add reaction",
"info.sending.message": "Sending...",
"larp.redacted": "This message was deleted."
}

File diff suppressed because it is too large Load diff

View file

@ -133,6 +133,14 @@ var chatScreen = `
<div style="display: flex; flex-direction: column; height: 100%; width: 100%;">
<div id="chat-messages" style="flex-grow: 1; overflow-y: auto; padding: 1rem; display: flex; flex-direction: column; gap: 0.5rem;">
</div>
<div id="replying-bar" style="display: none; padding: 0.5rem 1rem; border-top: var(--border-width) solid var(--light-border-color); font-size: 0.85rem; justify-content: space-between; align-items: center; background: var(--main-bg-color);">
<div style="overflow: hidden; text-overflow: ellipsis; white-space: nowrap; flex-grow: 1;">
<span style="opacity: 0.7;"><blah>title.replied.to</blah> </span><strong id="replying-to-name"></strong>: <span id="replying-to-text" style="opacity: 0.7;"></span>
</div>
<button onclick="cancelReply()" style="background: none; border: none; color: var(--text-color); cursor: pointer; padding: 0.2rem; margin-left: 0.5rem;">
<svg xmlns="http://www.w3.org/2000/svg" width="1.2rem" viewBox="0 -960 960 960" fill="currentColor"><path d="m256-200-56-56 224-224-224-224 56-56 224 224 224-224 56 56-224 224 224 224-56 56-224-224-224 224Z"/></svg>
</button>
</div>
<div style="padding: 1rem; border-top: var(--border-width) solid var(--light-border-color); display: flex; gap: 0.5rem;">
<textarea id="chat-input" class="forminput" style="flex-grow: 1; margin: 0; resize: none; min-height: 2.5rem; max-height: 8rem; padding: 0.5rem;" placeholder="{blah(placeholder.message.input)}" onkeydown="handleChatInputKey(event)" oninput="handleChatInputResize(this)"></textarea>
<button class="submit-button" onclick="sendMessage()" style="margin: 0; padding: 0; aspect-ratio: 1;">
@ -220,6 +228,20 @@ var addSpaceMenu = `
</button>
`;
var messageContextMenu = `
<button onclick="replyMessage(currentContextMenuMsgId)">
<svg xmlns="http://www.w3.org/2000/svg" width="1.4rem" viewBox="0 -960 960 960" fill="var(--text-color)"><path d="M760-200v-160q0-50-35-85t-85-35H273l144 144-57 56-240-240 240-240 57 56-144 144h367q83 0 141.5 58.5T840-360v160h-80Z"/></svg>
<span class="blah">title.reply.message</span>
</button>
<button onclick="reactMessagePrompt(currentContextMenuMsgId)">
<svg xmlns="http://www.w3.org/2000/svg" width="1.4rem" viewBox="0 -960 960 960" fill="var(--text-color)"><path d="M480-260q70 0 126.5-40.5T682-400H278q19 59 75.5 99.5T480-260Zm-160-220q25 0 42.5-17.5T380-540q0-25-17.5-42.5T320-600q-25 0-42.5 17.5T260-540q0 25 17.5 42.5T320-480Zm320 0q25 0 42.5-17.5T700-540q0-25-17.5-42.5T640-600q-25 0-42.5 17.5T580-540q0 25 17.5 42.5T640-480ZM480-80q-83 0-156-31.5T197-197q-54-54-85.5-127T80-480q0-83 31.5-156T197-763q54-54 127-85.5T480-880q83 0 156 31.5T763-763q54 54 85.5 127T880-480q0 83-31.5 156T763-197q-54 54-127 85.5T480-80Zm0-80q134 0 227-93t93-227q0-134-93-227t-227-93q-134 0-227 93t-93 227q0 134 93 227t227 93Zm0-320Z"/></svg>
<span class="blah">title.react.message</span>
</button>
<button id="context-delete-btn" onclick="deleteMessage(currentContextMenuMsgId)">
<svg xmlns="http://www.w3.org/2000/svg" height="1.4rem" viewBox="0 -960 960 960" fill="var(--big-red)"><path d="M280-120q-33 0-56.5-23.5T200-200v-520h-40v-80h200v-40h240v40h200v80h-40v520q0 33-23.5 56.5T680-120H280Zm400-600H280v520h400v-520ZM360-280h80v-360h-80v360Zm160 0h80v-360h-80v360ZM280-720v520-520Z"/></svg>
<span class="blah" style="color: var(--big-red)">title.delete.message</span>
</button>
`;
//elements
var detailsBtn = `<button class="mobile-nav-btn right" onclick="mobileNavDetails()"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 -960 960 960" fill="var(--text-color)"><path d="M120-240v-80h720v80H120Zm0-200v-80h720v80H120Zm0-200v-80h720v80H120Z"/></svg></button>`;

View file

@ -630,7 +630,18 @@ space{
.chat-message {
display: flex;
gap: 1rem;
padding: 0.2rem 0;
padding: 0.4rem 0.6rem;
margin: 0 -0.6rem;
border-radius: 0.8rem;
transition: background-color 0.15s ease;
}
@media (hover: hover) {
.chat-message:hover {
background-color: rgba(255, 255, 255, 0.04);
}
}
.chat-message:active, .chat-message.context-menu-open {
background-color: rgba(255, 255, 255, 0.04);
}
.chat-message.with-avatar {
margin-top: 0.8rem;