cleanup, add button to resend messages
This commit is contained in:
Vendored
+34
-11
@@ -260,7 +260,7 @@
|
|||||||
var IV_SIZE = 12;
|
var IV_SIZE = 12;
|
||||||
var ENCRYPTION_ALG = "AES-GCM";
|
var ENCRYPTION_ALG = "AES-GCM";
|
||||||
async function encryptString(plaintext, passphrase) {
|
async function encryptString(plaintext, passphrase) {
|
||||||
if (!window.crypto.subtle) return false;
|
if (!window.crypto.subtle) return plaintext;
|
||||||
const iv = generateIV();
|
const iv = generateIV();
|
||||||
const key = await importKey(passphrase, "encrypt");
|
const key = await importKey(passphrase, "encrypt");
|
||||||
const encryptedArray = await encrypt(iv, key, plaintext);
|
const encryptedArray = await encrypt(iv, key, plaintext);
|
||||||
@@ -360,6 +360,7 @@
|
|||||||
newSecondaryChannelName;
|
newSecondaryChannelName;
|
||||||
primaryChannelInput;
|
primaryChannelInput;
|
||||||
cannotSendMessage;
|
cannotSendMessage;
|
||||||
|
cannotResendMessage;
|
||||||
cannotAddSecondaryChannel;
|
cannotAddSecondaryChannel;
|
||||||
cannotSetChannel;
|
cannotSetChannel;
|
||||||
cannotUndoChannel;
|
cannotUndoChannel;
|
||||||
@@ -392,6 +393,10 @@
|
|||||||
],
|
],
|
||||||
() => this.primaryChannel.value == "" || this.composingMessage.value == "" || senderName.value == "" || this.isSubscribed.value == false || isConnected.value == false
|
() => this.primaryChannel.value == "" || this.composingMessage.value == "" || senderName.value == "" || this.isSubscribed.value == false || isConnected.value == false
|
||||||
);
|
);
|
||||||
|
this.cannotResendMessage = createProxyState(
|
||||||
|
[this.primaryChannel, this.isSubscribed, isConnected, senderName],
|
||||||
|
() => this.primaryChannel.value == "" || senderName.value == "" || this.isSubscribed.value == false || isConnected.value == false
|
||||||
|
);
|
||||||
this.cannotAddSecondaryChannel = createProxyState(
|
this.cannotAddSecondaryChannel = createProxyState(
|
||||||
[this.newSecondaryChannelName],
|
[this.newSecondaryChannelName],
|
||||||
() => this.newSecondaryChannelName.value == ""
|
() => this.newSecondaryChannelName.value == ""
|
||||||
@@ -439,8 +444,16 @@
|
|||||||
this.messages.add(chatMessage);
|
this.messages.add(chatMessage);
|
||||||
};
|
};
|
||||||
// messages
|
// messages
|
||||||
sendMessage = async () => {
|
sendNewMessage = async () => {
|
||||||
if (this.cannotSendMessage.value == true) return;
|
if (this.cannotSendMessage.value == true) return;
|
||||||
|
this.sendMessageText(this.composingMessage.value);
|
||||||
|
this.composingMessage.value = "";
|
||||||
|
};
|
||||||
|
resendMessage = (message) => {
|
||||||
|
if (this.cannotResendMessage.value == true) return;
|
||||||
|
this.sendMessageText(message.body);
|
||||||
|
};
|
||||||
|
sendMessageText = async (messageText) => {
|
||||||
const secondaryChannelNames = [
|
const secondaryChannelNames = [
|
||||||
...this.secondaryChannels.value.values()
|
...this.secondaryChannels.value.values()
|
||||||
];
|
];
|
||||||
@@ -448,10 +461,7 @@
|
|||||||
this.primaryChannel.value,
|
this.primaryChannel.value,
|
||||||
...secondaryChannelNames
|
...secondaryChannelNames
|
||||||
];
|
];
|
||||||
const encrypted = this.encryptionKey.value == "" ? this.composingMessage.value : await encryptString(
|
const encrypted = this.encryptionKey.value == "" ? messageText : await encryptString(messageText, this.encryptionKey.value);
|
||||||
this.composingMessage.value,
|
|
||||||
this.encryptionKey.value
|
|
||||||
) || this.composingMessage.value;
|
|
||||||
const joinedChannelName = allChannelNames.join("/");
|
const joinedChannelName = allChannelNames.join("/");
|
||||||
const messageObject = {
|
const messageObject = {
|
||||||
channel: joinedChannelName,
|
channel: joinedChannelName,
|
||||||
@@ -461,7 +471,6 @@
|
|||||||
};
|
};
|
||||||
const messageString = JSON.stringify(messageObject);
|
const messageString = JSON.stringify(messageObject);
|
||||||
UDN.sendMessage(joinedChannelName, messageString);
|
UDN.sendMessage(joinedChannelName, messageString);
|
||||||
this.composingMessage.value = "";
|
|
||||||
};
|
};
|
||||||
clearMessages = () => {
|
clearMessages = () => {
|
||||||
this.messages.clear();
|
this.messages.clear();
|
||||||
@@ -775,6 +784,7 @@
|
|||||||
noChatSelected: "No chat selected",
|
noChatSelected: "No chat selected",
|
||||||
composerPlaceholder: "Type a message...",
|
composerPlaceholder: "Type a message...",
|
||||||
sendMessage: "Send",
|
sendMessage: "Send",
|
||||||
|
resendMessage: "Resend message",
|
||||||
decryptMessage: "Decrypt message",
|
decryptMessage: "Decrypt message",
|
||||||
copyMessage: "Copy message",
|
copyMessage: "Copy message",
|
||||||
deleteMessage: "Delete message"
|
deleteMessage: "Delete message"
|
||||||
@@ -821,6 +831,7 @@
|
|||||||
noChatSelected: "Selecciona un chat",
|
noChatSelected: "Selecciona un chat",
|
||||||
composerPlaceholder: "Escribe un mensaje...",
|
composerPlaceholder: "Escribe un mensaje...",
|
||||||
sendMessage: "Enviar",
|
sendMessage: "Enviar",
|
||||||
|
resendMessage: "Enviar de nuevo",
|
||||||
decryptMessage: "Descifrar mensaje",
|
decryptMessage: "Descifrar mensaje",
|
||||||
copyMessage: "Copiar mensaje",
|
copyMessage: "Copiar mensaje",
|
||||||
deleteMessage: "Eliminar este mensaje"
|
deleteMessage: "Eliminar este mensaje"
|
||||||
@@ -865,6 +876,7 @@
|
|||||||
noChatSelected: "Kein Chat ausgew\xE4hlt",
|
noChatSelected: "Kein Chat ausgew\xE4hlt",
|
||||||
composerPlaceholder: "Neue Nachricht...",
|
composerPlaceholder: "Neue Nachricht...",
|
||||||
sendMessage: "Senden",
|
sendMessage: "Senden",
|
||||||
|
resendMessage: "Erneut senden",
|
||||||
decryptMessage: "Nachricht entschl\xFCsseln",
|
decryptMessage: "Nachricht entschl\xFCsseln",
|
||||||
copyMessage: "Nachricht kopieren",
|
copyMessage: "Nachricht kopieren",
|
||||||
deleteMessage: "Nachricht l\xF6schen"
|
deleteMessage: "Nachricht l\xF6schen"
|
||||||
@@ -981,13 +993,13 @@
|
|||||||
style: "max-width: unset",
|
style: "max-width: unset",
|
||||||
placeholder: translation.composerPlaceholder,
|
placeholder: translation.composerPlaceholder,
|
||||||
"bind:value": chat.composingMessage,
|
"bind:value": chat.composingMessage,
|
||||||
"on:enter": chat.sendMessage
|
"on:enter": chat.sendNewMessage
|
||||||
}
|
}
|
||||||
), /* @__PURE__ */ createElement(
|
), /* @__PURE__ */ createElement(
|
||||||
"button",
|
"button",
|
||||||
{
|
{
|
||||||
class: "primary",
|
class: "primary",
|
||||||
"on:click": chat.sendMessage,
|
"on:click": chat.sendNewMessage,
|
||||||
"toggle:disabled": chat.cannotSendMessage
|
"toggle:disabled": chat.cannotSendMessage
|
||||||
},
|
},
|
||||||
/* @__PURE__ */ createElement("span", { class: "icon" }, "send")
|
/* @__PURE__ */ createElement("span", { class: "icon" }, "send")
|
||||||
@@ -997,6 +1009,9 @@
|
|||||||
// src/Views/threadView.tsx
|
// src/Views/threadView.tsx
|
||||||
function ThreadView(chat) {
|
function ThreadView(chat) {
|
||||||
const messageConverter = (message) => {
|
const messageConverter = (message) => {
|
||||||
|
function resendMessage() {
|
||||||
|
chat.resendMessage(message);
|
||||||
|
}
|
||||||
function copyMessage() {
|
function copyMessage() {
|
||||||
navigator.clipboard.writeText(message.body);
|
navigator.clipboard.writeText(message.body);
|
||||||
}
|
}
|
||||||
@@ -1010,7 +1025,15 @@
|
|||||||
[chat.messages],
|
[chat.messages],
|
||||||
() => message.body
|
() => message.body
|
||||||
);
|
);
|
||||||
return /* @__PURE__ */ createElement("div", { class: "tile width-100 flex-no padding-0" }, /* @__PURE__ */ createElement("div", { class: "flex-column" }, /* @__PURE__ */ createElement("div", { class: "flex-row justify-apart align-center secondary" }, /* @__PURE__ */ createElement("span", { class: "padding-h ellipsis" }, /* @__PURE__ */ createElement("b", { class: "info" }, message.sender), " - ", message.channel), /* @__PURE__ */ createElement("span", { class: "flex-row" }, /* @__PURE__ */ createElement(
|
return /* @__PURE__ */ createElement("div", { class: "tile width-100 flex-no padding-0" }, /* @__PURE__ */ createElement("div", { class: "flex-column" }, /* @__PURE__ */ createElement("div", { class: "flex-row justify-apart align-center secondary" }, /* @__PURE__ */ createElement("span", { class: "padding-h ellipsis" }, /* @__PURE__ */ createElement("b", { class: "info" }, message.sender)), /* @__PURE__ */ createElement("span", { class: "flex-row" }, /* @__PURE__ */ createElement(
|
||||||
|
"button",
|
||||||
|
{
|
||||||
|
"aria-label": translation.resendMessage,
|
||||||
|
"on:click": resendMessage,
|
||||||
|
"toggle:disabled": chat.cannotResendMessage
|
||||||
|
},
|
||||||
|
/* @__PURE__ */ createElement("span", { class: "icon" }, "replay")
|
||||||
|
), /* @__PURE__ */ createElement(
|
||||||
"button",
|
"button",
|
||||||
{
|
{
|
||||||
"aria-label": translation.copyMessage,
|
"aria-label": translation.copyMessage,
|
||||||
@@ -1024,7 +1047,7 @@
|
|||||||
"on:click": decrypt2
|
"on:click": decrypt2
|
||||||
},
|
},
|
||||||
/* @__PURE__ */ createElement("span", { class: "icon" }, "key")
|
/* @__PURE__ */ createElement("span", { class: "icon" }, "key")
|
||||||
), /* @__PURE__ */ createElement("button", { "aria-label": translation.deleteMessage, "on:click": remove }, /* @__PURE__ */ createElement("span", { class: "icon" }, "delete")))), /* @__PURE__ */ createElement("div", { class: "flex-column padding-h padding-bottom" }, /* @__PURE__ */ createElement("b", { class: "break-word", "subscribe:innerText": messageBody }), /* @__PURE__ */ createElement("span", { class: "secondary" }, new Date(message.isoDate).toLocaleString()))));
|
), /* @__PURE__ */ createElement("button", { "aria-label": translation.deleteMessage, "on:click": remove }, /* @__PURE__ */ createElement("span", { class: "icon" }, "delete")))), /* @__PURE__ */ createElement("div", { class: "flex-column padding-h padding-bottom" }, /* @__PURE__ */ createElement("b", { class: "break-word", "subscribe:innerText": messageBody }), /* @__PURE__ */ createElement("span", { class: "secondary" }, /* @__PURE__ */ createElement("b", null, new Date(message.isoDate).toLocaleString()), " - ", message.channel))));
|
||||||
};
|
};
|
||||||
const listElement = /* @__PURE__ */ createElement(
|
const listElement = /* @__PURE__ */ createElement(
|
||||||
"div",
|
"div",
|
||||||
|
|||||||
+22
-9
@@ -38,6 +38,7 @@ export class Chat {
|
|||||||
primaryChannelInput: React.State<string>;
|
primaryChannelInput: React.State<string>;
|
||||||
|
|
||||||
cannotSendMessage: React.State<boolean>;
|
cannotSendMessage: React.State<boolean>;
|
||||||
|
cannotResendMessage: React.State<boolean>;
|
||||||
cannotAddSecondaryChannel: React.State<boolean>;
|
cannotAddSecondaryChannel: React.State<boolean>;
|
||||||
cannotSetChannel: React.State<boolean>;
|
cannotSetChannel: React.State<boolean>;
|
||||||
cannotUndoChannel: React.State<boolean>;
|
cannotUndoChannel: React.State<boolean>;
|
||||||
@@ -84,6 +85,14 @@ export class Chat {
|
|||||||
this.isSubscribed.value == false ||
|
this.isSubscribed.value == false ||
|
||||||
isConnected.value == false
|
isConnected.value == false
|
||||||
);
|
);
|
||||||
|
this.cannotResendMessage = React.createProxyState(
|
||||||
|
[this.primaryChannel, this.isSubscribed, isConnected, senderName],
|
||||||
|
() =>
|
||||||
|
this.primaryChannel.value == "" ||
|
||||||
|
senderName.value == "" ||
|
||||||
|
this.isSubscribed.value == false ||
|
||||||
|
isConnected.value == false
|
||||||
|
);
|
||||||
this.cannotAddSecondaryChannel = React.createProxyState(
|
this.cannotAddSecondaryChannel = React.createProxyState(
|
||||||
[this.newSecondaryChannelName],
|
[this.newSecondaryChannelName],
|
||||||
() => this.newSecondaryChannelName.value == ""
|
() => this.newSecondaryChannelName.value == ""
|
||||||
@@ -141,9 +150,19 @@ export class Chat {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// messages
|
// messages
|
||||||
sendMessage = async (): Promise<void> => {
|
sendNewMessage = async (): Promise<void> => {
|
||||||
if (this.cannotSendMessage.value == true) return;
|
if (this.cannotSendMessage.value == true) return;
|
||||||
|
|
||||||
|
this.sendMessageText(this.composingMessage.value);
|
||||||
|
this.composingMessage.value = "";
|
||||||
|
};
|
||||||
|
|
||||||
|
resendMessage = (message: ChatMessage) => {
|
||||||
|
if (this.cannotResendMessage.value == true) return;
|
||||||
|
this.sendMessageText(message.body);
|
||||||
|
};
|
||||||
|
|
||||||
|
sendMessageText = async (messageText: string): Promise<void> => {
|
||||||
// get channels
|
// get channels
|
||||||
const secondaryChannelNames: string[] = [
|
const secondaryChannelNames: string[] = [
|
||||||
...this.secondaryChannels.value.values(),
|
...this.secondaryChannels.value.values(),
|
||||||
@@ -156,11 +175,8 @@ export class Chat {
|
|||||||
// encrypt
|
// encrypt
|
||||||
const encrypted =
|
const encrypted =
|
||||||
this.encryptionKey.value == ""
|
this.encryptionKey.value == ""
|
||||||
? this.composingMessage.value
|
? messageText
|
||||||
: (await encryptString(
|
: await encryptString(messageText, this.encryptionKey.value);
|
||||||
this.composingMessage.value,
|
|
||||||
this.encryptionKey.value
|
|
||||||
)) || this.composingMessage.value;
|
|
||||||
|
|
||||||
// create object
|
// create object
|
||||||
const joinedChannelName = allChannelNames.join("/");
|
const joinedChannelName = allChannelNames.join("/");
|
||||||
@@ -174,9 +190,6 @@ export class Chat {
|
|||||||
|
|
||||||
// send
|
// send
|
||||||
UDN.sendMessage(joinedChannelName, messageString);
|
UDN.sendMessage(joinedChannelName, messageString);
|
||||||
|
|
||||||
// clear
|
|
||||||
this.composingMessage.value = "";
|
|
||||||
};
|
};
|
||||||
|
|
||||||
clearMessages = (): void => {
|
clearMessages = (): void => {
|
||||||
|
|||||||
@@ -12,11 +12,11 @@ export function MessageComposer(chat: Chat) {
|
|||||||
style="max-width: unset"
|
style="max-width: unset"
|
||||||
placeholder={translation.composerPlaceholder}
|
placeholder={translation.composerPlaceholder}
|
||||||
bind:value={chat.composingMessage}
|
bind:value={chat.composingMessage}
|
||||||
on:enter={chat.sendMessage}
|
on:enter={chat.sendNewMessage}
|
||||||
></input>
|
></input>
|
||||||
<button
|
<button
|
||||||
class="primary"
|
class="primary"
|
||||||
on:click={chat.sendMessage}
|
on:click={chat.sendNewMessage}
|
||||||
toggle:disabled={chat.cannotSendMessage}
|
toggle:disabled={chat.cannotSendMessage}
|
||||||
>
|
>
|
||||||
<span class="icon">send</span>
|
<span class="icon">send</span>
|
||||||
|
|||||||
@@ -6,6 +6,10 @@ import { translation } from "../translations";
|
|||||||
|
|
||||||
export function ThreadView(chat: Chat) {
|
export function ThreadView(chat: Chat) {
|
||||||
const messageConverter: React.ListItemConverter<ChatMessage> = (message) => {
|
const messageConverter: React.ListItemConverter<ChatMessage> = (message) => {
|
||||||
|
function resendMessage() {
|
||||||
|
chat.resendMessage(message);
|
||||||
|
}
|
||||||
|
|
||||||
function copyMessage() {
|
function copyMessage() {
|
||||||
navigator.clipboard.writeText(message.body);
|
navigator.clipboard.writeText(message.body);
|
||||||
}
|
}
|
||||||
@@ -28,9 +32,16 @@ export function ThreadView(chat: Chat) {
|
|||||||
<div class="flex-column">
|
<div class="flex-column">
|
||||||
<div class="flex-row justify-apart align-center secondary">
|
<div class="flex-row justify-apart align-center secondary">
|
||||||
<span class="padding-h ellipsis">
|
<span class="padding-h ellipsis">
|
||||||
<b class="info">{message.sender}</b> - {message.channel}
|
<b class="info">{message.sender}</b>
|
||||||
</span>
|
</span>
|
||||||
<span class="flex-row">
|
<span class="flex-row">
|
||||||
|
<button
|
||||||
|
aria-label={translation.resendMessage}
|
||||||
|
on:click={resendMessage}
|
||||||
|
toggle:disabled={chat.cannotResendMessage}
|
||||||
|
>
|
||||||
|
<span class="icon">replay</span>
|
||||||
|
</button>
|
||||||
<button
|
<button
|
||||||
aria-label={translation.copyMessage}
|
aria-label={translation.copyMessage}
|
||||||
on:click={copyMessage}
|
on:click={copyMessage}
|
||||||
@@ -50,9 +61,7 @@ export function ThreadView(chat: Chat) {
|
|||||||
</div>
|
</div>
|
||||||
<div class="flex-column padding-h padding-bottom">
|
<div class="flex-column padding-h padding-bottom">
|
||||||
<b class="break-word" subscribe:innerText={messageBody}></b>
|
<b class="break-word" subscribe:innerText={messageBody}></b>
|
||||||
<span class="secondary">
|
<span class="secondary"><b>{new Date(message.isoDate).toLocaleString()}</b> - {message.channel}</span>
|
||||||
{new Date(message.isoDate).toLocaleString()}
|
|
||||||
</span>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
+2
-2
@@ -5,8 +5,8 @@ const ENCRYPTION_ALG = "AES-GCM";
|
|||||||
export async function encryptString(
|
export async function encryptString(
|
||||||
plaintext: string,
|
plaintext: string,
|
||||||
passphrase: string
|
passphrase: string
|
||||||
): Promise<string | false> {
|
): Promise<string> {
|
||||||
if (!window.crypto.subtle) return false;
|
if (!window.crypto.subtle) return plaintext;
|
||||||
|
|
||||||
const iv = generateIV();
|
const iv = generateIV();
|
||||||
const key = await importKey(passphrase, "encrypt");
|
const key = await importKey(passphrase, "encrypt");
|
||||||
|
|||||||
@@ -55,6 +55,7 @@ const englishTranslations = {
|
|||||||
composerPlaceholder: "Type a message...",
|
composerPlaceholder: "Type a message...",
|
||||||
sendMessage: "Send",
|
sendMessage: "Send",
|
||||||
|
|
||||||
|
resendMessage: "Resend message",
|
||||||
decryptMessage: "Decrypt message",
|
decryptMessage: "Decrypt message",
|
||||||
copyMessage: "Copy message",
|
copyMessage: "Copy message",
|
||||||
deleteMessage: "Delete message",
|
deleteMessage: "Delete message",
|
||||||
@@ -119,6 +120,7 @@ const allTranslations: { [key: string]: typeof englishTranslations } = {
|
|||||||
composerPlaceholder: "Escribe un mensaje...",
|
composerPlaceholder: "Escribe un mensaje...",
|
||||||
sendMessage: "Enviar",
|
sendMessage: "Enviar",
|
||||||
|
|
||||||
|
resendMessage: "Enviar de nuevo",
|
||||||
decryptMessage: "Descifrar mensaje",
|
decryptMessage: "Descifrar mensaje",
|
||||||
copyMessage: "Copiar mensaje",
|
copyMessage: "Copiar mensaje",
|
||||||
deleteMessage: "Eliminar este mensaje",
|
deleteMessage: "Eliminar este mensaje",
|
||||||
@@ -180,6 +182,7 @@ const allTranslations: { [key: string]: typeof englishTranslations } = {
|
|||||||
composerPlaceholder: "Neue Nachricht...",
|
composerPlaceholder: "Neue Nachricht...",
|
||||||
sendMessage: "Senden",
|
sendMessage: "Senden",
|
||||||
|
|
||||||
|
resendMessage: "Erneut senden",
|
||||||
decryptMessage: "Nachricht entschlüsseln",
|
decryptMessage: "Nachricht entschlüsseln",
|
||||||
copyMessage: "Nachricht kopieren",
|
copyMessage: "Nachricht kopieren",
|
||||||
deleteMessage: "Nachricht löschen",
|
deleteMessage: "Nachricht löschen",
|
||||||
|
|||||||
Reference in New Issue
Block a user