prepare FileModel to manage files, cleanup
This commit is contained in:
@@ -3,3 +3,7 @@ export const DATA_VERSION = "v2"
|
|||||||
export function checkIsValidObject(object: any): boolean {
|
export function checkIsValidObject(object: any): boolean {
|
||||||
return object.dataVersion == DATA_VERSION;
|
return object.dataVersion == DATA_VERSION;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface ValidObject {
|
||||||
|
dataVersion: "v2";
|
||||||
|
}
|
||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
import FileModel, { File } from "./fileModel";
|
import FileModel, { File } from "./fileModel";
|
||||||
import StorageModel, { storageKeys } from "./storageModel";
|
import StorageModel, { storageKeys } from "./storageModel";
|
||||||
|
import { ValidObject, checkIsValidObject } from "./Utility/typeSafety";
|
||||||
import {
|
import {
|
||||||
createTimestamp,
|
createTimestamp,
|
||||||
parse,
|
parse,
|
||||||
@@ -14,7 +15,6 @@ import ChatListModel from "./chatListModel";
|
|||||||
import { Color } from "../ViewModel/colors";
|
import { Color } from "../ViewModel/colors";
|
||||||
import ConnectionModel from "./connectionModel";
|
import ConnectionModel from "./connectionModel";
|
||||||
import SettingsModel from "./settingsModel";
|
import SettingsModel from "./settingsModel";
|
||||||
import { checkIsValidObject } from "./Utility/typeSafety";
|
|
||||||
import { v4 } from "uuid";
|
import { v4 } from "uuid";
|
||||||
|
|
||||||
export default class ChatModel {
|
export default class ChatModel {
|
||||||
@@ -230,12 +230,14 @@ export default class ChatModel {
|
|||||||
|
|
||||||
connectionModel.setMessageSentHandler(this.handleMessageSent);
|
connectionModel.setMessageSentHandler(this.handleMessageSent);
|
||||||
|
|
||||||
this.fileModel = new FileModel(this);
|
this.fileModel = new FileModel(this, this.storageModel);
|
||||||
}
|
}
|
||||||
|
|
||||||
// utility
|
// utility
|
||||||
static generateChatInfo = (primaryChannel: string): ChatInfo => {
|
static generateChatInfo = (primaryChannel: string): ChatInfo => {
|
||||||
return {
|
return {
|
||||||
|
dataVersion: "v2",
|
||||||
|
|
||||||
primaryChannel,
|
primaryChannel,
|
||||||
secondaryChannels: [],
|
secondaryChannels: [],
|
||||||
encryptionKey: "",
|
encryptionKey: "",
|
||||||
@@ -281,7 +283,7 @@ export default class ChatModel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// types
|
// types
|
||||||
export interface ChatInfo {
|
export interface ChatInfo extends ValidObject {
|
||||||
primaryChannel: string;
|
primaryChannel: string;
|
||||||
secondaryChannels: string[];
|
secondaryChannels: string[];
|
||||||
encryptionKey: string;
|
encryptionKey: string;
|
||||||
@@ -295,9 +297,7 @@ export enum ChatMessageStatus {
|
|||||||
Received = "received",
|
Received = "received",
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ChatMessage {
|
export interface ChatMessage extends ValidObject {
|
||||||
dataVersion: "v2";
|
|
||||||
|
|
||||||
id: string;
|
id: string;
|
||||||
|
|
||||||
channel: string;
|
channel: string;
|
||||||
|
|||||||
+77
-13
@@ -1,11 +1,14 @@
|
|||||||
// this file is responsible for managing files within chats.
|
// this file is responsible for managing files within chats.
|
||||||
|
|
||||||
import ChatModel, { ChatMessage } from "./chatModel";
|
import ChatModel, { ChatMessage } from "./chatModel";
|
||||||
|
import StorageModel, { storageKeys } from "./storageModel";
|
||||||
|
import { parseValidObject, stringify } from "./Utility/utility";
|
||||||
|
|
||||||
import { parseValidObject } from "./Utility/utility";
|
import { ValidObject } from "./Utility/typeSafety";
|
||||||
|
|
||||||
export default class FileModel {
|
export default class FileModel {
|
||||||
chatModel: ChatModel;
|
chatModel: ChatModel;
|
||||||
|
storageModel: StorageModel;
|
||||||
|
|
||||||
// handler
|
// handler
|
||||||
handleStringifiedFile = (stringifiedFile: string): void => {
|
handleStringifiedFile = (stringifiedFile: string): void => {
|
||||||
@@ -18,25 +21,86 @@ export default class FileModel {
|
|||||||
this.chatModel.sendMessage("", file);
|
this.chatModel.sendMessage("", file);
|
||||||
};
|
};
|
||||||
|
|
||||||
// init
|
// storage
|
||||||
constructor(chatModel: ChatModel) {
|
storeFile = (file: File): void => {
|
||||||
this.chatModel = chatModel;
|
for (const fileContent of file.contentVersions) {
|
||||||
|
this.storeFileContent(file, fileContent);
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
storeFileContent = (file: File, fileContent: FileContent): void => {
|
||||||
|
const fileContentName: string = FileModel.getFileContentName(fileContent);
|
||||||
|
const fileContentPath: string[] = FileModel.getFileContentPath(
|
||||||
|
file,
|
||||||
|
fileContentName
|
||||||
|
);
|
||||||
|
const stringifiedContent: string = stringify(fileContent);
|
||||||
|
this.storageModel.write(fileContentPath, stringifiedContent);
|
||||||
|
};
|
||||||
|
|
||||||
|
listFileIds = (): string[] => {
|
||||||
|
return this.storageModel.list(storageKeys.chatFiles);
|
||||||
|
};
|
||||||
|
|
||||||
|
listFileContents = (file: File): string[] => {
|
||||||
|
const filePath: string[] = FileModel.getFilePath(file.id);
|
||||||
|
return this.storageModel.list(filePath);
|
||||||
|
};
|
||||||
|
|
||||||
|
getFile = (fileId: string): File | null => {
|
||||||
|
const filePath = FileModel.getFilePath(fileId);
|
||||||
|
const fileOrNull: File | null =
|
||||||
|
this.storageModel.readStringifiable<File>(filePath);
|
||||||
|
return fileOrNull;
|
||||||
|
};
|
||||||
|
|
||||||
|
getLatestFileContentName = (fileContentNames: string[]): string | null => {
|
||||||
|
return fileContentNames[fileContentNames.length - 1];
|
||||||
|
};
|
||||||
|
|
||||||
|
getFileContent = (
|
||||||
|
file: File,
|
||||||
|
fileContentName: string
|
||||||
|
): FileContent | null => {
|
||||||
|
const filePath = FileModel.getFileContentPath(file, fileContentName);
|
||||||
|
const fileContentOrNull: FileContent | null =
|
||||||
|
this.storageModel.readStringifiable<FileContent>(filePath);
|
||||||
|
return fileContentOrNull;
|
||||||
|
};
|
||||||
|
|
||||||
|
// init
|
||||||
|
constructor(chatModel: ChatModel, storageModel: StorageModel) {
|
||||||
|
this.chatModel = chatModel;
|
||||||
|
this.storageModel = storageModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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];
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// types
|
// types
|
||||||
export interface File {
|
export interface File extends ValidObject {
|
||||||
dataVersion: "v2";
|
|
||||||
|
|
||||||
id: string;
|
id: string;
|
||||||
title: string;
|
contentVersions: FileContent[];
|
||||||
|
|
||||||
contentVersions: { [id: string]: FileContent };
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface FileContent {
|
export interface FileContent extends ValidObject {
|
||||||
dataVersion: "v2";
|
|
||||||
|
|
||||||
id: string;
|
id: string;
|
||||||
creationDate: string;
|
creationDate: string;
|
||||||
|
|
||||||
|
type: string;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
// this file is responsible for managing message objects.c
|
||||||
@@ -1,8 +1,12 @@
|
|||||||
// this file is responsible for reading and writing persistent data; all storage shall be handled by this file.
|
// this file is responsible for reading and writing persistent data; all storage shall be handled by this file.
|
||||||
|
|
||||||
import { localeCompare, parse, stringify } from "./Utility/utility";
|
import { DATA_VERSION, ValidObject } from "./Utility/typeSafety";
|
||||||
|
import {
|
||||||
import { DATA_VERSION } from "./Utility/typeSafety";
|
localeCompare,
|
||||||
|
parse,
|
||||||
|
parseValidObject,
|
||||||
|
stringify,
|
||||||
|
} from "./Utility/utility";
|
||||||
|
|
||||||
export const PATH_COMPONENT_SEPARATOR = "\\";
|
export const PATH_COMPONENT_SEPARATOR = "\\";
|
||||||
|
|
||||||
@@ -69,16 +73,17 @@ export default class StorageModel {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// stringifiable
|
// stringifiable
|
||||||
writeStringifiable = (pathComponents: string[], value: any): void => {
|
writeStringifiable = (pathComponents: string[], value: ValidObject): void => {
|
||||||
const valueString: string = stringify(value);
|
const valueString: string = stringify(value);
|
||||||
this.write(pathComponents, valueString);
|
this.write(pathComponents, valueString);
|
||||||
};
|
};
|
||||||
|
|
||||||
readStringifiable = (pathComponents: string[]): any | null => {
|
readStringifiable = <T extends ValidObject>(pathComponents: string[]): T | null => {
|
||||||
const valueString: string | null = this.read(pathComponents);
|
const valueString: string | null = this.read(pathComponents);
|
||||||
if (!valueString) return null;
|
if (!valueString) return null;
|
||||||
|
|
||||||
return parse(valueString);
|
const object: T | null = parseValidObject(valueString);
|
||||||
|
return object;
|
||||||
};
|
};
|
||||||
|
|
||||||
// init
|
// init
|
||||||
@@ -168,4 +173,5 @@ export const storageKeys = {
|
|||||||
],
|
],
|
||||||
chatColor: (id: string) => [DATA_VERSION, "chat", id, "color"],
|
chatColor: (id: string) => [DATA_VERSION, "chat", id, "color"],
|
||||||
chatMessages: (id: string) => [DATA_VERSION, "chat", id, "messages"],
|
chatMessages: (id: string) => [DATA_VERSION, "chat", id, "messages"],
|
||||||
|
chatFiles: [DATA_VERSION, "chat", "files"],
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user