From c21d6657763be683ce468e3466d677fa2bb279df Mon Sep 17 00:00:00 2001 From: marlon-erler Date: Mon, 22 Jul 2024 03:01:04 +0200 Subject: [PATCH] remodel storage location map --- dist/index.js | 357 ++++++++++++++++++---------- src/Model/Chat/chatListModel.ts | 4 +- src/Model/Chat/chatModel.ts | 142 +++++------ src/Model/Files/fileModel.ts | 41 ++-- src/Model/Global/connectionModel.ts | 66 +++-- src/Model/Global/settingsModel.ts | 24 +- src/Model/Global/storageModel.ts | 79 +++--- src/ViewModel/chatViewModel.ts | 11 +- 8 files changed, 452 insertions(+), 272 deletions(-) diff --git a/dist/index.js b/dist/index.js index 19a88d57..6905f988 100644 --- a/dist/index.js +++ b/dist/index.js @@ -395,11 +395,7 @@ if (object == null) return null; return object; }; - // init - constructor() { - this.initializeTree(); - } - // utility + // tree initializeTree = () => { console.log("initializing tree"); this.storageEntryTree = {}; @@ -420,6 +416,11 @@ printTree = () => { return stringify(this.storageEntryTree); }; + // init + constructor() { + this.initializeTree(); + } + // utility static getFileName = (pathComponents) => { return pathComponents[pathComponents.length - 1] || "\\"; }; @@ -441,6 +442,39 @@ } return _StorageModel.pathComponentsToString(...allComponents); }; + static getPath(locationName, filePath) { + return [DATA_VERSION, storageLocations[locationName], ...filePath]; + } + }; + var storageLocations = { + connectionModel: "connection", + chat: "chat", + settingsModel: "settings" + }; + var filePaths = { + connectionModel: { + socketAddress: ["socket-address"], + reconnectAddress: ["reconnect-address"], + outbox: ["outbox"], + mailboxes: ["mailboxes"], + previousAddresses: ["previous-addresses"] + }, + chat: { + base: [], + chatBase: (id) => [id], + info: (id) => [...filePaths.chat.chatBase(id), "info"], + color: (id) => [...filePaths.chat.chatBase(id), "color"], + messages: (id) => [...filePaths.chat.chatBase(id), "messages"], + files: (id) => [...filePaths.chat.chatBase(id), "files"], + lastUsedPage: (id) => [ + ...filePaths.chat.chatBase(id), + "last-used-page" + ] + }, + settingsModel: { + username: ["user-name"], + firstDayOfWeek: ["first-day-of-week"] + } }; var storageKeys = { // connection @@ -467,10 +501,36 @@ chatFiles: [DATA_VERSION, "chat", "files"] }; + // src/Model/Files/taskModel.ts + var TaskModel = class { + chatModel; + fileModel; + // init + constructor(chatModel, fileModel) { + this.chatModel = chatModel; + this.fileModel = fileModel; + } + }; + // src/Model/Files/fileModel.ts var FileModel = class _FileModel { chatModel; storageModel; + taskModel; + // paths + getBasePath = () => { + return StorageModel.getPath( + "chat", + filePaths.chat.files(this.chatModel.id) + ); + }; + getFilePath = (fileId) => { + return [...this.getBasePath(), fileId]; + }; + getFileContentPath = (file, fileContentName) => { + const filePath = this.getFilePath(file.id); + return [...filePath, fileContentName]; + }; // handler handleStringifiedFile = (stringifiedFile) => { const file = parseValidObject(stringifiedFile, FileReference); @@ -489,7 +549,7 @@ }; storeFileContent = (file, fileContent) => { const fileContentName = _FileModel.getFileContentName(fileContent); - const fileContentPath = _FileModel.getFileContentPath( + const fileContentPath = this.getFileContentPath( file, fileContentName ); @@ -499,14 +559,14 @@ this.storageModel.write(fileContentPath, stringifiedContent); }; listFileIds = () => { - return this.storageModel.list(storageKeys.chatFiles); + return this.storageModel.list(this.getBasePath()); }; listFileContents = (file) => { - const filePath = _FileModel.getFilePath(file.id); + const filePath = this.getFilePath(file.id); return this.storageModel.list(filePath); }; getFile = (fileId) => { - const filePath = _FileModel.getFilePath(fileId); + const filePath = this.getFilePath(fileId); const fileOrNull = this.storageModel.readStringifiable( filePath, FileReference @@ -517,7 +577,7 @@ return fileContentNames[fileContentNames.length - 1]; }; getFileContent = (file, fileContentName) => { - const filePath = _FileModel.getFileContentPath(file, fileContentName); + const filePath = this.getFileContentPath(file, fileContentName); const fileContentOrNull = this.storageModel.readStringifiable(filePath, FileContentReference); return fileContentOrNull; }; @@ -525,18 +585,12 @@ constructor(chatModel, storageModel2) { this.chatModel = chatModel; this.storageModel = storageModel2; + this.taskModel = new TaskModel(chatModel, this); } // utility - static getFilePath = (fileId) => { - return [...storageKeys.chatFiles, fileId]; - }; static getFileContentName = (fileContent) => { return fileContent.creationDate + fileContent.id; }; - static getFileContentPath = (file, fileContentName) => { - const filePath = _FileModel.getFilePath(file.id); - return [...filePath, fileContentName]; - }; static createFile = () => { return { dataVersion: DATA_VERSION, @@ -655,26 +709,29 @@ color; chatMessageHandler = () => { }; + // paths + getBasePath = () => { + return StorageModel.getPath("chat", filePaths.chat.chatBase(this.id)); + }; + getInfoPath = () => { + return StorageModel.getPath("chat", filePaths.chat.info(this.id)); + }; + getColorPath = () => { + return StorageModel.getPath("chat", filePaths.chat.color(this.id)); + }; + getMessageDirPath = () => { + return StorageModel.getPath("chat", filePaths.chat.messages(this.id)); + }; + getMessagePath = (id) => { + return [...this.getMessageDirPath(), id]; + }; // sorting get index() { return this.chatListModel.getIndexOfPrimaryChannel( this.info.primaryChannel ); } - // paths - get infoPath() { - return storageKeys.chatInfo(this.id); - } - get colorPath() { - return storageKeys.chatColor(this.id); - } - get messageDirPath() { - return storageKeys.chatMessages(this.id); - } - getMessagePath = (id) => { - return [...this.messageDirPath, id]; - }; - // set + // settings setPrimaryChannel = (primaryChannel) => { this.info.primaryChannel = primaryChannel; this.storeInfo(); @@ -693,63 +750,6 @@ this.color = color; this.storeColor(); }; - // store & add - storeInfo = () => { - this.storageModel.writeStringifiable(this.infoPath, this.info); - }; - storeColor = () => { - this.storageModel.write(this.colorPath, this.color); - }; - addMessage = async (chatMessage) => { - await this.decryptMessage(chatMessage); - if (chatMessage.body != "") { - const messagePath = this.getMessagePath(chatMessage.id); - this.storageModel.writeStringifiable(messagePath, chatMessage); - this.chatMessageHandler(chatMessage); - } - this.fileModel.handleStringifiedFile(chatMessage.stringifiedFile); - }; - // delete - delete = () => { - this.chatListModel.untrackChat(this); - const dirPath = [...storageKeys.chats, this.id]; - this.storageModel.removeRecursively(dirPath); - }; - // load - loadInfo = () => { - const info = this.storageModel.readStringifiable( - this.infoPath, - ChatInfoReference - ); - if (info != null) { - this.info = info; - } else { - this.info = _ChatModel.generateChatInfo("0"); - } - }; - loadColor = () => { - const path = this.colorPath; - const color = this.storageModel.read(path); - if (!color) { - this.color = "standard" /* Standard */; - } else { - this.color = color; - } - }; - get messages() { - const messageIds = this.storageModel.list(this.messageDirPath); - if (!Array.isArray(messageIds)) return []; - const chatMessages = []; - for (const messageId of messageIds) { - const messagePath = this.getMessagePath(messageId); - const chatMessage = this.storageModel.readStringifiable(messagePath, ChatMessageReference); - chatMessages.push(chatMessage); - } - const sorted = chatMessages.sort( - (a, b) => a.dateSent.localeCompare(b.dateSent) - ); - return sorted; - } // messaging sendMessage = async (body, file) => { const senderName = this.settingsModel.username; @@ -801,6 +801,64 @@ subscribe = () => { this.connectionModel.addChannel(this.info.primaryChannel); }; + // storage + storeInfo = () => { + this.storageModel.writeStringifiable(this.getInfoPath(), this.info); + }; + storeColor = () => { + this.storageModel.write(this.getColorPath(), this.color); + }; + addMessage = async (chatMessage) => { + await this.decryptMessage(chatMessage); + if (chatMessage.body != "") { + const messagePath = this.getMessagePath(chatMessage.id); + this.storageModel.writeStringifiable(messagePath, chatMessage); + this.chatMessageHandler(chatMessage); + } + this.fileModel.handleStringifiedFile(chatMessage.stringifiedFile); + }; + delete = () => { + this.chatListModel.untrackChat(this); + const dirPath = this.getBasePath(); + this.storageModel.removeRecursively(dirPath); + }; + // load + loadInfo = () => { + const info = this.storageModel.readStringifiable( + this.getInfoPath(), + ChatInfoReference + ); + if (info != null) { + this.info = info; + } else { + this.info = _ChatModel.generateChatInfo("0"); + } + }; + loadColor = () => { + const path = this.getColorPath(); + const color = this.storageModel.read(path); + if (!color) { + this.color = "standard" /* Standard */; + } else { + this.color = color; + } + }; + get messages() { + const messageIds = this.storageModel.list( + this.getMessageDirPath() + ); + if (!Array.isArray(messageIds)) return []; + const chatMessages = []; + for (const messageId of messageIds) { + const messagePath = this.getMessagePath(messageId); + const chatMessage = this.storageModel.readStringifiable(messagePath, ChatMessageReference); + chatMessages.push(chatMessage); + } + const sorted = chatMessages.sort( + (a, b) => a.dateSent.localeCompare(b.dateSent) + ); + return sorted; + } // init constructor(storageModel2, connectionModel2, settingsModel2, chatListModel2, chatId) { this.id = chatId; @@ -890,7 +948,19 @@ } } }; - // store & add + // sorting + updateIndices = () => { + this.sortedPrimaryChannels = []; + let allChannels = []; + for (const chatModel of this.chatModels) { + allChannels.push(chatModel.info.primaryChannel); + } + this.sortedPrimaryChannels = allChannels.sort(localeCompare); + }; + getIndexOfPrimaryChannel(primaryChannel) { + return this.sortedPrimaryChannels.indexOf(primaryChannel); + } + // storage addChatModel = (chatModel) => { this.chatModels.add(chatModel); this.updateIndices(); @@ -912,21 +982,9 @@ this.chatModels.delete(chat); this.updateIndices(); }; - // sorting - updateIndices = () => { - this.sortedPrimaryChannels = []; - let allChannels = []; - for (const chatModel of this.chatModels) { - allChannels.push(chatModel.info.primaryChannel); - } - this.sortedPrimaryChannels = allChannels.sort(localeCompare); - }; - getIndexOfPrimaryChannel(primaryChannel) { - return this.sortedPrimaryChannels.indexOf(primaryChannel); - } // load loadChats = () => { - const chatDir = storageKeys.chats; + const chatDir = StorageModel.getPath("chat", filePaths.chat.base); const chatIds = this.storageModel.list(chatDir); for (const chatId of chatIds) { const chatModel = new ChatModel( @@ -1844,15 +1902,7 @@ messageSentHandler = () => { }; channelsToSubscribe = /* @__PURE__ */ new Set(); - // connection - connect = (address) => { - this.udn.connect(address); - }; - disconnect = () => { - this.udn.disconnect(); - const reconnectAddressPath = storageKeys.reconnectAddress; - this.storageModel.remove(reconnectAddressPath); - }; + // handlers handleMessage = (data) => { this.messageHandler(data); }; @@ -1866,23 +1916,41 @@ this.sendSubscriptionRequest(); this.sendMessagesInOutbox(); }; + // connection + connect = (address) => { + this.udn.connect(address); + }; + disconnect = () => { + this.udn.disconnect(); + const reconnectAddressPath = StorageModel.getPath( + "connectionModel", + filePaths.connectionModel.reconnectAddress + ); + this.storageModel.remove(reconnectAddressPath); + }; // mailbox + getMailboxPath = (address) => { + const mailboxDirPath = StorageModel.getPath( + "connectionModel", + filePaths.connectionModel.mailboxes + ); + const mailboxFilePath = [...mailboxDirPath, address]; + return mailboxFilePath; + }; requestNewMailbox = () => { console.trace("requesting mailbox"); this.udn.requestMailbox(); }; connectMailbox = () => { if (this.address == void 0) return; - const path = [...storageKeys.mailboxes, this.address]; - const mailboxId = this.storageModel.read(path); + const mailboxId = this.storageModel.read(this.getMailboxPath(this.address)); console.log("connecting mailbox", mailboxId); if (mailboxId == null) return this.requestNewMailbox(); this.udn.connectMailbox(mailboxId); }; storeMailbox = (mailboxId) => { if (this.address == void 0) return; - const path = [...storageKeys.mailboxes, this.address]; - this.storageModel.write(path, mailboxId); + this.storageModel.write(this.getMailboxPath(this.address), mailboxId); }; // subscription addChannel = (channel) => { @@ -1897,8 +1965,14 @@ this.connectMailbox(); }; // outbox + getOutboxPath = () => { + return StorageModel.getPath( + "connectionModel", + filePaths.connectionModel.outbox + ); + }; getOutboxMessags = () => { - const outboxPath = storageKeys.outbox; + const outboxPath = this.getOutboxPath(); const messageIds = this.storageModel.list(outboxPath); let chatMessages = []; for (const messageId of messageIds) { @@ -1912,11 +1986,11 @@ return chatMessages; }; addToOutbox = (chatMessage) => { - const messagePath = [...storageKeys.outbox, chatMessage.id]; + const messagePath = [...this.getOutboxPath(), chatMessage.id]; this.storageModel.writeStringifiable(messagePath, chatMessage); }; removeFromOutbox = (chatMessage) => { - const messagePath = [...storageKeys.outbox, chatMessage.id]; + const messagePath = [...this.getOutboxPath(), chatMessage.id]; this.storageModel.remove(messagePath); }; sendMessagesInOutbox = () => { @@ -1943,14 +2017,26 @@ return isSent; }; // storage + getPreviousAddressPath = () => { + return StorageModel.getPath( + "connectionModel", + filePaths.connectionModel.previousAddresses + ); + }; getAddressPath = (address) => { - const dirPath = storageKeys.previousAddresses; + const dirPath = this.getPreviousAddressPath(); return [...dirPath, address]; }; + getReconnectAddressPath = () => { + return StorageModel.getPath( + "connectionModel", + filePaths.connectionModel.reconnectAddress + ); + }; storeAddress = (address) => { const addressPath = this.getAddressPath(address); this.storageModel.write(addressPath, ""); - const reconnectAddressPath = storageKeys.reconnectAddress; + const reconnectAddressPath = this.getReconnectAddressPath(); this.storageModel.write(reconnectAddressPath, address); }; removeAddress = (address) => { @@ -1958,10 +2044,10 @@ this.storageModel.remove(addressPath); }; get addresses() { - const dirPath = storageKeys.previousAddresses; + const dirPath = this.getPreviousAddressPath(); return this.storageModel.list(dirPath); } - // handlers + // other setConnectionChangeHandler = (handler) => { this.connectionChangeHandler = handler; }; @@ -1971,7 +2057,7 @@ setMessageSentHandler = (handler) => { this.messageSentHandler = handler; }; - // setup + // init constructor(storageModel2) { this.udn = new UDNFrontend(); this.storageModel = storageModel2; @@ -1996,7 +2082,7 @@ this.udn.onmailboxconnect = (mailboxId) => { console.log(`using mailbox ${mailboxId}`); }; - const reconnectAddressPath = storageKeys.reconnectAddress; + const reconnectAddressPath = this.getPreviousAddressPath(); const reconnectAddress = storageModel2.read(reconnectAddressPath); if (reconnectAddress != null) { this.connect(reconnectAddress); @@ -2201,27 +2287,40 @@ // src/Model/Global/settingsModel.ts var SettingsModel = class { storageModel; + // data username; firstDayOfWeek; - // set + // storage setName(newValue) { this.username = newValue; - const path = storageKeys.username; + const path = StorageModel.getPath( + "settingsModel", + filePaths.settingsModel.username + ); this.storageModel.write(path, newValue); } setFirstDayOfWeek(newValue) { this.firstDayOfWeek = newValue; - const path = storageKeys.firstDayOfWeek; + const path = StorageModel.getPath( + "settingsModel", + filePaths.settingsModel.firstDayOfWeek + ); this.storageModel.write(path, newValue); } // load loadUsernam() { - const path = storageKeys.username; + const path = StorageModel.getPath( + "settingsModel", + filePaths.settingsModel.username + ); const content = this.storageModel.read(path); this.username = content ?? ""; } loadFirstDayofWeek() { - const path = storageKeys.firstDayOfWeek; + const path = StorageModel.getPath( + "settingsModel", + filePaths.settingsModel.firstDayOfWeek + ); const content = this.storageModel.read(path); this.firstDayOfWeek = content ?? "0"; } diff --git a/src/Model/Chat/chatListModel.ts b/src/Model/Chat/chatListModel.ts index ca6803a4..5afadef3 100644 --- a/src/Model/Chat/chatListModel.ts +++ b/src/Model/Chat/chatListModel.ts @@ -1,4 +1,4 @@ -import StorageModel, { storageKeys } from "../Global/storageModel"; +import StorageModel, { filePaths } from "../Global/storageModel"; import ChatModel from "./chatModel"; import ConnectionModel from "../Global/connectionModel"; @@ -78,7 +78,7 @@ export default class ChatListModel { // load loadChats = (): void => { - const chatDir = storageKeys.chats; + const chatDir = StorageModel.getPath("chat", filePaths.chat.base); const chatIds = this.storageModel.list(chatDir); for (const chatId of chatIds) { const chatModel = new ChatModel( diff --git a/src/Model/Chat/chatModel.ts b/src/Model/Chat/chatModel.ts index 9924f776..b6f32944 100644 --- a/src/Model/Chat/chatModel.ts +++ b/src/Model/Chat/chatModel.ts @@ -2,7 +2,7 @@ import { DATA_VERSION, ValidObject } from "../Utility/typeSafety"; import FileModel, { File } from "../Files/fileModel"; -import StorageModel, { storageKeys } from "../Global/storageModel"; +import StorageModel, { filePaths } from "../Global/storageModel"; import { createTimestamp, parseValidObject, @@ -32,20 +32,24 @@ export default class ChatModel { chatMessageHandler: (chatMessage: ChatMessage) => void = () => {}; // paths - get infoPath(): string[] { - return storageKeys.chatInfo(this.id); - } + getBasePath = (): string[] => { + return StorageModel.getPath("chat", filePaths.chat.chatBase(this.id)); + }; - get colorPath(): string[] { - return storageKeys.chatColor(this.id); - } + getInfoPath = (): string[] => { + return StorageModel.getPath("chat", filePaths.chat.info(this.id)); + }; - get messageDirPath(): string[] { - return storageKeys.chatMessages(this.id); - } + getColorPath = (): string[] => { + return StorageModel.getPath("chat", filePaths.chat.color(this.id)); + }; + + getMessageDirPath = (): string[] => { + return StorageModel.getPath("chat", filePaths.chat.messages(this.id)); + }; getMessagePath = (id: string): string[] => { - return [...this.messageDirPath, id]; + return [...this.getMessageDirPath(), id]; }; // sorting @@ -78,75 +82,75 @@ export default class ChatModel { this.storeColor(); }; -// messaging -sendMessage = async (body: string, file?: File): Promise => { - const senderName = this.settingsModel.username; - if (senderName == "") return false; + // messaging + sendMessage = async (body: string, file?: File): Promise => { + const senderName = this.settingsModel.username; + if (senderName == "") return false; - const allChannels = [this.info.primaryChannel]; - for (const secondaryChannel of this.info.secondaryChannels) { - allChannels.push(secondaryChannel); - } + const allChannels = [this.info.primaryChannel]; + for (const secondaryChannel of this.info.secondaryChannels) { + allChannels.push(secondaryChannel); + } - const combinedChannel: string = allChannels.join("/"); + const combinedChannel: string = allChannels.join("/"); - const chatMessage: ChatMessage = await ChatModel.createChatMessage( - combinedChannel, - senderName, - this.info.encryptionKey, - body, - file - ); + const chatMessage: ChatMessage = await ChatModel.createChatMessage( + combinedChannel, + senderName, + this.info.encryptionKey, + body, + file + ); - this.addMessage(chatMessage); - this.connectionModel.sendMessageOrStore(chatMessage); - return true; -}; + this.addMessage(chatMessage); + this.connectionModel.sendMessageOrStore(chatMessage); + return true; + }; -handleMessage = (body: string): void => { - const chatMessage: ChatMessage | null = parseValidObject( - body, - ChatMessageReference - ); - if (chatMessage == null) return; + handleMessage = (body: string): void => { + const chatMessage: ChatMessage | null = parseValidObject( + body, + ChatMessageReference + ); + if (chatMessage == null) return; - chatMessage.status = ChatMessageStatus.Received; - this.addMessage(chatMessage); -}; + chatMessage.status = ChatMessageStatus.Received; + this.addMessage(chatMessage); + }; -handleMessageSent = (chatMessage: ChatMessage): void => { - chatMessage.status = ChatMessageStatus.Sent; - this.addMessage(chatMessage); -}; + handleMessageSent = (chatMessage: ChatMessage): void => { + chatMessage.status = ChatMessageStatus.Sent; + this.addMessage(chatMessage); + }; -decryptMessage = async (chatMessage: ChatMessage): Promise => { - const decryptedBody: string = await decryptString( - chatMessage.body, - this.info.encryptionKey - ); - const decryptedFile: string = await decryptString( - chatMessage.stringifiedFile ?? "", - this.info.encryptionKey - ); - chatMessage.body = decryptedBody; - chatMessage.stringifiedFile = decryptedFile; -}; + decryptMessage = async (chatMessage: ChatMessage): Promise => { + const decryptedBody: string = await decryptString( + chatMessage.body, + this.info.encryptionKey + ); + const decryptedFile: string = await decryptString( + chatMessage.stringifiedFile ?? "", + this.info.encryptionKey + ); + chatMessage.body = decryptedBody; + chatMessage.stringifiedFile = decryptedFile; + }; -setMessageHandler = (handler: (chatMessage: ChatMessage) => void): void => { - this.chatMessageHandler = handler; -}; + setMessageHandler = (handler: (chatMessage: ChatMessage) => void): void => { + this.chatMessageHandler = handler; + }; -subscribe = (): void => { - this.connectionModel.addChannel(this.info.primaryChannel); -}; + subscribe = (): void => { + this.connectionModel.addChannel(this.info.primaryChannel); + }; // storage storeInfo = (): void => { - this.storageModel.writeStringifiable(this.infoPath, this.info); + this.storageModel.writeStringifiable(this.getInfoPath(), this.info); }; storeColor = (): void => { - this.storageModel.write(this.colorPath, this.color); + this.storageModel.write(this.getColorPath(), this.color); }; addMessage = async (chatMessage: ChatMessage): Promise => { @@ -168,14 +172,14 @@ subscribe = (): void => { this.chatListModel.untrackChat(this); // delete - const dirPath: string[] = [...storageKeys.chats, this.id]; + const dirPath: string[] = this.getBasePath(); this.storageModel.removeRecursively(dirPath); }; // load loadInfo = (): void => { const info: ChatInfo | null = this.storageModel.readStringifiable( - this.infoPath, + this.getInfoPath(), ChatInfoReference ); if (info != null) { @@ -186,7 +190,7 @@ subscribe = (): void => { }; loadColor = (): void => { - const path: string[] = this.colorPath; + const path: string[] = this.getColorPath(); const color: string | null = this.storageModel.read(path); if (!color) { this.color = Color.Standard; @@ -196,7 +200,9 @@ subscribe = (): void => { }; get messages(): ChatMessage[] { - const messageIds: string[] = this.storageModel.list(this.messageDirPath); + const messageIds: string[] = this.storageModel.list( + this.getMessageDirPath() + ); if (!Array.isArray(messageIds)) return []; const chatMessages: ChatMessage[] = []; diff --git a/src/Model/Files/fileModel.ts b/src/Model/Files/fileModel.ts index dfb46e44..9d4f9426 100644 --- a/src/Model/Files/fileModel.ts +++ b/src/Model/Files/fileModel.ts @@ -1,7 +1,7 @@ // this file is responsible for managing files within chats. import { DATA_VERSION, ValidObject } from "../Utility/typeSafety"; -import StorageModel, { storageKeys } from "../Global/storageModel"; +import StorageModel, { filePaths } from "../Global/storageModel"; import { parseValidObject, stringify } from "../Utility/utility"; import ChatModel from "../Chat/chatModel"; @@ -14,6 +14,23 @@ export default class FileModel { taskModel: TaskModel; + // paths + getBasePath = (): string[] => { + return StorageModel.getPath( + "chat", + filePaths.chat.files(this.chatModel.id) + ); + }; + + getFilePath = (fileId: string): string[] => { + return [...this.getBasePath(), fileId]; + }; + + getFileContentPath = (file: File, fileContentName: string): string[] => { + const filePath: string[] = this.getFilePath(file.id); + return [...filePath, fileContentName]; + }; + // handler handleStringifiedFile = (stringifiedFile: string): void => { const file: File | null = parseValidObject(stringifiedFile, FileReference); @@ -36,7 +53,7 @@ export default class FileModel { storeFileContent = (file: File, fileContent: FileContent): void => { const fileContentName: string = FileModel.getFileContentName(fileContent); - const fileContentPath: string[] = FileModel.getFileContentPath( + const fileContentPath: string[] = this.getFileContentPath( file, fileContentName ); @@ -51,16 +68,16 @@ export default class FileModel { }; listFileIds = (): string[] => { - return this.storageModel.list(storageKeys.chatFiles); + return this.storageModel.list(this.getBasePath()); }; listFileContents = (file: File): string[] => { - const filePath: string[] = FileModel.getFilePath(file.id); + const filePath: string[] = this.getFilePath(file.id); return this.storageModel.list(filePath); }; getFile = (fileId: string): File | null => { - const filePath = FileModel.getFilePath(fileId); + const filePath = this.getFilePath(fileId); const fileOrNull: File | null = this.storageModel.readStringifiable( filePath, FileReference @@ -76,7 +93,7 @@ export default class FileModel { file: File, fileContentName: string ): FileContent | null => { - const filePath = FileModel.getFileContentPath(file, fileContentName); + const filePath = this.getFileContentPath(file, fileContentName); const fileContentOrNull: FileContent | null = this.storageModel.readStringifiable(filePath, FileContentReference); return fileContentOrNull; @@ -91,22 +108,10 @@ export default class FileModel { } // utility - static getFilePath = (fileId: string): string[] => { - return [...storageKeys.chatFiles, fileId]; - }; - static getFileContentName = (fileContent: FileContent): string => { return fileContent.creationDate + fileContent.id; }; - static getFileContentPath = ( - file: File, - fileContentName: string - ): string[] => { - const filePath: string[] = FileModel.getFilePath(file.id); - return [...filePath, fileContentName]; - }; - static createFile = (): File => { return { dataVersion: DATA_VERSION, diff --git a/src/Model/Global/connectionModel.ts b/src/Model/Global/connectionModel.ts index d76afd55..0cf3dc17 100644 --- a/src/Model/Global/connectionModel.ts +++ b/src/Model/Global/connectionModel.ts @@ -1,7 +1,7 @@ // this file is responsible for managing UDN connections. import { ChatMessage, ChatMessageReference } from "../Chat/chatModel"; -import StorageModel, { storageKeys } from "./storageModel"; +import StorageModel, { filePaths } from "./storageModel"; import UDNFrontend, { Message } from "udn-frontend"; import { stringify } from "../Utility/utility"; @@ -52,11 +52,23 @@ export default class ConnectionModel { this.udn.disconnect(); // do not reconnect - const reconnectAddressPath: string[] = storageKeys.reconnectAddress; + const reconnectAddressPath: string[] = StorageModel.getPath( + "connectionModel", + filePaths.connectionModel.reconnectAddress + ); this.storageModel.remove(reconnectAddressPath); }; // mailbox + getMailboxPath = (address: string): string[] => { + const mailboxDirPath = StorageModel.getPath( + "connectionModel", + filePaths.connectionModel.mailboxes + ); + const mailboxFilePath = [...mailboxDirPath, address]; + return mailboxFilePath; + }; + requestNewMailbox = (): void => { console.trace("requesting mailbox"); this.udn.requestMailbox(); @@ -64,8 +76,8 @@ export default class ConnectionModel { connectMailbox = (): void => { if (this.address == undefined) return; - const path = [...storageKeys.mailboxes, this.address]; - const mailboxId = this.storageModel.read(path); + + const mailboxId = this.storageModel.read(this.getMailboxPath(this.address)); console.log("connecting mailbox", mailboxId); if (mailboxId == null) return this.requestNewMailbox(); @@ -74,8 +86,7 @@ export default class ConnectionModel { storeMailbox = (mailboxId: string): void => { if (this.address == undefined) return; - const path = [...storageKeys.mailboxes, this.address]; - this.storageModel.write(path, mailboxId); + this.storageModel.write(this.getMailboxPath(this.address), mailboxId); }; // subscription @@ -95,8 +106,15 @@ export default class ConnectionModel { }; // outbox + getOutboxPath = (): string[] => { + return StorageModel.getPath( + "connectionModel", + filePaths.connectionModel.outbox + ); + }; + getOutboxMessags = (): ChatMessage[] => { - const outboxPath: string[] = storageKeys.outbox; + const outboxPath: string[] = this.getOutboxPath(); const messageIds: string[] = this.storageModel.list(outboxPath); let chatMessages: ChatMessage[] = []; @@ -115,12 +133,12 @@ export default class ConnectionModel { }; addToOutbox = (chatMessage: ChatMessage): void => { - const messagePath: string[] = [...storageKeys.outbox, chatMessage.id]; + const messagePath: string[] = [...this.getOutboxPath(), chatMessage.id]; this.storageModel.writeStringifiable(messagePath, chatMessage); }; removeFromOutbox = (chatMessage: ChatMessage): void => { - const messagePath: string[] = [...storageKeys.outbox, chatMessage.id]; + const messagePath: string[] = [...this.getOutboxPath(), chatMessage.id]; this.storageModel.remove(messagePath); }; @@ -154,18 +172,32 @@ export default class ConnectionModel { }; // storage - private getAddressPath = (address: string): string[] => { - const dirPath = storageKeys.previousAddresses; + getPreviousAddressPath = (): string[] => { + return StorageModel.getPath( + "connectionModel", + filePaths.connectionModel.previousAddresses + ); + }; + + getAddressPath = (address: string): string[] => { + const dirPath = this.getPreviousAddressPath(); return [...dirPath, address]; }; + getReconnectAddressPath = (): string[] => { + return StorageModel.getPath( + "connectionModel", + filePaths.connectionModel.reconnectAddress + ); + }; + storeAddress = (address: string): void => { // history const addressPath = this.getAddressPath(address); this.storageModel.write(addressPath, ""); // reconnect - const reconnectAddressPath: string[] = storageKeys.reconnectAddress; + const reconnectAddressPath: string[] = this.getReconnectAddressPath(); this.storageModel.write(reconnectAddressPath, address); }; @@ -175,7 +207,7 @@ export default class ConnectionModel { }; get addresses(): string[] { - const dirPath = storageKeys.previousAddresses; + const dirPath = this.getPreviousAddressPath(); return this.storageModel.list(dirPath); } @@ -225,7 +257,7 @@ export default class ConnectionModel { }; // reconnect - const reconnectAddressPath: string[] = storageKeys.reconnectAddress; + const reconnectAddressPath: string[] = this.getPreviousAddressPath(); const reconnectAddress: string | null = storageModel.read(reconnectAddressPath); if (reconnectAddress != null) { @@ -233,3 +265,9 @@ export default class ConnectionModel { } } } + +// paths +export enum settingsModelStorageFiles { + username = "user-name", + firstDayOfWeek = "first-day-of-week", +} diff --git a/src/Model/Global/settingsModel.ts b/src/Model/Global/settingsModel.ts index cfa1b3e7..dbaa6415 100644 --- a/src/Model/Global/settingsModel.ts +++ b/src/Model/Global/settingsModel.ts @@ -1,6 +1,6 @@ // this file is responsible for all settings. -import StorageModel, { storageKeys } from "./storageModel"; +import StorageModel, { filePaths } from "./storageModel"; export default class SettingsModel { storageModel: StorageModel; @@ -9,28 +9,40 @@ export default class SettingsModel { username: string; firstDayOfWeek: string; - // set + // storage setName(newValue: string): void { this.username = newValue; - const path = storageKeys.username; + const path = StorageModel.getPath( + "settingsModel", + filePaths.settingsModel.username + ); this.storageModel.write(path, newValue); } setFirstDayOfWeek(newValue: string): void { this.firstDayOfWeek = newValue; - const path = storageKeys.firstDayOfWeek; + const path = StorageModel.getPath( + "settingsModel", + filePaths.settingsModel.firstDayOfWeek + ); this.storageModel.write(path, newValue); } // load loadUsernam(): void { - const path = storageKeys.username; + const path = StorageModel.getPath( + "settingsModel", + filePaths.settingsModel.username + ); const content = this.storageModel.read(path); this.username = content ?? ""; } loadFirstDayofWeek(): void { - const path = storageKeys.firstDayOfWeek; + const path = StorageModel.getPath( + "settingsModel", + filePaths.settingsModel.firstDayOfWeek + ); const content = this.storageModel.read(path); this.firstDayOfWeek = content ?? "0"; } diff --git a/src/Model/Global/storageModel.ts b/src/Model/Global/storageModel.ts index 00a2dbb6..2abbe3b9 100644 --- a/src/Model/Global/storageModel.ts +++ b/src/Model/Global/storageModel.ts @@ -90,12 +90,7 @@ export default class StorageModel { return object; }; - // init - constructor() { - this.initializeTree(); - } - - // utility + // tree initializeTree = (): void => { console.log("initializing tree"); @@ -121,6 +116,12 @@ export default class StorageModel { return stringify(this.storageEntryTree); }; + // init + constructor() { + this.initializeTree(); + } + + // utility static getFileName = (pathComponents: string[]): string => { return pathComponents[pathComponents.length - 1] || "\\"; }; @@ -146,36 +147,52 @@ export default class StorageModel { } return StorageModel.pathComponentsToString(...allComponents); }; + + static getPath( + locationName: keyof typeof storageLocations, + filePath: string[] + ): string[] { + return [DATA_VERSION, storageLocations[locationName], ...filePath]; + } } // types export type StorageEntry = { [key: string]: StorageEntry }; -// keys -export const storageKeys = { - // connection - socketAddress: [DATA_VERSION, "connection", "socket-address"], - reconnectAddress: [DATA_VERSION, "connection", "reconnect-address"], - outbox: [DATA_VERSION, "connection", "outbox"], - mailboxes: [DATA_VERSION, "connection", "mailboxes"], +// locations +const storageLocations = { + connectionModel: "connection", - // settings - username: [DATA_VERSION, "settings", "user-name"], - firstDayOfWeek: [DATA_VERSION, "settings", "first-day-of-week"], + chat: "chat", - // history - previousAddresses: [DATA_VERSION, "history", "previous-addresses"], - - // chat - chats: [DATA_VERSION, "chat"], - chatInfo: (id: string) => [DATA_VERSION, "chat", id, "info"], - chatLastUsedPage: (id: string) => [ - DATA_VERSION, - "chat", - id, - "last-used-page", - ], - chatColor: (id: string) => [DATA_VERSION, "chat", id, "color"], - chatMessages: (id: string) => [DATA_VERSION, "chat", id, "messages"], - chatFiles: [DATA_VERSION, "chat", "files"], + settingsModel: "settings", }; + +export const filePaths = { + connectionModel: { + socketAddress: ["socket-address"], + reconnectAddress: ["reconnect-address"], + outbox: ["outbox"], + mailboxes: ["mailboxes"], + + previousAddresses: ["previous-addresses"], + }, + + chat: { + base: [], + chatBase: (id: string) => [id], + info: (id: string) => [...filePaths.chat.chatBase(id), "info"], + color: (id: string) => [...filePaths.chat.chatBase(id), "color"], + messages: (id: string) => [...filePaths.chat.chatBase(id), "messages"], + files: (id: string) => [...filePaths.chat.chatBase(id), "files"], + lastUsedPage: (id: string) => [ + ...filePaths.chat.chatBase(id), + "last-used-page", + ], + }, + + settingsModel: { + username: ["user-name"], + firstDayOfWeek: ["first-day-of-week"], + }, +}; \ No newline at end of file diff --git a/src/ViewModel/chatViewModel.ts b/src/ViewModel/chatViewModel.ts index f85c3634..8264d413 100644 --- a/src/ViewModel/chatViewModel.ts +++ b/src/ViewModel/chatViewModel.ts @@ -1,7 +1,7 @@ import * as React from "bloatless-react"; import ChatModel, { ChatMessage } from "../Model/Chat/chatModel"; -import StorageModel, { storageKeys } from "../Model/Global/storageModel"; +import StorageModel, { filePaths } from "../Model/Global/storageModel"; import ChatListViewModel from "./chatListViewModel"; import ChatMessageViewModel from "./chatMessageViewModel"; @@ -134,7 +134,7 @@ export default class ChatViewModel { // messaging sendMessage = (): void => { if (this.cannotSendMessage.value == true) return; - + this.sendMessageFromBody(this.composingMessage.value); this.composingMessage.value = ""; }; @@ -154,7 +154,10 @@ export default class ChatViewModel { // load loadPageSelection = (): void => { - const path: string[] = storageKeys.chatLastUsedPage(this.chatModel.id); + const path: string[] = StorageModel.getPath( + "chat", + filePaths.chat.lastUsedPage(this.chatModel.id) + ); const lastUsedPage: string | null = this.storageModel.read(path); if (lastUsedPage != null) { this.selectedPage.value = lastUsedPage as any; @@ -178,7 +181,7 @@ export default class ChatViewModel { for (const chatMessage of this.chatModel.messages) { this.addChatMessage(chatMessage); } - } + }; // init constructor(