clean model (A)
This commit is contained in:
@@ -1,13 +1,16 @@
|
||||
// this file is responsible for managing UDN connections.
|
||||
// cleanup: Phase A
|
||||
|
||||
import { ChatMessage, ChatMessageReference } from "../Chat/chatModel";
|
||||
import { HandlerManager, stringify } from "../Utility/utility";
|
||||
import StorageModel, { StorageModelSubPaths, filePaths } from "./storageModel";
|
||||
import UDNFrontend, { Message } from "udn-frontend";
|
||||
import StorageModel, { StorageModelSubPaths, filePaths } from "./storageModel";
|
||||
import { HandlerManager, stringify } from "../Utility/utility";
|
||||
import { ChatMessage, ChatMessageReference } from "../Chat/chatModel";
|
||||
|
||||
export default class ConnectionModel {
|
||||
// models etc
|
||||
readonly udn: UDNFrontend;
|
||||
readonly storageModel: StorageModel;
|
||||
|
||||
// config
|
||||
reconnectInterval: number | undefined = undefined;
|
||||
shouldAttemptReconnect: boolean = false;
|
||||
|
||||
@@ -20,17 +23,18 @@ export default class ConnectionModel {
|
||||
return this.udn.ws?.url;
|
||||
}
|
||||
|
||||
// handler managers
|
||||
readonly connectionChangeHandlerManager = new HandlerManager<void>();
|
||||
readonly messageHandlerManager = new HandlerManager<Message>();
|
||||
readonly messageSentHandlerManager = new HandlerManager<ChatMessage>();
|
||||
readonly channelsToSubscribe = new Set<string>();
|
||||
|
||||
// handlers
|
||||
handleMessage = (data: Message): void => {
|
||||
readonly handleMessage = (data: Message): void => {
|
||||
this.messageHandlerManager.trigger(data);
|
||||
};
|
||||
|
||||
handleConnectionChange = (): void => {
|
||||
readonly handleConnectionChange = (): void => {
|
||||
console.log("connection status:", this.isConnected, this.address);
|
||||
this.connectionChangeHandlerManager.trigger();
|
||||
if (this.address == undefined) return;
|
||||
@@ -41,13 +45,13 @@ export default class ConnectionModel {
|
||||
};
|
||||
|
||||
// connection
|
||||
connect = (address: string): void => {
|
||||
readonly connect = (address: string): void => {
|
||||
console.log("connecting...", address);
|
||||
this.shouldAttemptReconnect = true;
|
||||
this.udn.connect(address);
|
||||
};
|
||||
|
||||
disconnect = (): void => {
|
||||
readonly disconnect = (): void => {
|
||||
this.shouldAttemptReconnect = false;
|
||||
this.udn.disconnect();
|
||||
|
||||
@@ -59,7 +63,7 @@ export default class ConnectionModel {
|
||||
this.storageModel.remove(reconnectAddressPath);
|
||||
};
|
||||
|
||||
reconnect = (): void => {
|
||||
readonly reconnect = (): void => {
|
||||
const reconnectAddressPath: string[] = this.getReconnectAddressPath();
|
||||
const reconnectAddress: string | null =
|
||||
this.storageModel.read(reconnectAddressPath);
|
||||
@@ -70,7 +74,7 @@ export default class ConnectionModel {
|
||||
};
|
||||
|
||||
// mailbox
|
||||
getMailboxPath = (address: string): string[] => {
|
||||
readonly getMailboxPath = (address: string): string[] => {
|
||||
const mailboxDirPath = StorageModel.getPath(
|
||||
StorageModelSubPaths.ConnectionModel,
|
||||
filePaths.connectionModel.mailboxes,
|
||||
@@ -79,12 +83,12 @@ export default class ConnectionModel {
|
||||
return mailboxFilePath;
|
||||
};
|
||||
|
||||
requestNewMailbox = (): void => {
|
||||
readonly requestNewMailbox = (): void => {
|
||||
console.log("requesting new mailbox");
|
||||
this.udn.requestMailbox();
|
||||
};
|
||||
|
||||
connectMailbox = (): void => {
|
||||
readonly connectMailbox = (): void => {
|
||||
if (this.address == undefined) return;
|
||||
|
||||
const mailboxId = this.storageModel.read(
|
||||
@@ -96,18 +100,18 @@ export default class ConnectionModel {
|
||||
this.udn.connectMailbox(mailboxId);
|
||||
};
|
||||
|
||||
storeMailbox = (mailboxId: string): void => {
|
||||
readonly storeMailbox = (mailboxId: string): void => {
|
||||
if (this.address == undefined) return;
|
||||
this.storageModel.write(this.getMailboxPath(this.address), mailboxId);
|
||||
};
|
||||
|
||||
// subscription
|
||||
addChannel = (channel: string): void => {
|
||||
readonly addChannel = (channel: string): void => {
|
||||
this.channelsToSubscribe.add(channel);
|
||||
this.sendSubscriptionRequest();
|
||||
};
|
||||
|
||||
sendSubscriptionRequest = (): void => {
|
||||
readonly sendSubscriptionRequest = (): void => {
|
||||
if (this.isConnected == false) return;
|
||||
|
||||
for (const channel of this.channelsToSubscribe) {
|
||||
@@ -118,14 +122,14 @@ export default class ConnectionModel {
|
||||
};
|
||||
|
||||
// outbox
|
||||
getOutboxPath = (): string[] => {
|
||||
readonly getOutboxPath = (): string[] => {
|
||||
return StorageModel.getPath(
|
||||
StorageModelSubPaths.ConnectionModel,
|
||||
filePaths.connectionModel.outbox,
|
||||
);
|
||||
};
|
||||
|
||||
getOutboxMessags = (): ChatMessage[] => {
|
||||
readonly getOutboxMessags = (): ChatMessage[] => {
|
||||
const outboxPath: string[] = this.getOutboxPath();
|
||||
const messageIds: string[] = this.storageModel.list(outboxPath);
|
||||
|
||||
@@ -144,17 +148,17 @@ export default class ConnectionModel {
|
||||
return chatMessages;
|
||||
};
|
||||
|
||||
addToOutbox = (chatMessage: ChatMessage): void => {
|
||||
readonly addToOutbox = (chatMessage: ChatMessage): void => {
|
||||
const messagePath: string[] = [...this.getOutboxPath(), chatMessage.id];
|
||||
this.storageModel.writeStringifiable(messagePath, chatMessage);
|
||||
};
|
||||
|
||||
removeFromOutbox = (chatMessage: ChatMessage): void => {
|
||||
readonly removeFromOutbox = (chatMessage: ChatMessage): void => {
|
||||
const messagePath: string[] = [...this.getOutboxPath(), chatMessage.id];
|
||||
this.storageModel.remove(messagePath);
|
||||
};
|
||||
|
||||
sendMessagesInOutbox = (): void => {
|
||||
readonly sendMessagesInOutbox = (): void => {
|
||||
const messages: ChatMessage[] = this.getOutboxMessags();
|
||||
|
||||
for (const message of messages) {
|
||||
@@ -166,14 +170,14 @@ export default class ConnectionModel {
|
||||
};
|
||||
|
||||
// messaging
|
||||
sendMessageOrStore = (chatMessage: ChatMessage): void => {
|
||||
readonly sendMessageOrStore = (chatMessage: ChatMessage): void => {
|
||||
const isSent = this.tryToSendMessage(chatMessage);
|
||||
if (isSent == true) return;
|
||||
|
||||
this.addToOutbox(chatMessage);
|
||||
};
|
||||
|
||||
tryToSendMessage = (chatMessage: ChatMessage): boolean => {
|
||||
readonly tryToSendMessage = (chatMessage: ChatMessage): boolean => {
|
||||
const stringifiedBody: string = stringify(chatMessage);
|
||||
const isSent: boolean = this.sendPlainMessage(
|
||||
chatMessage.channel,
|
||||
@@ -183,31 +187,31 @@ export default class ConnectionModel {
|
||||
return isSent;
|
||||
};
|
||||
|
||||
sendPlainMessage = (channel: string, body: string): boolean => {
|
||||
readonly sendPlainMessage = (channel: string, body: string): boolean => {
|
||||
return this.udn.sendMessage(channel, body);
|
||||
};
|
||||
|
||||
// storage
|
||||
getPreviousAddressPath = (): string[] => {
|
||||
readonly getPreviousAddressPath = (): string[] => {
|
||||
return StorageModel.getPath(
|
||||
StorageModelSubPaths.ConnectionModel,
|
||||
filePaths.connectionModel.previousAddresses,
|
||||
);
|
||||
};
|
||||
|
||||
getAddressPath = (address: string): string[] => {
|
||||
readonly getAddressPath = (address: string): string[] => {
|
||||
const dirPath = this.getPreviousAddressPath();
|
||||
return [...dirPath, address];
|
||||
};
|
||||
|
||||
getReconnectAddressPath = (): string[] => {
|
||||
readonly getReconnectAddressPath = (): string[] => {
|
||||
return StorageModel.getPath(
|
||||
StorageModelSubPaths.ConnectionModel,
|
||||
filePaths.connectionModel.reconnectAddress,
|
||||
);
|
||||
};
|
||||
|
||||
storeAddress = (address: string): void => {
|
||||
readonly storeAddress = (address: string): void => {
|
||||
// history
|
||||
const addressPath = this.getAddressPath(address);
|
||||
this.storageModel.write(addressPath, "");
|
||||
@@ -217,7 +221,7 @@ export default class ConnectionModel {
|
||||
this.storageModel.write(reconnectAddressPath, address);
|
||||
};
|
||||
|
||||
removeAddress = (address: string): void => {
|
||||
readonly removeAddress = (address: string): void => {
|
||||
const addressPath = this.getAddressPath(address);
|
||||
this.storageModel.remove(addressPath);
|
||||
};
|
||||
|
||||
@@ -1,17 +1,16 @@
|
||||
// this file is responsible for sending and handling files.
|
||||
// cleanup: Phase A
|
||||
|
||||
import { Message } from "udn-frontend";
|
||||
import StorageModel from "./storageModel";
|
||||
import ConnectionModel from "./connectionModel";
|
||||
import {
|
||||
HandlerManager,
|
||||
generateRandomToken,
|
||||
parse,
|
||||
stringify,
|
||||
} from "../Utility/utility";
|
||||
import { decryptString, encryptString } from "../Utility/crypto";
|
||||
|
||||
import ConnectionModel from "./connectionModel";
|
||||
import { Message } from "udn-frontend";
|
||||
import StorageModel from "./storageModel";
|
||||
import { checkMatchesObjectStructure } from "../Utility/typeSafety";
|
||||
import { decryptString, encryptString } from "../Utility/crypto";
|
||||
|
||||
export default class FileTransferModel {
|
||||
readonly storageModel: StorageModel;
|
||||
@@ -21,12 +20,14 @@ export default class FileTransferModel {
|
||||
|
||||
// data
|
||||
transferData: TransferData | undefined;
|
||||
readonly fileHandlerManager = new HandlerManager<string>();
|
||||
readonly readyToSendHandlerManager = new HandlerManager<boolean>();
|
||||
direction: TransferDirections = TransferDirections.Send;
|
||||
|
||||
// handler managers
|
||||
readonly fileHandlerManager = new HandlerManager<string>();
|
||||
readonly readyToSendHandlerManager = new HandlerManager<boolean>();
|
||||
|
||||
// general
|
||||
generateTransferData = (): TransferData => {
|
||||
readonly generateTransferData = (): TransferData => {
|
||||
const transferData: TransferData = {
|
||||
channel: generateRandomToken(4),
|
||||
key: generateRandomToken(6),
|
||||
@@ -35,12 +36,12 @@ export default class FileTransferModel {
|
||||
return transferData;
|
||||
};
|
||||
|
||||
prepareToSend = (): void => {
|
||||
readonly prepareToSend = (): void => {
|
||||
this.direction = TransferDirections.Send;
|
||||
this.connectionModel.addChannel(this.transferData.channel);
|
||||
};
|
||||
|
||||
prepareToReceive = (transferData: TransferData): void => {
|
||||
readonly prepareToReceive = (transferData: TransferData): void => {
|
||||
this.direction = TransferDirections.Receive;
|
||||
|
||||
this.connectionModel.addChannel(transferData.channel);
|
||||
@@ -52,7 +53,7 @@ export default class FileTransferModel {
|
||||
};
|
||||
|
||||
// handlers
|
||||
handleMessage = (data: Message): void => {
|
||||
readonly handleMessage = (data: Message): void => {
|
||||
if (this.transferData == undefined) return;
|
||||
if (data.messageChannel != this.transferData.channel) return;
|
||||
if (
|
||||
@@ -68,7 +69,7 @@ export default class FileTransferModel {
|
||||
this.handleFile(data.messageBody);
|
||||
};
|
||||
|
||||
handleFile = async (encryptedFileData: string): Promise<void> => {
|
||||
readonly handleFile = async (encryptedFileData: string): Promise<void> => {
|
||||
if (this.transferData == undefined) return;
|
||||
|
||||
const decrypted: string = await decryptString(
|
||||
@@ -93,7 +94,7 @@ export default class FileTransferModel {
|
||||
};
|
||||
|
||||
// sending
|
||||
sendFiles = (
|
||||
readonly sendFiles = (
|
||||
directoryPaths: IteratorObject<string[]>,
|
||||
callback: (path: string) => void,
|
||||
): void => {
|
||||
@@ -108,7 +109,7 @@ export default class FileTransferModel {
|
||||
}
|
||||
};
|
||||
|
||||
sendFile = async (filePath: string[]): Promise<void> => {
|
||||
readonly sendFile = async (filePath: string[]): Promise<void> => {
|
||||
if (this.transferData == undefined) return;
|
||||
const fileContent: string | null = this.storageModel.read(filePath);
|
||||
if (fileContent == null) return;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// this file is responsible for all settings.
|
||||
// cleanup: Phase A
|
||||
|
||||
import StorageModel, { StorageModelSubPaths, filePaths } from "./storageModel";
|
||||
|
||||
@@ -12,10 +12,10 @@ export default class SettingsModel {
|
||||
theme: string;
|
||||
|
||||
// storage
|
||||
private storeSetting(
|
||||
private readonly storeSetting = (
|
||||
pathName: keyof typeof filePaths.settingsModel,
|
||||
value: string,
|
||||
): void {
|
||||
): void => {
|
||||
const path = StorageModel.getPath(
|
||||
StorageModelSubPaths.SettingsModel,
|
||||
filePaths.settingsModel[pathName],
|
||||
@@ -23,28 +23,28 @@ export default class SettingsModel {
|
||||
this.storageModel.write(path, value);
|
||||
}
|
||||
|
||||
setName = (newValue: string): void => {
|
||||
readonly setName = (newValue: string): void => {
|
||||
this.username = newValue;
|
||||
this.storeSetting("username", newValue);
|
||||
};
|
||||
|
||||
setFirstDayOfWeek = (newValue: string): void => {
|
||||
readonly setFirstDayOfWeek = (newValue: string): void => {
|
||||
this.firstDayOfWeek = newValue;
|
||||
this.storeSetting("firstDayOfWeek", newValue);
|
||||
};
|
||||
|
||||
setLanguage = (newValue: string): void => {
|
||||
readonly setLanguage = (newValue: string): void => {
|
||||
this.language = newValue;
|
||||
this.storeSetting("language", newValue);
|
||||
};
|
||||
|
||||
setTheme = (newValue: string): void => {
|
||||
readonly setTheme = (newValue: string): void => {
|
||||
this.theme = newValue;
|
||||
this.storeSetting("theme", newValue);
|
||||
};
|
||||
|
||||
// load
|
||||
private readSetting = (
|
||||
private readonly readSetting = (
|
||||
pathName: keyof typeof filePaths.settingsModel,
|
||||
): string => {
|
||||
const path = StorageModel.getPath(
|
||||
@@ -54,22 +54,22 @@ export default class SettingsModel {
|
||||
return this.storageModel.read(path);
|
||||
};
|
||||
|
||||
loadUsername = (): void => {
|
||||
readonly loadUsername = (): void => {
|
||||
const content: string | null = this.readSetting("username");
|
||||
this.username = content ?? "";
|
||||
};
|
||||
|
||||
loadFirstDayofWeek = (): void => {
|
||||
readonly loadFirstDayofWeek = (): void => {
|
||||
const content: string | null = this.readSetting("firstDayOfWeek");
|
||||
this.firstDayOfWeek = content ?? "0";
|
||||
};
|
||||
|
||||
loadLanguage = (): void => {
|
||||
readonly loadLanguage = (): void => {
|
||||
const content: string | null = this.readSetting("language");
|
||||
this.language = content ?? SettingsModel.getSystemLanguage();
|
||||
};
|
||||
|
||||
loadTheme = (): void => {
|
||||
readonly loadTheme = (): void => {
|
||||
const content: string | null = this.readSetting("theme");
|
||||
this.theme = content ?? ThemeSettings.System;
|
||||
};
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// this file is responsible for reading and writing persistent data.
|
||||
// cleanup: Phase A
|
||||
|
||||
import { DATA_VERSION, ValidObject } from "../Utility/typeSafety";
|
||||
import { localeCompare, parseValidObject, stringify } from "../Utility/utility";
|
||||
import { DATA_VERSION, ValidObject } from "../Utility/typeSafety";
|
||||
|
||||
export const PATH_COMPONENT_SEPARATOR = "\\";
|
||||
|
||||
@@ -9,14 +9,14 @@ export default class StorageModel {
|
||||
storageEntryTree: StorageEntry = {};
|
||||
|
||||
// read
|
||||
read = (pathComponents: string[]): string | null => {
|
||||
readonly read = (pathComponents: string[]): string | null => {
|
||||
const pathString: string = StorageModel.pathComponentsToString(
|
||||
...pathComponents,
|
||||
);
|
||||
return localStorage.getItem(pathString);
|
||||
};
|
||||
|
||||
list = (pathComponents: string[]): string[] => {
|
||||
readonly list = (pathComponents: string[]): string[] => {
|
||||
let currentParent: StorageEntry = this.storageEntryTree;
|
||||
for (const component of pathComponents) {
|
||||
const nextParent: StorageEntry | undefined =
|
||||
@@ -29,7 +29,7 @@ export default class StorageModel {
|
||||
};
|
||||
|
||||
// write
|
||||
write = (pathComponents: string[], value: string): void => {
|
||||
readonly write = (pathComponents: string[], value: string): void => {
|
||||
const pathString: string = StorageModel.pathComponentsToString(
|
||||
...pathComponents,
|
||||
);
|
||||
@@ -37,7 +37,7 @@ export default class StorageModel {
|
||||
this.updateTree(...pathComponents);
|
||||
};
|
||||
|
||||
remove = (
|
||||
readonly remove = (
|
||||
pathComponents: string[],
|
||||
shouldInitialize: boolean = true,
|
||||
): void => {
|
||||
@@ -51,7 +51,7 @@ export default class StorageModel {
|
||||
}
|
||||
};
|
||||
|
||||
rename = (
|
||||
readonly rename = (
|
||||
sourcePathComponents: string[],
|
||||
destinationPathComponents: string[],
|
||||
shouldInitialize: boolean = true,
|
||||
@@ -69,7 +69,7 @@ export default class StorageModel {
|
||||
};
|
||||
|
||||
// recursion
|
||||
recurse = (rootDirectory: string[], fn: (path: string[]) => void): void => {
|
||||
readonly recurse = (rootDirectory: string[], fn: (path: string[]) => void): void => {
|
||||
loop_over_files: for (const key of Object.keys(localStorage)) {
|
||||
// get path of current entity
|
||||
const pathComponentsOfCurrentEntity: string[] =
|
||||
@@ -92,14 +92,14 @@ export default class StorageModel {
|
||||
this.initializeTree();
|
||||
};
|
||||
|
||||
removeRecursively = (pathComponents: string[]): void => {
|
||||
readonly removeRecursively = (pathComponents: string[]): void => {
|
||||
this.recurse(pathComponents, (path: string[]) =>
|
||||
this.remove(path, false),
|
||||
);
|
||||
this.initializeTree();
|
||||
};
|
||||
|
||||
renameRecursively = (
|
||||
readonly renameRecursively = (
|
||||
sourcePathComponents: string[],
|
||||
destinationPathComponents: string[],
|
||||
): void => {
|
||||
@@ -120,7 +120,7 @@ export default class StorageModel {
|
||||
};
|
||||
|
||||
// stringifiable
|
||||
writeStringifiable = (
|
||||
readonly writeStringifiable = (
|
||||
pathComponents: string[],
|
||||
value: ValidObject,
|
||||
): void => {
|
||||
@@ -128,7 +128,7 @@ export default class StorageModel {
|
||||
this.write(pathComponents, valueString);
|
||||
};
|
||||
|
||||
readStringifiable = <T extends ValidObject>(
|
||||
readonly readStringifiable = <T extends ValidObject>(
|
||||
pathComponents: string[],
|
||||
reference: T,
|
||||
): T | null => {
|
||||
@@ -142,7 +142,7 @@ export default class StorageModel {
|
||||
};
|
||||
|
||||
// cleaning
|
||||
removeJunk = (): void => {
|
||||
readonly removeJunk = (): void => {
|
||||
this.recurse([], (path: string[]) => {
|
||||
if (path[0] == DATA_VERSION) return;
|
||||
this.remove(path);
|
||||
@@ -150,7 +150,7 @@ export default class StorageModel {
|
||||
};
|
||||
|
||||
// tree
|
||||
initializeTree = (): void => {
|
||||
readonly initializeTree = (): void => {
|
||||
console.log("initializing tree");
|
||||
|
||||
this.storageEntryTree = {};
|
||||
@@ -161,7 +161,7 @@ export default class StorageModel {
|
||||
}
|
||||
};
|
||||
|
||||
updateTree = (...pathComponents: string[]): void => {
|
||||
readonly updateTree = (...pathComponents: string[]): void => {
|
||||
let currentParent: StorageEntry = this.storageEntryTree;
|
||||
for (const pathPart of pathComponents) {
|
||||
if (!currentParent[pathPart]) {
|
||||
@@ -172,7 +172,7 @@ export default class StorageModel {
|
||||
}
|
||||
};
|
||||
|
||||
printTree = (): string => {
|
||||
readonly printTree = (): string => {
|
||||
return stringify(this.storageEntryTree);
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user