remodel fileModel, start board methods of taskModel

This commit is contained in:
marlon-erler
2024-07-22 17:23:48 +02:00
parent 76737a390a
commit 3cc961a82b
4 changed files with 328 additions and 308 deletions
+10 -7
View File
@@ -1,7 +1,7 @@
// this file is responsible for managing chats.
import { DATA_VERSION, ValidObject } from "../Utility/typeSafety";
import FileModel, { File } from "../Files/fileModel";
import FileModel, { FileVersion } from "../Files/fileModel";
import StorageModel, { filePaths } from "../Global/storageModel";
import {
createTimestamp,
@@ -83,7 +83,10 @@ export default class ChatModel {
};
// messaging
sendMessage = async (body: string, file?: File): Promise<boolean> => {
sendMessage = async (
body: string,
fileVersion: FileVersion<string>
): Promise<boolean> => {
const senderName = this.settingsModel.username;
if (senderName == "") return false;
@@ -99,7 +102,7 @@ export default class ChatModel {
senderName,
this.info.encryptionKey,
body,
file
fileVersion
);
this.addMessage(chatMessage);
@@ -164,7 +167,7 @@ export default class ChatModel {
}
// file
this.fileModel.handleStringifiedFile(chatMessage.stringifiedFile);
this.fileModel.handleStringifiedFileVersion(chatMessage.stringifiedFile);
};
delete = () => {
@@ -260,7 +263,7 @@ export default class ChatModel {
sender: string,
encryptionKey: string,
body: string,
file?: File
fileVersion: FileVersion<string>
): Promise<ChatMessage> => {
const chatMessage: ChatMessage = {
dataVersion: DATA_VERSION,
@@ -275,8 +278,8 @@ export default class ChatModel {
status: ChatMessageStatus.Outbox,
stringifiedFile: "",
};
if (file != undefined) {
const stringifiedFile = stringify(file);
if (fileVersion != undefined) {
const stringifiedFile = stringify(fileVersion);
chatMessage.stringifiedFile = stringifiedFile;
}
+92 -83
View File
@@ -9,6 +9,7 @@ import {
} from "../Utility/utility";
import ChatModel from "../Chat/chatModel";
import { Color } from "../../ViewModel/colors";
import TaskModel from "./taskModel";
import { v4 } from "uuid";
@@ -26,92 +27,109 @@ export default class FileModel {
);
};
getModelDirectoryPath = (
modelName: keyof typeof modelDirectories
getFileContainerPath = (): string[] => {
return [...this.getBasePath(), subDirectories.data];
};
getModelContainerPath = (
modelName: keyof typeof subDirectories
): string[] => {
return [...this.getBasePath(), modelName];
return [...this.getBasePath(), subDirectories.model, modelName];
};
getFilePath = (fileId: string): string[] => {
return [...this.getBasePath(), fileId];
return [...this.getFileContainerPath(), fileId];
};
getFileContentPath = (file: File, fileContentName: string): string[] => {
const filePath: string[] = this.getFilePath(file.id);
return [...filePath, fileContentName];
getFileVersionPath = (fileId: string, fileVersionId: string): string[] => {
const filePath: string[] = this.getFilePath(fileId);
return [...filePath, fileVersionId];
};
// handler
handleStringifiedFile = (stringifiedFile: string): void => {
const file: File | null = parseValidObject(stringifiedFile, FileReference);
if (file == null) return;
handleStringifiedFileVersion = (stringifiedFileVersion: string): void => {
const fileVersion: FileVersion<string> | null = parseValidObject(
stringifiedFileVersion,
FileVersionReference
);
if (fileVersion == null) return;
this.handleFileAndClearContents(file);
this.handleFileVersion(fileVersion);
};
handleFileAndClearContents = (file: File): void => {
for (const fileContent of file.contentVersions) {
this.storeFileContent(file, fileContent);
this.taskModel.handleFileContent(file, fileContent);
}
handleFileVersion = (fileVersion: FileVersion<string>): void => {
const didStore: boolean = this.storeFileVersion(fileVersion);
if (didStore == false) return;
file.contentVersions = [];
this.taskModel.handleFileVersion(fileVersion);
};
// methods
addOrUpdateFile = (file: File, fileContent: FileContent<string>): void => {
file.contentVersions.push(fileContent);
this.chatModel.sendMessage("", file);
this.handleFileAndClearContents(file);
addFileVersion = (fileVersion: FileVersion<string>): void => {
this.handleFileVersion(fileVersion);
this.chatModel.sendMessage("", fileVersion);
};
// storage
storeFileContent = (file: File, fileContent: FileContent<string>): void => {
const fileContentName: string = FileModel.getFileContentName(fileContent);
const fileContentPath: string[] = this.getFileContentPath(
file,
fileContentName
storeFileVersion = (fileVersion: FileVersion<string>): boolean => {
const fileVersionPath: string[] = this.getFileVersionPath(
fileVersion.fileId,
fileVersion.fileVersionId
);
// check if fileContent already exists
const existingFileContent: string | null =
this.storageModel.read(fileContentPath);
if (existingFileContent != null) return;
// check if fileVersion already exists
const existingFileVersion: string | null =
this.storageModel.read(fileVersionPath);
if (existingFileVersion != null) return false;
const stringifiedContent: string = stringify(fileContent);
this.storageModel.write(fileContentPath, stringifiedContent);
const stringifiedContent: string = stringify(fileVersion);
this.storageModel.write(fileVersionPath, stringifiedContent);
return true;
};
listFileIds = (): string[] => {
return this.storageModel.list(this.getBasePath());
};
getFile = (fileId: string): File | null => {
listFileVersionIds = (fileId: string): string[] => {
const filePath: string[] = this.getFilePath(fileId);
const fileOrNull: File | null = this.storageModel.readStringifiable(
filePath,
FileReference
);
return fileOrNull;
};
listFileContents = (file: File): string[] => {
const filePath: string[] = this.getFilePath(file.id);
return this.storageModel.list(filePath);
};
getLatestFileContentName = (fileContentNames: string[]): string | null => {
return fileContentNames[fileContentNames.length - 1];
selectLatestFileVersionId = (
fileVersionIds: string[]
): string | undefined => {
return fileVersionIds[fileVersionIds.length - 1];
};
getFileContent = (
file: File,
fileContentName: string
): FileContent<string> | null => {
const filePath: string[] = this.getFileContentPath(file, fileContentName);
const fileContentOrNull: FileContent<string> | null =
this.storageModel.readStringifiable(filePath, FileContentReference);
return fileContentOrNull;
getFileVersion = <T extends FileVersion<string>>(
fileId: string,
fileVersionName: string,
reference: T
): T | null => {
const filePath: string[] = this.getFileVersionPath(fileId, fileVersionName);
const fileVersionOrNull: T | null = this.storageModel.readStringifiable(
filePath,
reference
);
return fileVersionOrNull;
};
getLatestFileVersion = <T extends FileVersion<string>>(
fileId: string,
reference: T
): T | null => {
const fileVersionsIds: string[] = this.listFileVersionIds(fileId);
const latestFileVersionId: string | undefined =
this.selectLatestFileVersionId(fileVersionsIds);
if (latestFileVersionId == undefined) return null;
const fileVersion: T | null = this.getFileVersion(
fileId,
latestFileVersionId,
reference
);
return fileVersion;
};
// init
@@ -123,60 +141,51 @@ export default class FileModel {
}
// utility
static getFileContentName = (fileContent: FileContent<string>): string => {
return fileContent.creationDate + fileContent.id;
static generateFileVersionId = (creationDate): string => {
return creationDate + v4();
};
static createFile = (): File => {
static createFileVersion = <T extends string>(
fileId: string,
type: T
): FileVersion<T> => {
const creationDate: string = createTimestamp();
const fileVersionId: string = FileModel.generateFileVersionId(creationDate);
return {
dataVersion: DATA_VERSION,
id: v4(),
contentVersions: [],
};
};
static createFileContent = <T extends string>(type: T): FileContent<T> => {
return {
dataVersion: DATA_VERSION,
id: v4(),
creationDate: createTimestamp(),
fileId,
fileVersionId,
creationDate,
type,
};
};
}
// paths
export const modelDirectories = {
export const subDirectories = {
data: "data",
model: "model",
taskModel: "tasks",
};
// types
export interface File extends ValidObject {
id: string;
contentVersions: FileContent<string>[];
}
export interface FileContent<T extends string> extends ValidObject {
id: string;
export interface FileVersion<T extends string> extends ValidObject {
fileId: string;
fileVersionId: string;
creationDate: string;
type: T;
}
// references
export const FileContentReference: FileContent<string> = {
export const FileVersionReference: FileVersion<string> = {
dataVersion: DATA_VERSION,
id: "",
fileId: "",
fileVersionId: "",
creationDate: "",
type: "",
};
export const FileReference: File = {
dataVersion: DATA_VERSION,
id: "",
contentVersions: [FileContentReference],
};
+78 -83
View File
@@ -2,18 +2,14 @@
import {
DATA_VERSION,
ValidObject,
checkMatchesObjectStructure,
} from "../Utility/typeSafety";
import FileModel, {
File,
FileContent,
FileContentReference,
} from "./fileModel";
import FileModel, { FileVersion } from "./fileModel";
import ChatModel from "../Chat/chatModel";
import { Color } from "../../ViewModel/colors";
import StorageModel from "../Global/storageModel";
import { v4 } from "uuid";
export default class TaskModel {
storageModel: StorageModel;
@@ -22,115 +18,106 @@ export default class TaskModel {
// paths
getBasePath = (): string[] => {
return this.fileModel.getModelDirectoryPath("taskModel");
return this.fileModel.getModelContainerPath("taskModel");
};
getBoardDirPath = (): string[] => {
getBoardFilePath = (boardId: string): string[] => {
return [...this.fileModel.getFilePath(boardId), boardId];
};
getBoardContainerPath = (): string[] => {
return [...this.getBasePath(), subDirectories.boards];
};
getBoardPath = (boardId: string): string[] => {
return [...this.getBoardDirPath(), boardId];
getBoardDirectoryPath = (boardId: string): string[] => {
return [...this.getBoardContainerPath(), boardId];
};
getBoardInfoPath = (boardId: string): string[] => {
return [...this.getBoardPath(boardId), subDirectories.boardInfo];
};
getTaskDirPath = (boardId: string): string[] => {
return [...this.getBoardPath(boardId), subDirectories.boardTasks];
getTaskContainerPath = (boardId: string): string[] => {
return [...this.getBoardDirectoryPath(boardId), subDirectories.boardTasks];
};
getTaskPath = (boardId: string, fileId: string): string[] => {
return [...this.getTaskDirPath(boardId), fileId];
return [...this.getTaskContainerPath(boardId), fileId];
};
getTaskContentPath = (
boardId: string,
fileId: string,
contentName: string
versionId: string
): string[] => {
return [...this.getTaskPath(boardId, fileId), contentName];
return [...this.getTaskPath(boardId, fileId), versionId];
};
// handler
handleFileContent = (file: File, fileContent: FileContent<string>): void => {
handleFileVersion = (fileVersion: FileVersion<string>): void => {
if (
checkMatchesObjectStructure(fileContent, BoardInfoFileContentReference) ==
checkMatchesObjectStructure(fileVersion, BoardInfoFileVersionReference) ==
true
) {
// todo
this.handleBoard(fileVersion as BoardInfoVersion);
} else if (
checkMatchesObjectStructure(fileContent, TaskFileContentReference) == true
checkMatchesObjectStructure(fileVersion, TaskFileVersionReference) == true
) {
// todo
this.handleTask(fileVersion as TaskFileVersion);
}
};
handleBoard = (boardInfoFileVersion: BoardInfoVersion) => {
console.log("board", boardInfoFileVersion);
};
handleTask = (taskFileVersion: TaskFileVersion) => {};
// boards
createBoard = (name: string): void => {
const file: File = FileModel.createFile();
const boardInfoFileContent: BoardInfoFileContent =
TaskModel.createBoardInfoFileContent(name, Color.Standard);
this.fileModel.addOrUpdateFile(file, boardInfoFileContent);
const boardInfoFileVersion: BoardInfoVersion =
TaskModel.createBoardInfoFileVersion(v4(), name, Color.Standard);
this.createOrUpdateBoard(boardInfoFileVersion);
};
listBoardIds = (): string[] => {
const boardDirPath: string[] = this.getBoardDirPath();
const boardNames: string[] = this.storageModel.list(boardDirPath);
const boardContainerPath: string[] = this.getBoardContainerPath();
const boardNames: string[] = this.storageModel.list(boardContainerPath);
return boardNames;
};
getBoardInfo = (boardId: string): BoardInfoFileContent | null => {
const boardInfoPath: string[] = this.getBoardInfoPath(boardId);
const boardInfoFileContentOrNull: BoardInfoFileContent | null =
this.storageModel.readStringifiable(
boardInfoPath,
BoardInfoFileContentReference
getBoardInfo = (fileId: string): BoardInfoVersion | null => {
const boardInfoFileVersionOrNull: BoardInfoVersion | null =
this.fileModel.getLatestFileVersion(
fileId,
BoardInfoFileVersionReference
);
return boardInfoFileContentOrNull;
return boardInfoFileVersionOrNull;
};
createOrUpdateBoard = (boardInfoFileVersion: BoardInfoVersion): void => {
// store info
this.fileModel.addFileVersion(boardInfoFileVersion);
// add to list
const boardDirectoryPath: string[] = this.getBoardDirectoryPath(
boardInfoFileVersion.fileId
);
this.storageModel.write(boardDirectoryPath, "");
};
//tasks
createTask = (boardId: string, name: string): void => {
const file: File = FileModel.createFile();
const taskFileContent: TaskFileContent = TaskModel.createTaskFileContent(
const taskFileVersion: TaskFileVersion = TaskModel.createTaskFileVersion(
v4(),
boardId,
name
);
this.fileModel.addOrUpdateFile(file, taskFileContent);
this.fileModel.addFileVersion(taskFileVersion);
};
listTaskIds = (boardName: string): string[] => {
const getTaskDirPath: string[] = this.getTaskDirPath(boardName);
const getTaskDirPath: string[] = this.getTaskContainerPath(boardName);
const fileIds: string[] = this.storageModel.list(getTaskDirPath);
return fileIds;
};
getTaskVersionNames = (boardName: string, fileId: string): string[] => {
const fileDirectoryPath: string[] = this.getTaskPath(boardName, fileId);
const versionNames: string[] = this.storageModel.list(fileDirectoryPath);
return versionNames;
};
getTaskFileContent = (
boardName: string,
fileId: string,
versionName: string
): TaskFileContent | null => {
const fileContentPath: string[] = this.getTaskContentPath(
boardName,
fileId,
versionName
);
const taskFileContentOrNull: TaskFileContent | null =
this.storageModel.readStringifiable(
fileContentPath,
TaskFileContentReference
);
return taskFileContentOrNull;
};
moveTask = (
taskFileId: string,
oldBoardId: string,
@@ -153,28 +140,34 @@ export default class TaskModel {
}
// utility
static createBoardInfoFileContent = (
static createBoardInfoFileVersion = (
fileId: string,
name: string,
color: Color
): BoardInfoFileContent => {
const fileContent: FileContent<"board"> =
FileModel.createFileContent("board");
): BoardInfoVersion => {
const fileVersion: FileVersion<"board-info"> = FileModel.createFileVersion(
fileId,
"board-info"
);
return {
...fileContent,
...fileVersion,
name,
color,
};
};
static createTaskFileContent = (
static createTaskFileVersion = (
fileId: string,
name: string,
boardId: string
): TaskFileContent => {
const fileContent: FileContent<"task"> =
FileModel.createFileContent("task");
): TaskFileVersion => {
const fileVersion: FileVersion<"task"> = FileModel.createFileVersion(
fileId,
"task"
);
return {
...fileContent,
...fileVersion,
name,
boardId,
@@ -184,17 +177,16 @@ export default class TaskModel {
export const subDirectories = {
boards: "boards",
boardInfo: "info",
boardTasks: "tasks",
};
// types
export interface BoardInfoFileContent extends FileContent<"board"> {
export interface BoardInfoVersion extends FileVersion<"board-info"> {
name: string;
color: Color;
}
export interface TaskFileContent extends FileContent<"task"> {
export interface TaskFileVersion extends FileVersion<"task"> {
name: string;
boardId: string;
@@ -209,21 +201,24 @@ export interface TaskFileContent extends FileContent<"task"> {
}
// reference
export const BoardInfoFileContentReference: BoardInfoFileContent = {
export const BoardInfoFileVersionReference: BoardInfoVersion = {
dataVersion: DATA_VERSION,
id: "",
fileId: "string",
fileVersionId: "",
creationDate: "",
type: "board",
type: "board-info",
name: "",
color: "" as Color,
};
export const TaskFileContentReference: TaskFileContent = {
export const TaskFileVersionReference: TaskFileVersion = {
dataVersion: DATA_VERSION,
id: "",
fileId: "string",
fileVersionId: "",
creationDate: "",
type: "task",