working messages!!@!@
This commit is contained in:
parent
b24b36adec
commit
92edb123f3
8 changed files with 189 additions and 18 deletions
|
|
@ -121,7 +121,7 @@
|
||||||
"placeholder.username": "cat name",
|
"placeholder.username": "cat name",
|
||||||
"placeholder.captcha.code": "captcha code",
|
"placeholder.captcha.code": "captcha code",
|
||||||
"placeholder.message.input": "meow...",
|
"placeholder.message.input": "meow...",
|
||||||
"desc.messages.encryption.active": "meows are end-to-end encrypted :3",
|
"desc.messages.loading": "loading meows...",
|
||||||
"desc.no.dms": "no direct meowchats :c",
|
"desc.no.dms": "no direct meowchats :c",
|
||||||
"action.dm.opening": "opening meowchat...",
|
"action.dm.opening": "opening meowchat...",
|
||||||
"dm.open.failed": "failed to open meowchat :c",
|
"dm.open.failed": "failed to open meowchat :c",
|
||||||
|
|
|
||||||
|
|
@ -120,7 +120,7 @@
|
||||||
"placeholder.username": "username",
|
"placeholder.username": "username",
|
||||||
"placeholder.captcha.code": "captcha code",
|
"placeholder.captcha.code": "captcha code",
|
||||||
"placeholder.message.input": "Message...",
|
"placeholder.message.input": "Message...",
|
||||||
"desc.messages.encryption.active": "Messages are end-to-end encrypted",
|
"desc.messages.loading": "Fetching messages...",
|
||||||
"desc.no.dms": "No direct messages",
|
"desc.no.dms": "No direct messages",
|
||||||
"action.dm.opening": "Opening DM...",
|
"action.dm.opening": "Opening DM...",
|
||||||
"dm.open.failed": "Failed to open DM",
|
"dm.open.failed": "Failed to open DM",
|
||||||
|
|
|
||||||
|
|
@ -1645,6 +1645,7 @@ async function gotoHome() {
|
||||||
switchRoomContent("title.splash", splashScreen, false);
|
switchRoomContent("title.splash", splashScreen, false);
|
||||||
switchRoomsBar("title.home", homeRoomBar);
|
switchRoomsBar("title.home", homeRoomBar);
|
||||||
setActiveRoombarItem(null);
|
setActiveRoombarItem(null);
|
||||||
|
setupWebSocket();
|
||||||
await refreshDms(210);
|
await refreshDms(210);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1852,7 +1853,7 @@ async function openDm(dmId, username, targetId) {
|
||||||
|
|
||||||
let msgContainer = document.getElementById("chat-messages");
|
let msgContainer = document.getElementById("chat-messages");
|
||||||
if (msgContainer) {
|
if (msgContainer) {
|
||||||
msgContainer.innerHTML = `<div style="text-align: center; opacity: 0.5; padding: 1rem;"><blah>desc.messages.encryption.active</blah></div>`;
|
msgContainer.innerHTML = `<div style="text-align: center; opacity: 0.5; padding: 1rem;"><blah>desc.messages.loading</blah></div>`;
|
||||||
let blahTags = msgContainer.getElementsByTagName("blah");
|
let blahTags = msgContainer.getElementsByTagName("blah");
|
||||||
for (let i = 0; i < blahTags.length; i++) {
|
for (let i = 0; i < blahTags.length; i++) {
|
||||||
blahTags[i].innerHTML = processBlah(blahTags[i].innerHTML);
|
blahTags[i].innerHTML = processBlah(blahTags[i].innerHTML);
|
||||||
|
|
@ -1861,6 +1862,15 @@ async function openDm(dmId, username, targetId) {
|
||||||
|
|
||||||
await loadDmMessages(dmId);
|
await loadDmMessages(dmId);
|
||||||
|
|
||||||
|
if (dmMessagePollInterval) clearInterval(dmMessagePollInterval);
|
||||||
|
dmMessagePollInterval = setInterval(() => {
|
||||||
|
if (currentDmId === dmId) {
|
||||||
|
loadDmMessages(dmId);
|
||||||
|
} else {
|
||||||
|
clearInterval(dmMessagePollInterval);
|
||||||
|
}
|
||||||
|
}, 15000);
|
||||||
|
|
||||||
setActiveRoombarItem(`dm-btn-${dmId}`);
|
setActiveRoombarItem(`dm-btn-${dmId}`);
|
||||||
clearAction("dmopen");
|
clearAction("dmopen");
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
|
@ -1906,7 +1916,8 @@ async function renderMessages(messages) {
|
||||||
|
|
||||||
if (msg.key && msg.key !== "") {
|
if (msg.key && msg.key !== "") {
|
||||||
try {
|
try {
|
||||||
content = await decryptAesGcmFromBase64(content, currentDmKey);
|
let dmKeyBytes = await sha256Bytes(base64ToUint8(currentDmKey));
|
||||||
|
content = await decryptAesGcmFromBase64(content, dmKeyBytes);
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
content = `<span style="color:var(--error-color)"><blah>error:messages.decrypt.failed</blah></span>`;
|
content = `<span style="color:var(--error-color)"><blah>error:messages.decrypt.failed</blah></span>`;
|
||||||
}
|
}
|
||||||
|
|
@ -1957,4 +1968,79 @@ async function renderMessages(messages) {
|
||||||
|
|
||||||
container.innerHTML = html;
|
container.innerHTML = html;
|
||||||
container.scrollTop = container.scrollHeight;
|
container.scrollTop = container.scrollHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function sendMessage() {
|
||||||
|
if (!currentDmId || !currentDmKey) return;
|
||||||
|
|
||||||
|
let input = document.getElementById("chat-input");
|
||||||
|
let content = input.value.trim();
|
||||||
|
if (!content) return;
|
||||||
|
|
||||||
|
try {
|
||||||
|
let dmKeyBytes = await sha256Bytes(base64ToUint8(currentDmKey));
|
||||||
|
let encryptedContent = await encryptAesGcmToBase64(content, dmKeyBytes);
|
||||||
|
|
||||||
|
let msgPayload = {
|
||||||
|
string1: currentDmId,
|
||||||
|
string2: encryptedContent,
|
||||||
|
string3: ""
|
||||||
|
};
|
||||||
|
|
||||||
|
input.value = "";
|
||||||
|
|
||||||
|
let res = await fetchEncrypted("dm/message/send", JSON.stringify(msgPayload));
|
||||||
|
if (res && res.startsWith("error:")) {
|
||||||
|
showBlahNotification(res);
|
||||||
|
} else {
|
||||||
|
await loadDmMessages(currentDmId);
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e);
|
||||||
|
showBlahNotification("error:message.send.failed");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleChatInputKey(event) {
|
||||||
|
if (event.key === "Enter" && !event.shiftKey) {
|
||||||
|
const isMobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);
|
||||||
|
if (!isMobile) {
|
||||||
|
event.preventDefault();
|
||||||
|
sendMessage();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let dmMessagePollInterval = null;
|
||||||
|
let appWebSocket = null;
|
||||||
|
|
||||||
|
function setupWebSocket() {
|
||||||
|
if (appWebSocket && appWebSocket.readyState === WebSocket.OPEN) return;
|
||||||
|
|
||||||
|
let wsUrl = url.replace(/^http/, "ws") + "/ws";
|
||||||
|
appWebSocket = new WebSocket(wsUrl);
|
||||||
|
|
||||||
|
appWebSocket.onopen = async () => {
|
||||||
|
try {
|
||||||
|
let nonce = await getNonce(id, passwordHash);
|
||||||
|
let secretEnc = await encryptWithNonce(passwordHash, passwordHash, nonce);
|
||||||
|
appWebSocket.send(JSON.stringify({ string1: id, string2: secretEnc }));
|
||||||
|
} catch (e) {
|
||||||
|
console.error("WS auth failed", e);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
appWebSocket.onmessage = (event) => {
|
||||||
|
let data = event.data;
|
||||||
|
if (data.startsWith("dm_message:")) {
|
||||||
|
let msgDmId = data.substring("dm_message:".length);
|
||||||
|
if (currentDmId === msgDmId) {
|
||||||
|
loadDmMessages(msgDmId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
appWebSocket.onclose = () => {
|
||||||
|
setTimeout(setupWebSocket, 5000);
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
@ -132,10 +132,9 @@ var invitesEntry = `
|
||||||
var chatScreen = `
|
var chatScreen = `
|
||||||
<div style="display: flex; flex-direction: column; height: 100%; width: 100%;">
|
<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 id="chat-messages" style="flex-grow: 1; overflow-y: auto; padding: 1rem; display: flex; flex-direction: column; gap: 0.5rem;">
|
||||||
<!-- messages go here -->
|
|
||||||
</div>
|
</div>
|
||||||
<div style="padding: 1rem; border-top: var(--border-width) solid var(--light-border-color); display: flex; gap: 0.5rem;">
|
<div style="padding: 1rem; border-top: var(--border-width) solid var(--light-border-color); display: flex; gap: 0.5rem;">
|
||||||
<input type="text" id="chat-input" class="forminput" style="flex-grow: 1; margin: 0;" placeholder="{blah(placeholder.message.input)}">
|
<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)"></textarea>
|
||||||
<button class="submit-button" onclick="sendMessage()" style="margin: 0; padding: 0; aspect-ratio: 1;">
|
<button class="submit-button" onclick="sendMessage()" style="margin: 0; padding: 0; aspect-ratio: 1;">
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="-0.9 -0.5 15.6 16" fill="none" width="1.5rem">
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="-0.9 -0.5 15.6 16" fill="none" width="1.5rem">
|
||||||
<path stroke="var(--main-bg-color)" stroke-linecap="round" stroke-linejoin="round" d="m3.75 7.5 -1.875 5.625 11.25 -5.625L1.875 1.875l1.875 5.625zm0 0h3.75" stroke-width="1.1"></path>
|
<path stroke="var(--main-bg-color)" stroke-linecap="round" stroke-linejoin="round" d="m3.75 7.5 -1.875 5.625 11.25 -5.625L1.875 1.875l1.875 5.625zm0 0h3.75" stroke-width="1.1"></path>
|
||||||
|
|
|
||||||
|
|
@ -71,7 +71,7 @@ loading {
|
||||||
user-select: none !important;
|
user-select: none !important;
|
||||||
-webkit-user-drag: none !important;
|
-webkit-user-drag: none !important;
|
||||||
}
|
}
|
||||||
button, input {
|
button, input, textarea {
|
||||||
border-radius: 0.8rem;
|
border-radius: 0.8rem;
|
||||||
background-color: rgba(255, 255, 255, 0.05);
|
background-color: rgba(255, 255, 255, 0.05);
|
||||||
margin: var(--button-margin);
|
margin: var(--button-margin);
|
||||||
|
|
@ -92,7 +92,7 @@ button, input {
|
||||||
touch-action: manipulation;
|
touch-action: manipulation;
|
||||||
-webkit-touch-callout: none;
|
-webkit-touch-callout: none;
|
||||||
}
|
}
|
||||||
input {
|
input, textarea {
|
||||||
padding-left: calc(var(--button-margin) * 2);
|
padding-left: calc(var(--button-margin) * 2);
|
||||||
-webkit-touch-callout: default;
|
-webkit-touch-callout: default;
|
||||||
user-select: text !important;
|
user-select: text !important;
|
||||||
|
|
@ -677,7 +677,7 @@ space{
|
||||||
border-radius: 0.8rem;
|
border-radius: 0.8rem;
|
||||||
transform: translateY(calc( ( var(--icon-button-height) + (var(--button-margin) * 2) ) / 2 - 0.6rem));
|
transform: translateY(calc( ( var(--icon-button-height) + (var(--button-margin) * 2) ) / 2 - 0.6rem));
|
||||||
}
|
}
|
||||||
button:hover, input:hover {
|
button:hover, input:hover, textarea:hover {
|
||||||
background-color: rgba(255, 255, 255, 0.1);
|
background-color: rgba(255, 255, 255, 0.1);
|
||||||
}
|
}
|
||||||
.submit-button:hover {
|
.submit-button:hover {
|
||||||
|
|
@ -694,14 +694,14 @@ space{
|
||||||
filter: brightness(0.93);
|
filter: brightness(0.93);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
button:active, button.is-pressed, input:active, input.is-pressed {
|
button:active, button.is-pressed, input:active, input.is-pressed, textarea:active, textarea.is-pressed {
|
||||||
background-color: rgba(255, 255, 255, 0.1);
|
background-color: rgba(255, 255, 255, 0.1);
|
||||||
transform: var(--press-scale);
|
transform: var(--press-scale);
|
||||||
}
|
}
|
||||||
.invite-actions button:active {
|
.invite-actions button:active {
|
||||||
filter: brightness(0.85);
|
filter: brightness(0.85);
|
||||||
}
|
}
|
||||||
button.active, input.active {
|
button.active, input.active, textarea.active {
|
||||||
background-color: rgba(255, 255, 255, 0.1);
|
background-color: rgba(255, 255, 255, 0.1);
|
||||||
}
|
}
|
||||||
.submit-button:active, .submit-button.is-pressed {
|
.submit-button:active, .submit-button.is-pressed {
|
||||||
|
|
|
||||||
|
|
@ -1645,6 +1645,7 @@ async function gotoHome() {
|
||||||
switchRoomContent("title.splash", splashScreen, false);
|
switchRoomContent("title.splash", splashScreen, false);
|
||||||
switchRoomsBar("title.home", homeRoomBar);
|
switchRoomsBar("title.home", homeRoomBar);
|
||||||
setActiveRoombarItem(null);
|
setActiveRoombarItem(null);
|
||||||
|
setupWebSocket();
|
||||||
await refreshDms(210);
|
await refreshDms(210);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1861,6 +1862,15 @@ async function openDm(dmId, username, targetId) {
|
||||||
|
|
||||||
await loadDmMessages(dmId);
|
await loadDmMessages(dmId);
|
||||||
|
|
||||||
|
if (dmMessagePollInterval) clearInterval(dmMessagePollInterval);
|
||||||
|
dmMessagePollInterval = setInterval(() => {
|
||||||
|
if (currentDmId === dmId) {
|
||||||
|
loadDmMessages(dmId);
|
||||||
|
} else {
|
||||||
|
clearInterval(dmMessagePollInterval);
|
||||||
|
}
|
||||||
|
}, 15000);
|
||||||
|
|
||||||
setActiveRoombarItem(`dm-btn-${dmId}`);
|
setActiveRoombarItem(`dm-btn-${dmId}`);
|
||||||
clearAction("dmopen");
|
clearAction("dmopen");
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
|
@ -1906,7 +1916,8 @@ async function renderMessages(messages) {
|
||||||
|
|
||||||
if (msg.key && msg.key !== "") {
|
if (msg.key && msg.key !== "") {
|
||||||
try {
|
try {
|
||||||
content = await decryptAesGcmFromBase64(content, currentDmKey);
|
let dmKeyBytes = await sha256Bytes(base64ToUint8(currentDmKey));
|
||||||
|
content = await decryptAesGcmFromBase64(content, dmKeyBytes);
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
content = `<span style="color:var(--error-color)"><blah>error:messages.decrypt.failed</blah></span>`;
|
content = `<span style="color:var(--error-color)"><blah>error:messages.decrypt.failed</blah></span>`;
|
||||||
}
|
}
|
||||||
|
|
@ -1957,4 +1968,79 @@ async function renderMessages(messages) {
|
||||||
|
|
||||||
container.innerHTML = html;
|
container.innerHTML = html;
|
||||||
container.scrollTop = container.scrollHeight;
|
container.scrollTop = container.scrollHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function sendMessage() {
|
||||||
|
if (!currentDmId || !currentDmKey) return;
|
||||||
|
|
||||||
|
let input = document.getElementById("chat-input");
|
||||||
|
let content = input.value.trim();
|
||||||
|
if (!content) return;
|
||||||
|
|
||||||
|
try {
|
||||||
|
let dmKeyBytes = await sha256Bytes(base64ToUint8(currentDmKey));
|
||||||
|
let encryptedContent = await encryptAesGcmToBase64(content, dmKeyBytes);
|
||||||
|
|
||||||
|
let msgPayload = {
|
||||||
|
string1: currentDmId,
|
||||||
|
string2: encryptedContent,
|
||||||
|
string3: ""
|
||||||
|
};
|
||||||
|
|
||||||
|
input.value = "";
|
||||||
|
|
||||||
|
let res = await fetchEncrypted("dm/message/send", JSON.stringify(msgPayload));
|
||||||
|
if (res && res.startsWith("error:")) {
|
||||||
|
showBlahNotification(res);
|
||||||
|
} else {
|
||||||
|
await loadDmMessages(currentDmId);
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e);
|
||||||
|
showBlahNotification("error:message.send.failed");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleChatInputKey(event) {
|
||||||
|
if (event.key === "Enter" && !event.shiftKey) {
|
||||||
|
const isMobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);
|
||||||
|
if (!isMobile) {
|
||||||
|
event.preventDefault();
|
||||||
|
sendMessage();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let dmMessagePollInterval = null;
|
||||||
|
let appWebSocket = null;
|
||||||
|
|
||||||
|
function setupWebSocket() {
|
||||||
|
if (appWebSocket && appWebSocket.readyState === WebSocket.OPEN) return;
|
||||||
|
|
||||||
|
let wsUrl = url.replace(/^http/, "ws") + "/ws";
|
||||||
|
appWebSocket = new WebSocket(wsUrl);
|
||||||
|
|
||||||
|
appWebSocket.onopen = async () => {
|
||||||
|
try {
|
||||||
|
let nonce = await getNonce(id, passwordHash);
|
||||||
|
let secretEnc = await encryptWithNonce(passwordHash, passwordHash, nonce);
|
||||||
|
appWebSocket.send(JSON.stringify({ string1: id, string2: secretEnc }));
|
||||||
|
} catch (e) {
|
||||||
|
console.error("WS auth failed", e);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
appWebSocket.onmessage = (event) => {
|
||||||
|
let data = event.data;
|
||||||
|
if (data.startsWith("dm_message:")) {
|
||||||
|
let msgDmId = data.substring("dm_message:".length);
|
||||||
|
if (currentDmId === msgDmId) {
|
||||||
|
loadDmMessages(msgDmId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
appWebSocket.onclose = () => {
|
||||||
|
setTimeout(setupWebSocket, 5000);
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
@ -134,7 +134,7 @@ var chatScreen = `
|
||||||
<div id="chat-messages" style="flex-grow: 1; overflow-y: auto; padding: 1rem; display: flex; flex-direction: column; gap: 0.5rem;">
|
<div id="chat-messages" style="flex-grow: 1; overflow-y: auto; padding: 1rem; display: flex; flex-direction: column; gap: 0.5rem;">
|
||||||
</div>
|
</div>
|
||||||
<div style="padding: 1rem; border-top: var(--border-width) solid var(--light-border-color); display: flex; gap: 0.5rem;">
|
<div style="padding: 1rem; border-top: var(--border-width) solid var(--light-border-color); display: flex; gap: 0.5rem;">
|
||||||
<input type="text" id="chat-input" class="forminput" style="flex-grow: 1; margin: 0;" placeholder="{blah(placeholder.message.input)}">
|
<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)"></textarea>
|
||||||
<button class="submit-button" onclick="sendMessage()" style="margin: 0; padding: 0; aspect-ratio: 1;">
|
<button class="submit-button" onclick="sendMessage()" style="margin: 0; padding: 0; aspect-ratio: 1;">
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="-0.9 -0.5 15.6 16" fill="none" width="1.5rem">
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="-0.9 -0.5 15.6 16" fill="none" width="1.5rem">
|
||||||
<path stroke="var(--main-bg-color)" stroke-linecap="round" stroke-linejoin="round" d="m3.75 7.5 -1.875 5.625 11.25 -5.625L1.875 1.875l1.875 5.625zm0 0h3.75" stroke-width="1.1"></path>
|
<path stroke="var(--main-bg-color)" stroke-linecap="round" stroke-linejoin="round" d="m3.75 7.5 -1.875 5.625 11.25 -5.625L1.875 1.875l1.875 5.625zm0 0h3.75" stroke-width="1.1"></path>
|
||||||
|
|
|
||||||
|
|
@ -71,7 +71,7 @@ loading {
|
||||||
user-select: none !important;
|
user-select: none !important;
|
||||||
-webkit-user-drag: none !important;
|
-webkit-user-drag: none !important;
|
||||||
}
|
}
|
||||||
button, input {
|
button, input, textarea {
|
||||||
border-radius: 0.8rem;
|
border-radius: 0.8rem;
|
||||||
background-color: rgba(255, 255, 255, 0.05);
|
background-color: rgba(255, 255, 255, 0.05);
|
||||||
margin: var(--button-margin);
|
margin: var(--button-margin);
|
||||||
|
|
@ -92,7 +92,7 @@ button, input {
|
||||||
touch-action: manipulation;
|
touch-action: manipulation;
|
||||||
-webkit-touch-callout: none;
|
-webkit-touch-callout: none;
|
||||||
}
|
}
|
||||||
input {
|
input, textarea {
|
||||||
padding-left: calc(var(--button-margin) * 2);
|
padding-left: calc(var(--button-margin) * 2);
|
||||||
-webkit-touch-callout: default;
|
-webkit-touch-callout: default;
|
||||||
user-select: text !important;
|
user-select: text !important;
|
||||||
|
|
@ -677,7 +677,7 @@ space{
|
||||||
border-radius: 0.8rem;
|
border-radius: 0.8rem;
|
||||||
transform: translateY(calc( ( var(--icon-button-height) + (var(--button-margin) * 2) ) / 2 - 0.6rem));
|
transform: translateY(calc( ( var(--icon-button-height) + (var(--button-margin) * 2) ) / 2 - 0.6rem));
|
||||||
}
|
}
|
||||||
button:hover, input:hover {
|
button:hover, input:hover, textarea:hover {
|
||||||
background-color: rgba(255, 255, 255, 0.1);
|
background-color: rgba(255, 255, 255, 0.1);
|
||||||
}
|
}
|
||||||
.submit-button:hover {
|
.submit-button:hover {
|
||||||
|
|
@ -694,14 +694,14 @@ space{
|
||||||
filter: brightness(0.93);
|
filter: brightness(0.93);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
button:active, button.is-pressed, input:active, input.is-pressed {
|
button:active, button.is-pressed, input:active, input.is-pressed, textarea:active, textarea.is-pressed {
|
||||||
background-color: rgba(255, 255, 255, 0.1);
|
background-color: rgba(255, 255, 255, 0.1);
|
||||||
transform: var(--press-scale);
|
transform: var(--press-scale);
|
||||||
}
|
}
|
||||||
.invite-actions button:active {
|
.invite-actions button:active {
|
||||||
filter: brightness(0.85);
|
filter: brightness(0.85);
|
||||||
}
|
}
|
||||||
button.active, input.active {
|
button.active, input.active, textarea.active {
|
||||||
background-color: rgba(255, 255, 255, 0.1);
|
background-color: rgba(255, 255, 255, 0.1);
|
||||||
}
|
}
|
||||||
.submit-button:active, .submit-button.is-pressed {
|
.submit-button:active, .submit-button.is-pressed {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue