rename item->object, implement basic object editing
This commit is contained in:
Vendored
+85
-45
@@ -399,7 +399,7 @@
|
|||||||
messages(id) {
|
messages(id) {
|
||||||
return id + "messages";
|
return id + "messages";
|
||||||
},
|
},
|
||||||
items(id) {
|
objects(id) {
|
||||||
return id + "items";
|
return id + "items";
|
||||||
},
|
},
|
||||||
outbox(id) {
|
outbox(id) {
|
||||||
@@ -422,9 +422,9 @@
|
|||||||
secondaryChannels;
|
secondaryChannels;
|
||||||
encryptionKey;
|
encryptionKey;
|
||||||
messages;
|
messages;
|
||||||
items;
|
objects;
|
||||||
outbox;
|
outbox;
|
||||||
itemOutbox;
|
objectOutbox;
|
||||||
isOutBoxEmpty;
|
isOutBoxEmpty;
|
||||||
composingMessage;
|
composingMessage;
|
||||||
primaryChannelInput;
|
primaryChannelInput;
|
||||||
@@ -451,9 +451,9 @@
|
|||||||
);
|
);
|
||||||
this.encryptionKey = restoreState(storageKeys.encyptionKey(id), "");
|
this.encryptionKey = restoreState(storageKeys.encyptionKey(id), "");
|
||||||
this.messages = restoreListState(storageKeys.messages(id));
|
this.messages = restoreListState(storageKeys.messages(id));
|
||||||
this.items = restoreMapState(storageKeys.items(id));
|
this.objects = restoreMapState(storageKeys.objects(id));
|
||||||
this.outbox = restoreListState(storageKeys.outbox(id));
|
this.outbox = restoreListState(storageKeys.outbox(id));
|
||||||
this.itemOutbox = restoreListState(storageKeys.itemOutbox(id));
|
this.objectOutbox = restoreListState(storageKeys.itemOutbox(id));
|
||||||
this.isOutBoxEmpty = createProxyState(
|
this.isOutBoxEmpty = createProxyState(
|
||||||
[this.outbox],
|
[this.outbox],
|
||||||
() => this.outbox.value.size == 0
|
() => this.outbox.value.size == 0
|
||||||
@@ -504,11 +504,11 @@
|
|||||||
if (channels.indexOf(this.primaryChannel.value) == -1) return;
|
if (channels.indexOf(this.primaryChannel.value) == -1) return;
|
||||||
if (data.subscribed != void 0) this.handleSubscription(data.subscribed);
|
if (data.subscribed != void 0) this.handleSubscription(data.subscribed);
|
||||||
if (!data.messageBody) return;
|
if (!data.messageBody) return;
|
||||||
const { sender, body, channel, isoDate, itemData } = JSON.parse(
|
const { sender, body, channel, isoDate, messageObject } = JSON.parse(
|
||||||
data.messageBody
|
data.messageBody
|
||||||
);
|
);
|
||||||
if (itemData && itemData.id && itemData.title) {
|
if (messageObject && messageObject.id && messageObject.title) {
|
||||||
return this.handleItem(itemData);
|
return this.handleMessageObject(messageObject);
|
||||||
}
|
}
|
||||||
this.handleMessage({
|
this.handleMessage({
|
||||||
sender,
|
sender,
|
||||||
@@ -527,11 +527,11 @@
|
|||||||
this.messages.add(chatMessage);
|
this.messages.add(chatMessage);
|
||||||
if (selectedChat.value != this) this.hasUnreadMessages.value = true;
|
if (selectedChat.value != this) this.hasUnreadMessages.value = true;
|
||||||
};
|
};
|
||||||
handleItem = (itemData) => {
|
handleMessageObject = (messageObject) => {
|
||||||
this.items.set(itemData.id, itemData);
|
this.objects.set(messageObject.id, messageObject);
|
||||||
};
|
};
|
||||||
// messages
|
// messages
|
||||||
createMessage = async (messageText, itemData) => {
|
createChatMessage = async (messageText, messageObject) => {
|
||||||
const secondaryChannelNames = [
|
const secondaryChannelNames = [
|
||||||
...this.secondaryChannels.value.values()
|
...this.secondaryChannels.value.values()
|
||||||
];
|
];
|
||||||
@@ -540,14 +540,14 @@
|
|||||||
...secondaryChannelNames
|
...secondaryChannelNames
|
||||||
];
|
];
|
||||||
const joinedChannelName = allChannelNames.join("/");
|
const joinedChannelName = allChannelNames.join("/");
|
||||||
const messageObject = {
|
const chatMessage = {
|
||||||
channel: joinedChannelName,
|
channel: joinedChannelName,
|
||||||
sender: senderName.value,
|
sender: senderName.value,
|
||||||
body: messageText,
|
body: messageText,
|
||||||
isoDate: (/* @__PURE__ */ new Date()).toISOString()
|
isoDate: (/* @__PURE__ */ new Date()).toISOString()
|
||||||
};
|
};
|
||||||
if (itemData) messageObject.itemData = itemData;
|
if (messageObject) chatMessage.messageObject = messageObject;
|
||||||
return messageObject;
|
return chatMessage;
|
||||||
};
|
};
|
||||||
sendMessageFromComposer = async () => {
|
sendMessageFromComposer = async () => {
|
||||||
if (this.cannotSendMessage.value == true) return;
|
if (this.cannotSendMessage.value == true) return;
|
||||||
@@ -555,12 +555,12 @@
|
|||||||
this.composingMessage.value = "";
|
this.composingMessage.value = "";
|
||||||
};
|
};
|
||||||
sendMessageFromText = async (text) => {
|
sendMessageFromText = async (text) => {
|
||||||
const message = await this.createMessage(text);
|
const chatMessage = await this.createChatMessage(text);
|
||||||
this.sendMessage(message);
|
this.sendMessage(chatMessage);
|
||||||
};
|
};
|
||||||
resendMessage = (message) => {
|
resendMessage = (chatMessage) => {
|
||||||
if (this.cannotResendMessage.value == true) return;
|
if (this.cannotResendMessage.value == true) return;
|
||||||
this.sendMessageFromText(message.body);
|
this.sendMessageFromText(chatMessage.body);
|
||||||
};
|
};
|
||||||
sendMessage = async (chatMessage) => {
|
sendMessage = async (chatMessage) => {
|
||||||
if (isConnected.value == true && this.isSubscribed.value == true) {
|
if (isConnected.value == true && this.isSubscribed.value == true) {
|
||||||
@@ -569,7 +569,7 @@
|
|||||||
const messageString = JSON.stringify(chatMessage);
|
const messageString = JSON.stringify(chatMessage);
|
||||||
UDN.sendMessage(chatMessage.channel, messageString);
|
UDN.sendMessage(chatMessage.channel, messageString);
|
||||||
} else {
|
} else {
|
||||||
if (chatMessage.itemData) return this.itemOutbox.add(chatMessage);
|
if (chatMessage.messageObject) return this.objectOutbox.add(chatMessage);
|
||||||
this.outbox.add(chatMessage);
|
this.outbox.add(chatMessage);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -578,29 +578,29 @@
|
|||||||
this.sendMessage(message);
|
this.sendMessage(message);
|
||||||
this.outbox.remove(message);
|
this.outbox.remove(message);
|
||||||
});
|
});
|
||||||
this.itemOutbox.value.forEach((message) => {
|
this.objectOutbox.value.forEach((message) => {
|
||||||
this.sendMessage(message);
|
this.sendMessage(message);
|
||||||
this.itemOutbox.remove(message);
|
this.objectOutbox.remove(message);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
clearMessages = () => {
|
clearMessages = () => {
|
||||||
this.messages.clear();
|
this.messages.clear();
|
||||||
};
|
};
|
||||||
deleteMessage = (message) => {
|
deleteMessage = (chatMessage) => {
|
||||||
this.messages.remove(message);
|
this.messages.remove(chatMessage);
|
||||||
};
|
};
|
||||||
deleteOutboxMessage = (message) => {
|
deleteOutboxMessage = (chatMessage) => {
|
||||||
this.outbox.remove(message);
|
this.outbox.remove(chatMessage);
|
||||||
};
|
};
|
||||||
decryptReceivedMessage = async (message) => {
|
decryptReceivedMessage = async (chatMessage) => {
|
||||||
message.body = await decryptString(message.body, this.encryptionKey.value);
|
chatMessage.body = await decryptString(chatMessage.body, this.encryptionKey.value);
|
||||||
this.messages.callSubscriptions();
|
this.messages.callSubscriptions();
|
||||||
};
|
};
|
||||||
// items
|
// objects
|
||||||
async createItem(item) {
|
async createObject(object) {
|
||||||
this.items.set(item.id, item);
|
this.objects.set(object.id, object);
|
||||||
const message = await this.createMessage("", item);
|
const chatMessage = await this.createChatMessage("", object);
|
||||||
this.sendMessage(message);
|
this.sendMessage(chatMessage);
|
||||||
}
|
}
|
||||||
// channel
|
// channel
|
||||||
setChannel = () => {
|
setChannel = () => {
|
||||||
@@ -872,9 +872,11 @@
|
|||||||
var englishTranslations = {
|
var englishTranslations = {
|
||||||
// general
|
// general
|
||||||
set: "Set",
|
set: "Set",
|
||||||
|
save: "Save",
|
||||||
back: "Back",
|
back: "Back",
|
||||||
undoChanges: "Undo changes",
|
undoChanges: "Undo changes",
|
||||||
close: "Close",
|
close: "Close",
|
||||||
|
discard: "Discard",
|
||||||
// overview
|
// overview
|
||||||
overview: "Overview",
|
overview: "Overview",
|
||||||
connection: "Connection",
|
connection: "Connection",
|
||||||
@@ -896,7 +898,6 @@
|
|||||||
addChat: "Add",
|
addChat: "Add",
|
||||||
// messages
|
// messages
|
||||||
showChatOptions: "show chat options",
|
showChatOptions: "show chat options",
|
||||||
toggleChatTools: "toggle chat tools",
|
|
||||||
configureChatTitle: "Configure Chat",
|
configureChatTitle: "Configure Chat",
|
||||||
secondaryChannel: "Secondary channel",
|
secondaryChannel: "Secondary channel",
|
||||||
secondaryChannelPlaceholder: "Add secondary channel",
|
secondaryChannelPlaceholder: "Add secondary channel",
|
||||||
@@ -914,7 +915,12 @@
|
|||||||
resendMessage: "Resend message",
|
resendMessage: "Resend message",
|
||||||
decryptMessage: "Decrypt message",
|
decryptMessage: "Decrypt message",
|
||||||
copyMessage: "Copy message",
|
copyMessage: "Copy message",
|
||||||
deleteMessage: "Delete message"
|
deleteMessage: "Delete message",
|
||||||
|
// objects
|
||||||
|
toggleChatTools: "toggle chat tools",
|
||||||
|
objectTitle: "Object title",
|
||||||
|
objectTitlePlaceholder: "My object",
|
||||||
|
deleteObject: "Delete object"
|
||||||
};
|
};
|
||||||
var allTranslations = {
|
var allTranslations = {
|
||||||
en: englishTranslations,
|
en: englishTranslations,
|
||||||
@@ -1014,7 +1020,7 @@
|
|||||||
var language = navigator.language.substring(0, 2);
|
var language = navigator.language.substring(0, 2);
|
||||||
var translation = allTranslations[language] ?? allTranslations.en;
|
var translation = allTranslations[language] ?? allTranslations.en;
|
||||||
|
|
||||||
// src/Views/chatOptionModal.tsx
|
// src/Views/Chat/chatOptionModal.tsx
|
||||||
function ChatOptionModal(chat, isPresented) {
|
function ChatOptionModal(chat, isPresented) {
|
||||||
function closeModal() {
|
function closeModal() {
|
||||||
isPresented.value = false;
|
isPresented.value = false;
|
||||||
@@ -1113,21 +1119,55 @@
|
|||||||
), /* @__PURE__ */ createElement("button", { class: "danger", "on:click": deleteChat }, translation.removeChat, /* @__PURE__ */ createElement("span", { class: "icon" }, "delete")))), /* @__PURE__ */ createElement("button", { "on:click": closeModal }, translation.close, /* @__PURE__ */ createElement("span", { class: "icon" }, "close"))));
|
), /* @__PURE__ */ createElement("button", { class: "danger", "on:click": deleteChat }, translation.removeChat, /* @__PURE__ */ createElement("span", { class: "icon" }, "delete")))), /* @__PURE__ */ createElement("button", { "on:click": closeModal }, translation.close, /* @__PURE__ */ createElement("span", { class: "icon" }, "close"))));
|
||||||
}
|
}
|
||||||
|
|
||||||
// src/Views/chatToolView.tsx
|
// src/Views/Chat/itemDetailModal.tsx
|
||||||
|
function ItemDetailModal(chat, object, isPresented) {
|
||||||
|
function closeModal() {
|
||||||
|
isPresented.value = false;
|
||||||
|
}
|
||||||
|
function saveAndClose() {
|
||||||
|
object.title = editingTitle.value;
|
||||||
|
chat.objects.set(object.id, object);
|
||||||
|
closeModal();
|
||||||
|
}
|
||||||
|
function deleteAndClose() {
|
||||||
|
chat.objects.remove(object.id);
|
||||||
|
closeModal();
|
||||||
|
}
|
||||||
|
const editingTitle = new State(object.title);
|
||||||
|
return /* @__PURE__ */ createElement("div", { class: "modal", "toggle:open": isPresented }, /* @__PURE__ */ createElement("div", null, /* @__PURE__ */ createElement("main", null, /* @__PURE__ */ createElement("h2", null, object.title), /* @__PURE__ */ createElement("div", null, /* @__PURE__ */ createElement("label", { class: "tile" }, /* @__PURE__ */ createElement("span", { class: "icon" }, "label"), /* @__PURE__ */ createElement("div", null, /* @__PURE__ */ createElement("span", null, translation.objectTitle), /* @__PURE__ */ createElement(
|
||||||
|
"input",
|
||||||
|
{
|
||||||
|
"bind:value": editingTitle,
|
||||||
|
placeholder: translation.objectTitlePlaceholder
|
||||||
|
}
|
||||||
|
)))), /* @__PURE__ */ createElement("hr", null), /* @__PURE__ */ createElement("button", { class: "danger", "on:click": deleteAndClose }, translation.deleteObject, /* @__PURE__ */ createElement("span", { class: "icon" }, "delete"))), /* @__PURE__ */ createElement("div", { class: "flex-row" }, /* @__PURE__ */ createElement("button", { class: "flex-1 width-100 danger", "on:click": closeModal }, translation.discard), /* @__PURE__ */ createElement("button", { class: "flex-1 width-100 primary", "on:click": saveAndClose }, translation.save, /* @__PURE__ */ createElement("span", { class: "icon" }, "save")))));
|
||||||
|
}
|
||||||
|
|
||||||
|
// src/Views/Chat/chatToolView.tsx
|
||||||
function ChatToolView(chat) {
|
function ChatToolView(chat) {
|
||||||
|
const isShowingObjectModal = new State(false);
|
||||||
|
const selectedObject = new State(void 0);
|
||||||
|
const objectModal = createProxyState([selectedObject], () => {
|
||||||
|
if (selectedObject.value == void 0) return /* @__PURE__ */ createElement("div", null);
|
||||||
|
return ItemDetailModal(chat, selectedObject.value, isShowingObjectModal);
|
||||||
|
});
|
||||||
function createItem() {
|
function createItem() {
|
||||||
chat.createItem({
|
chat.createObject({
|
||||||
id: UUID(),
|
id: UUID(),
|
||||||
title: "new item"
|
title: "new item"
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
const itemConverter = (item) => {
|
const itemConverter = (object) => {
|
||||||
return /* @__PURE__ */ createElement("span", null, item.title);
|
function select() {
|
||||||
|
selectedObject.value = object;
|
||||||
|
isShowingObjectModal.value = true;
|
||||||
|
}
|
||||||
|
return /* @__PURE__ */ createElement("button", { "on:click": select }, object.title);
|
||||||
};
|
};
|
||||||
return /* @__PURE__ */ createElement("div", { class: "chat-tool-view" }, /* @__PURE__ */ createElement("button", { "on:click": createItem }, "+"), /* @__PURE__ */ createElement("hr", null), /* @__PURE__ */ createElement("div", { "children:append": [chat.items, itemConverter] }));
|
return /* @__PURE__ */ createElement("div", { class: "chat-tool-view" }, /* @__PURE__ */ createElement("button", { "on:click": createItem }, "+"), /* @__PURE__ */ createElement("hr", null), /* @__PURE__ */ createElement("div", { "children:append": [chat.objects, itemConverter] }), /* @__PURE__ */ createElement("div", { "children:set": objectModal }));
|
||||||
}
|
}
|
||||||
|
|
||||||
// src/Views/messageComposer.tsx
|
// src/Views/Chat/messageComposer.tsx
|
||||||
function MessageComposer(chat) {
|
function MessageComposer(chat) {
|
||||||
return /* @__PURE__ */ createElement("div", { class: "flex-row width-100" }, " ", /* @__PURE__ */ createElement(
|
return /* @__PURE__ */ createElement("div", { class: "flex-row width-100" }, " ", /* @__PURE__ */ createElement(
|
||||||
"input",
|
"input",
|
||||||
@@ -1149,7 +1189,7 @@
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
// src/Views/threadView.tsx
|
// src/Views/Chat/threadView.tsx
|
||||||
function ThreadView(chat) {
|
function ThreadView(chat) {
|
||||||
const messageConverter = (message) => {
|
const messageConverter = (message) => {
|
||||||
function resendMessage() {
|
function resendMessage() {
|
||||||
@@ -1271,7 +1311,7 @@
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// src/Views/chatListSection.tsx
|
// src/Views/Overview/chatListSection.tsx
|
||||||
var chatConverter = (chat) => {
|
var chatConverter = (chat) => {
|
||||||
function select() {
|
function select() {
|
||||||
selectChat(chat);
|
selectChat(chat);
|
||||||
@@ -1318,7 +1358,7 @@
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
// src/Views/connectionSection.tsx
|
// src/Views/Overview/connectionSection.tsx
|
||||||
var addressConverter = (address) => {
|
var addressConverter = (address) => {
|
||||||
return /* @__PURE__ */ createElement("option", null, address);
|
return /* @__PURE__ */ createElement("option", null, address);
|
||||||
};
|
};
|
||||||
@@ -1385,7 +1425,7 @@
|
|||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
|
|
||||||
// src/Views/personalSection.tsx
|
// src/Views/Overview/personalSection.tsx
|
||||||
function PersonalSection() {
|
function PersonalSection() {
|
||||||
return /* @__PURE__ */ createElement("div", { class: "flex-column" }, /* @__PURE__ */ createElement("label", { class: "tile" }, /* @__PURE__ */ createElement("span", { class: "icon" }, "account_circle"), /* @__PURE__ */ createElement("div", null, /* @__PURE__ */ createElement("span", null, translation.yourName), /* @__PURE__ */ createElement(
|
return /* @__PURE__ */ createElement("div", { class: "flex-column" }, /* @__PURE__ */ createElement("label", { class: "tile" }, /* @__PURE__ */ createElement("span", { class: "icon" }, "account_circle"), /* @__PURE__ */ createElement("div", null, /* @__PURE__ */ createElement("span", null, translation.yourName), /* @__PURE__ */ createElement(
|
||||||
"input",
|
"input",
|
||||||
|
|||||||
+35
-39
@@ -22,19 +22,15 @@ export interface ChatMessage {
|
|||||||
body: string;
|
body: string;
|
||||||
isoDate: string;
|
isoDate: string;
|
||||||
|
|
||||||
itemData?: Item;
|
messageObject?: MessageObject;
|
||||||
}
|
}
|
||||||
|
|
||||||
// item
|
// object
|
||||||
export interface Item {
|
export interface MessageObject {
|
||||||
id: string;
|
id: string;
|
||||||
title: string;
|
title: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface NoteItem extends Item {
|
|
||||||
body: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
// chat
|
// chat
|
||||||
export class Chat {
|
export class Chat {
|
||||||
id: string;
|
id: string;
|
||||||
@@ -46,9 +42,9 @@ export class Chat {
|
|||||||
|
|
||||||
encryptionKey: React.State<string>;
|
encryptionKey: React.State<string>;
|
||||||
messages: React.ListState<ChatMessage>;
|
messages: React.ListState<ChatMessage>;
|
||||||
items: React.MapState<Item>;
|
objects: React.MapState<MessageObject>;
|
||||||
outbox: React.ListState<ChatMessage>;
|
outbox: React.ListState<ChatMessage>;
|
||||||
itemOutbox: React.ListState<ChatMessage>;
|
objectOutbox: React.ListState<ChatMessage>;
|
||||||
isOutBoxEmpty: React.State<boolean>;
|
isOutBoxEmpty: React.State<boolean>;
|
||||||
|
|
||||||
composingMessage: React.State<string>;
|
composingMessage: React.State<string>;
|
||||||
@@ -82,9 +78,9 @@ export class Chat {
|
|||||||
);
|
);
|
||||||
this.encryptionKey = React.restoreState(storageKeys.encyptionKey(id), "");
|
this.encryptionKey = React.restoreState(storageKeys.encyptionKey(id), "");
|
||||||
this.messages = React.restoreListState(storageKeys.messages(id));
|
this.messages = React.restoreListState(storageKeys.messages(id));
|
||||||
this.items = React.restoreMapState(storageKeys.items(id));
|
this.objects = React.restoreMapState(storageKeys.objects(id));
|
||||||
this.outbox = React.restoreListState(storageKeys.outbox(id));
|
this.outbox = React.restoreListState(storageKeys.outbox(id));
|
||||||
this.itemOutbox = React.restoreListState(storageKeys.itemOutbox(id));
|
this.objectOutbox = React.restoreListState(storageKeys.itemOutbox(id));
|
||||||
this.isOutBoxEmpty = React.createProxyState(
|
this.isOutBoxEmpty = React.createProxyState(
|
||||||
[this.outbox],
|
[this.outbox],
|
||||||
() => this.outbox.value.size == 0
|
() => this.outbox.value.size == 0
|
||||||
@@ -149,12 +145,12 @@ export class Chat {
|
|||||||
if (data.subscribed != undefined) this.handleSubscription(data.subscribed);
|
if (data.subscribed != undefined) this.handleSubscription(data.subscribed);
|
||||||
|
|
||||||
if (!data.messageBody) return;
|
if (!data.messageBody) return;
|
||||||
const { sender, body, channel, isoDate, itemData } = JSON.parse(
|
const { sender, body, channel, isoDate, messageObject } = JSON.parse(
|
||||||
data.messageBody
|
data.messageBody
|
||||||
);
|
);
|
||||||
|
|
||||||
if (itemData && itemData.id && itemData.title) {
|
if (messageObject && messageObject.id && messageObject.title) {
|
||||||
return this.handleItem(itemData);
|
return this.handleMessageObject(messageObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.handleMessage({
|
this.handleMessage({
|
||||||
@@ -178,14 +174,14 @@ export class Chat {
|
|||||||
if (selectedChat.value != this) this.hasUnreadMessages.value = true;
|
if (selectedChat.value != this) this.hasUnreadMessages.value = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
handleItem = (itemData: Item): void => {
|
handleMessageObject = (messageObject: MessageObject): void => {
|
||||||
this.items.set(itemData.id, itemData);
|
this.objects.set(messageObject.id, messageObject);
|
||||||
};
|
};
|
||||||
|
|
||||||
// messages
|
// messages
|
||||||
createMessage = async (
|
createChatMessage = async (
|
||||||
messageText: string,
|
messageText: string,
|
||||||
itemData?: Item
|
messageObject?: MessageObject
|
||||||
): Promise<ChatMessage> => {
|
): Promise<ChatMessage> => {
|
||||||
// get channels
|
// get channels
|
||||||
const secondaryChannelNames: string[] = [
|
const secondaryChannelNames: string[] = [
|
||||||
@@ -198,15 +194,15 @@ export class Chat {
|
|||||||
|
|
||||||
// create object
|
// create object
|
||||||
const joinedChannelName = allChannelNames.join("/");
|
const joinedChannelName = allChannelNames.join("/");
|
||||||
const messageObject: ChatMessage = {
|
const chatMessage: ChatMessage = {
|
||||||
channel: joinedChannelName,
|
channel: joinedChannelName,
|
||||||
sender: senderName.value,
|
sender: senderName.value,
|
||||||
body: messageText,
|
body: messageText,
|
||||||
isoDate: new Date().toISOString(),
|
isoDate: new Date().toISOString(),
|
||||||
};
|
};
|
||||||
|
|
||||||
if (itemData) messageObject.itemData = itemData;
|
if (messageObject) chatMessage.messageObject = messageObject;
|
||||||
return messageObject;
|
return chatMessage;
|
||||||
};
|
};
|
||||||
|
|
||||||
sendMessageFromComposer = async (): Promise<void> => {
|
sendMessageFromComposer = async (): Promise<void> => {
|
||||||
@@ -217,13 +213,13 @@ export class Chat {
|
|||||||
};
|
};
|
||||||
|
|
||||||
sendMessageFromText = async (text: string): Promise<void> => {
|
sendMessageFromText = async (text: string): Promise<void> => {
|
||||||
const message = await this.createMessage(text);
|
const chatMessage = await this.createChatMessage(text);
|
||||||
this.sendMessage(message);
|
this.sendMessage(chatMessage);
|
||||||
};
|
};
|
||||||
|
|
||||||
resendMessage = (message: ChatMessage) => {
|
resendMessage = (chatMessage: ChatMessage) => {
|
||||||
if (this.cannotResendMessage.value == true) return;
|
if (this.cannotResendMessage.value == true) return;
|
||||||
this.sendMessageFromText(message.body);
|
this.sendMessageFromText(chatMessage.body);
|
||||||
};
|
};
|
||||||
|
|
||||||
sendMessage = async (chatMessage: ChatMessage): Promise<void> => {
|
sendMessage = async (chatMessage: ChatMessage): Promise<void> => {
|
||||||
@@ -238,7 +234,7 @@ export class Chat {
|
|||||||
const messageString = JSON.stringify(chatMessage);
|
const messageString = JSON.stringify(chatMessage);
|
||||||
UDN.sendMessage(chatMessage.channel, messageString);
|
UDN.sendMessage(chatMessage.channel, messageString);
|
||||||
} else {
|
} else {
|
||||||
if (chatMessage.itemData) return this.itemOutbox.add(chatMessage);
|
if (chatMessage.messageObject) return this.objectOutbox.add(chatMessage);
|
||||||
this.outbox.add(chatMessage);
|
this.outbox.add(chatMessage);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -248,9 +244,9 @@ export class Chat {
|
|||||||
this.sendMessage(message);
|
this.sendMessage(message);
|
||||||
this.outbox.remove(message);
|
this.outbox.remove(message);
|
||||||
});
|
});
|
||||||
this.itemOutbox.value.forEach((message) => {
|
this.objectOutbox.value.forEach((message) => {
|
||||||
this.sendMessage(message);
|
this.sendMessage(message);
|
||||||
this.itemOutbox.remove(message);
|
this.objectOutbox.remove(message);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -258,25 +254,25 @@ export class Chat {
|
|||||||
this.messages.clear();
|
this.messages.clear();
|
||||||
};
|
};
|
||||||
|
|
||||||
deleteMessage = (message: ChatMessage): void => {
|
deleteMessage = (chatMessage: ChatMessage): void => {
|
||||||
this.messages.remove(message);
|
this.messages.remove(chatMessage);
|
||||||
};
|
};
|
||||||
|
|
||||||
deleteOutboxMessage = (message: ChatMessage): void => {
|
deleteOutboxMessage = (chatMessage: ChatMessage): void => {
|
||||||
this.outbox.remove(message);
|
this.outbox.remove(chatMessage);
|
||||||
};
|
};
|
||||||
|
|
||||||
decryptReceivedMessage = async (message: ChatMessage): Promise<void> => {
|
decryptReceivedMessage = async (chatMessage: ChatMessage): Promise<void> => {
|
||||||
message.body = await decryptString(message.body, this.encryptionKey.value);
|
chatMessage.body = await decryptString(chatMessage.body, this.encryptionKey.value);
|
||||||
this.messages.callSubscriptions();
|
this.messages.callSubscriptions();
|
||||||
};
|
};
|
||||||
|
|
||||||
// items
|
// objects
|
||||||
async createItem(item: Item): Promise<void> {
|
async createObject(object: MessageObject): Promise<void> {
|
||||||
this.items.set(item.id, item);
|
this.objects.set(object.id, object);
|
||||||
|
|
||||||
const message = await this.createMessage("", item);
|
const chatMessage = await this.createChatMessage("", object);
|
||||||
this.sendMessage(message);
|
this.sendMessage(chatMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
// channel
|
// channel
|
||||||
|
|||||||
@@ -1,26 +1,43 @@
|
|||||||
import * as React from "bloatless-react";
|
import * as React from "bloatless-react";
|
||||||
|
|
||||||
import { Chat, Item } from "../../Model/chatModel";
|
import { Chat, MessageObject } from "../../Model/chatModel";
|
||||||
|
|
||||||
|
import { ChatOptionModal } from "./chatOptionModal";
|
||||||
|
import { ItemDetailModal } from "./itemDetailModal";
|
||||||
import { translation } from "../../translations";
|
import { translation } from "../../translations";
|
||||||
|
|
||||||
export function ChatToolView(chat: Chat) {
|
export function ChatToolView(chat: Chat) {
|
||||||
|
const isShowingObjectModal = new React.State(false);
|
||||||
|
const selectedObject = new React.State<MessageObject | undefined>(undefined);
|
||||||
|
const objectModal = React.createProxyState([selectedObject], () => {
|
||||||
|
if (selectedObject.value == undefined) return <div></div>;
|
||||||
|
|
||||||
|
return ItemDetailModal(chat, selectedObject.value, isShowingObjectModal);
|
||||||
|
});
|
||||||
|
|
||||||
function createItem() {
|
function createItem() {
|
||||||
chat.createItem({
|
chat.createObject({
|
||||||
id: React.UUID(),
|
id: React.UUID(),
|
||||||
title: "new item",
|
title: "new item",
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const itemConverter: React.StateItemConverter<Item> = (item) => {
|
const itemConverter: React.StateItemConverter<MessageObject> = (object) => {
|
||||||
return <span>{item.title}</span>;
|
function select() {
|
||||||
|
selectedObject.value = object;
|
||||||
|
isShowingObjectModal.value = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return <button on:click={select}>{object.title}</button>;
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div class="chat-tool-view">
|
<div class="chat-tool-view">
|
||||||
<button on:click={createItem}>+</button>
|
<button on:click={createItem}>+</button>
|
||||||
<hr></hr>
|
<hr></hr>
|
||||||
<div children:append={[chat.items, itemConverter]}></div>
|
<div children:append={[chat.objects, itemConverter]}></div>
|
||||||
|
|
||||||
|
<div children:set={objectModal}></div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,68 @@
|
|||||||
|
import * as React from "bloatless-react";
|
||||||
|
|
||||||
|
import { Chat, MessageObject } from "../../Model/chatModel";
|
||||||
|
|
||||||
|
import { translation } from "../../translations";
|
||||||
|
|
||||||
|
export function ItemDetailModal(
|
||||||
|
chat: Chat,
|
||||||
|
object: MessageObject,
|
||||||
|
isPresented: React.State<boolean>
|
||||||
|
) {
|
||||||
|
function closeModal() {
|
||||||
|
isPresented.value = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
function saveAndClose() {
|
||||||
|
object.title = editingTitle.value;
|
||||||
|
chat.objects.set(object.id, object);
|
||||||
|
closeModal();
|
||||||
|
}
|
||||||
|
|
||||||
|
function deleteAndClose() {
|
||||||
|
chat.objects.remove(object.id);
|
||||||
|
closeModal();
|
||||||
|
}
|
||||||
|
|
||||||
|
const editingTitle = new React.State(object.title);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div class="modal" toggle:open={isPresented}>
|
||||||
|
<div>
|
||||||
|
<main>
|
||||||
|
<h2>{object.title}</h2>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<label class="tile">
|
||||||
|
<span class="icon">label</span>
|
||||||
|
<div>
|
||||||
|
<span>{translation.objectTitle}</span>
|
||||||
|
<input
|
||||||
|
bind:value={editingTitle}
|
||||||
|
placeholder={translation.objectTitlePlaceholder}
|
||||||
|
></input>
|
||||||
|
</div>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<hr></hr>
|
||||||
|
|
||||||
|
<button class="danger" on:click={deleteAndClose}>
|
||||||
|
{translation.deleteObject}
|
||||||
|
<span class="icon">delete</span>
|
||||||
|
</button>
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<div class="flex-row">
|
||||||
|
<button class="flex-1 width-100 danger" on:click={closeModal}>
|
||||||
|
{translation.discard}
|
||||||
|
</button>
|
||||||
|
<button class="flex-1 width-100 primary" on:click={saveAndClose}>
|
||||||
|
{translation.save}
|
||||||
|
<span class="icon">save</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
+10
-1
@@ -1,9 +1,11 @@
|
|||||||
const englishTranslations = {
|
const englishTranslations = {
|
||||||
// general
|
// general
|
||||||
set: "Set",
|
set: "Set",
|
||||||
|
save: "Save",
|
||||||
back: "Back",
|
back: "Back",
|
||||||
undoChanges: "Undo changes",
|
undoChanges: "Undo changes",
|
||||||
close: "Close",
|
close: "Close",
|
||||||
|
discard: "Discard",
|
||||||
|
|
||||||
// overview
|
// overview
|
||||||
overview: "Overview",
|
overview: "Overview",
|
||||||
@@ -36,7 +38,6 @@ const englishTranslations = {
|
|||||||
|
|
||||||
// messages
|
// messages
|
||||||
showChatOptions: "show chat options",
|
showChatOptions: "show chat options",
|
||||||
toggleChatTools: "toggle chat tools",
|
|
||||||
configureChatTitle: "Configure Chat",
|
configureChatTitle: "Configure Chat",
|
||||||
|
|
||||||
secondaryChannel: "Secondary channel",
|
secondaryChannel: "Secondary channel",
|
||||||
@@ -62,6 +63,14 @@ const englishTranslations = {
|
|||||||
decryptMessage: "Decrypt message",
|
decryptMessage: "Decrypt message",
|
||||||
copyMessage: "Copy message",
|
copyMessage: "Copy message",
|
||||||
deleteMessage: "Delete message",
|
deleteMessage: "Delete message",
|
||||||
|
|
||||||
|
// objects
|
||||||
|
toggleChatTools: "toggle chat tools",
|
||||||
|
|
||||||
|
objectTitle: "Object title",
|
||||||
|
objectTitlePlaceholder: "My object",
|
||||||
|
|
||||||
|
deleteObject: "Delete object",
|
||||||
};
|
};
|
||||||
|
|
||||||
const allTranslations: { [key: string]: typeof englishTranslations } = {
|
const allTranslations: { [key: string]: typeof englishTranslations } = {
|
||||||
|
|||||||
+1
-1
@@ -19,7 +19,7 @@ export const storageKeys = {
|
|||||||
return id + "messages";
|
return id + "messages";
|
||||||
},
|
},
|
||||||
|
|
||||||
items(id: string): string {
|
objects(id: string): string {
|
||||||
return id + "items";
|
return id + "items";
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user