add outbox
This commit is contained in:
+39
-23
@@ -34,6 +34,8 @@ export class Chat {
|
||||
|
||||
encryptionKey: React.State<string>;
|
||||
messages: React.ListState<ChatMessage>;
|
||||
outbox: React.ListState<ChatMessage>;
|
||||
isOutBoxEmpty: React.State<boolean>;
|
||||
|
||||
composingMessage: React.State<string>;
|
||||
primaryChannelInput: React.State<string>;
|
||||
@@ -66,6 +68,11 @@ export class Chat {
|
||||
);
|
||||
this.encryptionKey = React.restoreState(storageKeys.encyptionKey(id), "");
|
||||
this.messages = React.restoreListState(storageKeys.messages(id));
|
||||
this.outbox = React.restoreListState(storageKeys.outbox(id));
|
||||
this.isOutBoxEmpty = React.createProxyState(
|
||||
[this.outbox],
|
||||
() => this.outbox.value.size == 0
|
||||
);
|
||||
|
||||
// inputs
|
||||
this.composingMessage = React.restoreState(
|
||||
@@ -77,27 +84,15 @@ export class Chat {
|
||||
|
||||
// guards
|
||||
this.cannotSendMessage = React.createProxyState(
|
||||
[
|
||||
this.primaryChannel,
|
||||
this.composingMessage,
|
||||
this.isSubscribed,
|
||||
isConnected,
|
||||
senderName,
|
||||
],
|
||||
[this.primaryChannel, this.composingMessage, senderName],
|
||||
() =>
|
||||
this.primaryChannel.value == "" ||
|
||||
this.composingMessage.value == "" ||
|
||||
senderName.value == "" ||
|
||||
this.isSubscribed.value == false ||
|
||||
isConnected.value == false
|
||||
senderName.value == ""
|
||||
);
|
||||
this.cannotResendMessage = React.createProxyState(
|
||||
[this.primaryChannel, this.isSubscribed, isConnected, senderName],
|
||||
() =>
|
||||
this.primaryChannel.value == "" ||
|
||||
senderName.value == "" ||
|
||||
this.isSubscribed.value == false ||
|
||||
isConnected.value == false
|
||||
[this.primaryChannel, senderName],
|
||||
() => this.primaryChannel.value == "" || senderName.value == ""
|
||||
);
|
||||
this.cannotAddSecondaryChannel = React.createProxyState(
|
||||
[this.newSecondaryChannelName],
|
||||
@@ -149,6 +144,10 @@ export class Chat {
|
||||
|
||||
handleSubscription = (isSubscribed: boolean): void => {
|
||||
this.isSubscribed.value = isSubscribed;
|
||||
|
||||
if (isSubscribed == true) {
|
||||
this.sendMessagesInOutbox();
|
||||
}
|
||||
};
|
||||
|
||||
handleMessage = (chatMessage: ChatMessage): void => {
|
||||
@@ -160,16 +159,17 @@ export class Chat {
|
||||
sendNewMessage = async (): Promise<void> => {
|
||||
if (this.cannotSendMessage.value == true) return;
|
||||
|
||||
this.sendMessageText(this.composingMessage.value);
|
||||
const message = await this.createMessage(this.composingMessage.value);
|
||||
this.sendExistingMessage(message);
|
||||
this.composingMessage.value = "";
|
||||
};
|
||||
|
||||
resendMessage = (message: ChatMessage) => {
|
||||
if (this.cannotResendMessage.value == true) return;
|
||||
this.sendMessageText(message.body);
|
||||
this.sendExistingMessage(message);
|
||||
};
|
||||
|
||||
sendMessageText = async (messageText: string): Promise<void> => {
|
||||
createMessage = async (messageText: string): Promise<ChatMessage> => {
|
||||
// get channels
|
||||
const secondaryChannelNames: string[] = [
|
||||
...this.secondaryChannels.value.values(),
|
||||
@@ -187,16 +187,28 @@ export class Chat {
|
||||
|
||||
// create object
|
||||
const joinedChannelName = allChannelNames.join("/");
|
||||
const messageObject: ChatMessage = {
|
||||
return {
|
||||
channel: joinedChannelName,
|
||||
sender: senderName.value,
|
||||
body: encrypted,
|
||||
isoDate: new Date().toISOString(),
|
||||
};
|
||||
const messageString = JSON.stringify(messageObject);
|
||||
};
|
||||
|
||||
// send
|
||||
UDN.sendMessage(joinedChannelName, messageString);
|
||||
sendExistingMessage = async (chatMessage: ChatMessage): Promise<void> => {
|
||||
if (isConnected.value == true && this.isSubscribed.value == true) {
|
||||
const messageString = JSON.stringify(chatMessage);
|
||||
UDN.sendMessage(chatMessage.channel, messageString);
|
||||
} else {
|
||||
this.outbox.add(chatMessage);
|
||||
}
|
||||
};
|
||||
|
||||
sendMessagesInOutbox = () => {
|
||||
this.outbox.value.forEach((message) => {
|
||||
this.sendExistingMessage(message)
|
||||
this.outbox.remove(message);
|
||||
});
|
||||
};
|
||||
|
||||
clearMessages = (): void => {
|
||||
@@ -207,6 +219,10 @@ export class Chat {
|
||||
this.messages.remove(message);
|
||||
};
|
||||
|
||||
deleteOutboxMessage = (message: ChatMessage): void => {
|
||||
this.outbox.remove(message);
|
||||
};
|
||||
|
||||
decryptReceivedMessage = async (message: ChatMessage): Promise<void> => {
|
||||
message.body = await decryptString(message.body, this.encryptionKey.value);
|
||||
this.messages.callSubscriptions();
|
||||
|
||||
@@ -72,20 +72,68 @@ export function ThreadView(chat: Chat) {
|
||||
);
|
||||
};
|
||||
|
||||
const listElement = (
|
||||
const outboxMessageConverter: React.ListItemConverter<ChatMessage> = (
|
||||
message
|
||||
) => {
|
||||
function remove() {
|
||||
chat.deleteOutboxMessage(message);
|
||||
}
|
||||
|
||||
return (
|
||||
<div class="tile width-100 flex-no padding-0">
|
||||
<div class="flex-column">
|
||||
<div class="flex-row justify-apart align-center">
|
||||
<b class="error padding-h">{translation.messageInOutbox}</b>
|
||||
<span class="flex-row secondary">
|
||||
<button aria-label={translation.deleteMessage} on:click={remove}>
|
||||
<span class="icon">delete</span>
|
||||
</button>
|
||||
</span>
|
||||
</div>
|
||||
<div class="flex-column padding-h padding-bottom">
|
||||
<b class="break-word">{message.body}</b>
|
||||
<span class="secondary">
|
||||
<b>{new Date(message.isoDate).toLocaleString()}</b>
|
||||
<br></br>
|
||||
{message.channel}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const messageList = (
|
||||
<div
|
||||
class="flex-column gap"
|
||||
children:append={[chat.messages, messageConverter]}
|
||||
></div>
|
||||
);
|
||||
chat.messages.handleAddition(() => {
|
||||
const outboxList = (
|
||||
<div
|
||||
class="flex-column gap"
|
||||
children:append={[chat.outbox, outboxMessageConverter]}
|
||||
></div>
|
||||
);
|
||||
const listWrapper = (
|
||||
<div class="flex-column gap">
|
||||
{messageList}
|
||||
{outboxList}
|
||||
</div>
|
||||
);
|
||||
|
||||
function scrollToBottom() {
|
||||
const scrollFromBottom =
|
||||
listElement.scrollHeight -
|
||||
(listElement.scrollTop + listElement.offsetHeight);
|
||||
listWrapper.scrollHeight -
|
||||
(listWrapper.scrollTop + listWrapper.offsetHeight);
|
||||
if (scrollFromBottom > 400) return;
|
||||
|
||||
listElement.scrollTop = listElement.scrollHeight;
|
||||
});
|
||||
setTimeout(() => (listElement.scrollTop = listElement.scrollHeight), 50);
|
||||
return listElement;
|
||||
listWrapper.scrollTop = listWrapper.scrollHeight;
|
||||
}
|
||||
|
||||
chat.messages.handleAddition(scrollToBottom);
|
||||
chat.outbox.handleAddition(scrollToBottom);
|
||||
setTimeout(() => (listWrapper.scrollTop = listWrapper.scrollHeight), 50);
|
||||
|
||||
return listWrapper;
|
||||
}
|
||||
|
||||
@@ -50,6 +50,8 @@ const englishTranslations = {
|
||||
removeChat: "Remove chat",
|
||||
clearChatMessages: "Clear chat messages",
|
||||
|
||||
messageInOutbox: "Pending",
|
||||
|
||||
noChatSelected: "No chat selected",
|
||||
|
||||
composerPlaceholder: "Type a message...",
|
||||
@@ -117,6 +119,8 @@ const allTranslations: { [key: string]: typeof englishTranslations } = {
|
||||
|
||||
noChatSelected: "Selecciona un chat",
|
||||
|
||||
messageInOutbox: "Pendiente",
|
||||
|
||||
composerPlaceholder: "Escribe un mensaje...",
|
||||
sendMessage: "Enviar",
|
||||
|
||||
@@ -179,6 +183,8 @@ const allTranslations: { [key: string]: typeof englishTranslations } = {
|
||||
|
||||
noChatSelected: "Kein Chat ausgewählt",
|
||||
|
||||
messageInOutbox: "Ausstehend",
|
||||
|
||||
composerPlaceholder: "Neue Nachricht...",
|
||||
sendMessage: "Senden",
|
||||
|
||||
|
||||
@@ -19,6 +19,10 @@ export const storageKeys = {
|
||||
return id + "messages";
|
||||
},
|
||||
|
||||
outbox(id: string): string {
|
||||
return id + "outbox";
|
||||
},
|
||||
|
||||
composingMessage(id: string): string {
|
||||
return id + "composing-message";
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user