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