cleanup, add handleStringifiedFile and addFile
This commit is contained in:
Vendored
+68
-28
@@ -276,6 +276,12 @@
|
|||||||
return element;
|
return element;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// src/Model/Utility/typeSafety.ts
|
||||||
|
var DATA_VERSION = "v2";
|
||||||
|
function checkIsValidObject(object) {
|
||||||
|
return object.dataVersion == DATA_VERSION;
|
||||||
|
}
|
||||||
|
|
||||||
// src/Model/Utility/utility.ts
|
// src/Model/Utility/utility.ts
|
||||||
function createTimestamp() {
|
function createTimestamp() {
|
||||||
return (/* @__PURE__ */ new Date()).toISOString();
|
return (/* @__PURE__ */ new Date()).toISOString();
|
||||||
@@ -284,18 +290,21 @@
|
|||||||
return JSON.stringify(data, null, 4);
|
return JSON.stringify(data, null, 4);
|
||||||
}
|
}
|
||||||
function parse(string) {
|
function parse(string) {
|
||||||
return JSON.parse(string);
|
try {
|
||||||
|
return JSON.parse(string);
|
||||||
|
} catch {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function parseValidObject(string) {
|
||||||
|
const parsed = parse(string);
|
||||||
|
if (checkIsValidObject(parsed) == false) return null;
|
||||||
|
return parsed;
|
||||||
}
|
}
|
||||||
function localeCompare(a, b) {
|
function localeCompare(a, b) {
|
||||||
return a.localeCompare(b);
|
return a.localeCompare(b);
|
||||||
}
|
}
|
||||||
|
|
||||||
// src/Model/Utility/typeSafety.ts
|
|
||||||
var DATA_VERSION = "v2";
|
|
||||||
function checkIsValidObject(object) {
|
|
||||||
return object.dataVersion == DATA_VERSION;
|
|
||||||
}
|
|
||||||
|
|
||||||
// src/Model/storageModel.ts
|
// src/Model/storageModel.ts
|
||||||
var PATH_COMPONENT_SEPARATOR = "\\";
|
var PATH_COMPONENT_SEPARATOR = "\\";
|
||||||
var StorageModel = class _StorageModel {
|
var StorageModel = class _StorageModel {
|
||||||
@@ -425,6 +434,24 @@
|
|||||||
chatMessages: (id) => [DATA_VERSION, "chat", id, "messages"]
|
chatMessages: (id) => [DATA_VERSION, "chat", id, "messages"]
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// src/Model/fileModel.ts
|
||||||
|
var FileModel = class {
|
||||||
|
chatModel;
|
||||||
|
// handler
|
||||||
|
handleStringifiedFile = (stringifiedFile) => {
|
||||||
|
const file = parseValidObject(stringifiedFile);
|
||||||
|
if (file == null) return;
|
||||||
|
};
|
||||||
|
// methods
|
||||||
|
addFile = (file) => {
|
||||||
|
this.chatModel.sendMessage("", file);
|
||||||
|
};
|
||||||
|
// init
|
||||||
|
constructor(chatModel) {
|
||||||
|
this.chatModel = chatModel;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// src/Model/Utility/crypto.ts
|
// src/Model/Utility/crypto.ts
|
||||||
var IV_SIZE = 12;
|
var IV_SIZE = 12;
|
||||||
var ENCRYPTION_ALG = "AES-GCM";
|
var ENCRYPTION_ALG = "AES-GCM";
|
||||||
@@ -516,6 +543,7 @@
|
|||||||
storageModel;
|
storageModel;
|
||||||
settingsModel;
|
settingsModel;
|
||||||
chatListModel;
|
chatListModel;
|
||||||
|
fileModel;
|
||||||
// data
|
// data
|
||||||
id;
|
id;
|
||||||
info;
|
info;
|
||||||
@@ -569,9 +597,12 @@
|
|||||||
};
|
};
|
||||||
addMessage = async (chatMessage) => {
|
addMessage = async (chatMessage) => {
|
||||||
await this.decryptMessage(chatMessage);
|
await this.decryptMessage(chatMessage);
|
||||||
const messagePath = this.getMessagePath(chatMessage.id);
|
if (chatMessage.body != "") {
|
||||||
this.storageModel.writeStringifiable(messagePath, chatMessage);
|
const messagePath = this.getMessagePath(chatMessage.id);
|
||||||
this.chatMessageHandler(chatMessage);
|
this.storageModel.writeStringifiable(messagePath, chatMessage);
|
||||||
|
this.chatMessageHandler(chatMessage);
|
||||||
|
}
|
||||||
|
this.fileModel.handleStringifiedFile(chatMessage.stringifiedFile);
|
||||||
};
|
};
|
||||||
// delete
|
// delete
|
||||||
delete = () => {
|
delete = () => {
|
||||||
@@ -613,7 +644,7 @@
|
|||||||
return sorted;
|
return sorted;
|
||||||
}
|
}
|
||||||
// messaging
|
// messaging
|
||||||
sendMessage = async (body) => {
|
sendMessage = async (body, file) => {
|
||||||
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];
|
||||||
@@ -621,20 +652,19 @@
|
|||||||
allChannels.push(secondaryChannel);
|
allChannels.push(secondaryChannel);
|
||||||
}
|
}
|
||||||
const combinedChannel = allChannels.join("/");
|
const combinedChannel = allChannels.join("/");
|
||||||
if (this.info.encryptionKey != "") {
|
const chatMessage = await _ChatModel.createChatMessage(
|
||||||
body = await encryptString(body, this.info.encryptionKey);
|
|
||||||
}
|
|
||||||
const chatMessage = _ChatModel.createChatMessage(
|
|
||||||
combinedChannel,
|
combinedChannel,
|
||||||
senderName,
|
senderName,
|
||||||
body
|
this.info.encryptionKey,
|
||||||
|
body,
|
||||||
|
file
|
||||||
);
|
);
|
||||||
this.addMessage(chatMessage);
|
this.addMessage(chatMessage);
|
||||||
this.connectionModel.sendMessageOrStore(chatMessage);
|
this.connectionModel.sendMessageOrStore(chatMessage);
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
handleMessage = (body) => {
|
handleMessage = (body) => {
|
||||||
const chatMessage = _ChatModel.parseMessage(body);
|
const chatMessage = parseValidObject(body);
|
||||||
if (chatMessage == null) return;
|
if (chatMessage == null) return;
|
||||||
chatMessage.status = "received" /* Received */;
|
chatMessage.status = "received" /* Received */;
|
||||||
this.addMessage(chatMessage);
|
this.addMessage(chatMessage);
|
||||||
@@ -648,7 +678,12 @@
|
|||||||
chatMessage.body,
|
chatMessage.body,
|
||||||
this.info.encryptionKey
|
this.info.encryptionKey
|
||||||
);
|
);
|
||||||
|
const decryptedFile = await decryptString(
|
||||||
|
chatMessage.stringifiedFile ?? "",
|
||||||
|
this.info.encryptionKey
|
||||||
|
);
|
||||||
chatMessage.body = decryptedBody;
|
chatMessage.body = decryptedBody;
|
||||||
|
chatMessage.stringifiedFile = decryptedFile;
|
||||||
};
|
};
|
||||||
setMessageHandler = (handler) => {
|
setMessageHandler = (handler) => {
|
||||||
this.chatMessageHandler = handler;
|
this.chatMessageHandler = handler;
|
||||||
@@ -667,6 +702,7 @@
|
|||||||
this.loadColor();
|
this.loadColor();
|
||||||
this.subscribe();
|
this.subscribe();
|
||||||
connectionModel2.setMessageSentHandler(this.handleMessageSent);
|
connectionModel2.setMessageSentHandler(this.handleMessageSent);
|
||||||
|
this.fileModel = new FileModel(this);
|
||||||
}
|
}
|
||||||
// utility
|
// utility
|
||||||
static generateChatInfo = (primaryChannel) => {
|
static generateChatInfo = (primaryChannel) => {
|
||||||
@@ -677,25 +713,29 @@
|
|||||||
hasUnreadMessages: false
|
hasUnreadMessages: false
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
static createChatMessage = (channel, sender, body) => {
|
static createChatMessage = async (channel, sender, encryptionKey, body, file) => {
|
||||||
return {
|
const chatMessage = {
|
||||||
dataVersion: "v2",
|
dataVersion: "v2",
|
||||||
id: v4_default(),
|
id: v4_default(),
|
||||||
channel,
|
channel,
|
||||||
sender,
|
sender,
|
||||||
body,
|
body,
|
||||||
dateSent: createTimestamp(),
|
dateSent: createTimestamp(),
|
||||||
status: "outbox" /* Outbox */
|
status: "outbox" /* Outbox */,
|
||||||
|
stringifiedFile: ""
|
||||||
};
|
};
|
||||||
};
|
if (file != void 0) {
|
||||||
static parseMessage = (string) => {
|
const stringifiedFile = stringify(file);
|
||||||
try {
|
chatMessage.stringifiedFile = stringifiedFile;
|
||||||
const parsed = parse(string);
|
|
||||||
if (checkIsValidObject(parsed) == false) return null;
|
|
||||||
return parsed;
|
|
||||||
} catch {
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
if (encryptionKey != "") {
|
||||||
|
chatMessage.body = await encryptString(chatMessage.body, encryptionKey);
|
||||||
|
chatMessage.stringifiedFile = await encryptString(
|
||||||
|
chatMessage.stringifiedFile,
|
||||||
|
encryptionKey
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return chatMessage;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
import { checkIsValidObject } from "./typeSafety";
|
||||||
|
|
||||||
// date
|
// date
|
||||||
export function createTimestamp(): string {
|
export function createTimestamp(): string {
|
||||||
return new Date().toISOString();
|
return new Date().toISOString();
|
||||||
@@ -9,10 +11,20 @@ export function stringify(data: any): string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function parse(string: string): any {
|
export function parse(string: string): any {
|
||||||
return JSON.parse(string);
|
try {
|
||||||
|
return JSON.parse(string);
|
||||||
|
} catch {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function parseValidObject<T>(string: string): T|null {
|
||||||
|
const parsed: any = parse(string);
|
||||||
|
if (checkIsValidObject(parsed) == false) return null;
|
||||||
|
return parsed;
|
||||||
}
|
}
|
||||||
|
|
||||||
// sort
|
// sort
|
||||||
export function localeCompare(a: string, b: string): number {
|
export function localeCompare(a: string, b: string): number {
|
||||||
return a.localeCompare(b);
|
return a.localeCompare(b);
|
||||||
}
|
}
|
||||||
|
|||||||
+49
-26
@@ -1,13 +1,18 @@
|
|||||||
// this file is responsible for managing chats.
|
// this file is responsible for managing chats.
|
||||||
|
|
||||||
|
import FileModel, { File } from "./fileModel";
|
||||||
import StorageModel, { storageKeys } from "./storageModel";
|
import StorageModel, { storageKeys } from "./storageModel";
|
||||||
import { createTimestamp, parse } from "./Utility/utility";
|
import {
|
||||||
|
createTimestamp,
|
||||||
|
parse,
|
||||||
|
parseValidObject,
|
||||||
|
stringify,
|
||||||
|
} from "./Utility/utility";
|
||||||
import { decryptString, encryptString } from "./Utility/crypto";
|
import { decryptString, encryptString } from "./Utility/crypto";
|
||||||
|
|
||||||
import ChatListModel from "./chatListModel";
|
import ChatListModel from "./chatListModel";
|
||||||
import { Color } from "../ViewModel/colors";
|
import { Color } from "../ViewModel/colors";
|
||||||
import ConnectionModel from "./connectionModel";
|
import ConnectionModel from "./connectionModel";
|
||||||
import FileModel from "./fileModel";
|
|
||||||
import SettingsModel from "./settingsModel";
|
import SettingsModel from "./settingsModel";
|
||||||
import { checkIsValidObject } from "./Utility/typeSafety";
|
import { checkIsValidObject } from "./Utility/typeSafety";
|
||||||
import { v4 } from "uuid";
|
import { v4 } from "uuid";
|
||||||
@@ -85,9 +90,16 @@ export default class ChatModel {
|
|||||||
|
|
||||||
addMessage = async (chatMessage: ChatMessage): Promise<void> => {
|
addMessage = async (chatMessage: ChatMessage): Promise<void> => {
|
||||||
await this.decryptMessage(chatMessage);
|
await this.decryptMessage(chatMessage);
|
||||||
const messagePath: string[] = this.getMessagePath(chatMessage.id);
|
|
||||||
this.storageModel.writeStringifiable(messagePath, chatMessage);
|
// message
|
||||||
this.chatMessageHandler(chatMessage);
|
if (chatMessage.body != "") {
|
||||||
|
const messagePath: string[] = this.getMessagePath(chatMessage.id);
|
||||||
|
this.storageModel.writeStringifiable(messagePath, chatMessage);
|
||||||
|
this.chatMessageHandler(chatMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
// file
|
||||||
|
this.fileModel.handleStringifiedFile(chatMessage.stringifiedFile);
|
||||||
};
|
};
|
||||||
|
|
||||||
// delete
|
// delete
|
||||||
@@ -140,7 +152,7 @@ export default class ChatModel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// messaging
|
// messaging
|
||||||
sendMessage = async (body: string): 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;
|
||||||
|
|
||||||
@@ -150,14 +162,13 @@ export default class ChatModel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const combinedChannel: string = allChannels.join("/");
|
const combinedChannel: string = allChannels.join("/");
|
||||||
if (this.info.encryptionKey != "") {
|
|
||||||
body = await encryptString(body, this.info.encryptionKey);
|
|
||||||
}
|
|
||||||
|
|
||||||
const chatMessage: ChatMessage = ChatModel.createChatMessage(
|
const chatMessage: ChatMessage = await ChatModel.createChatMessage(
|
||||||
combinedChannel,
|
combinedChannel,
|
||||||
senderName,
|
senderName,
|
||||||
body
|
this.info.encryptionKey,
|
||||||
|
body,
|
||||||
|
file
|
||||||
);
|
);
|
||||||
|
|
||||||
this.addMessage(chatMessage);
|
this.addMessage(chatMessage);
|
||||||
@@ -166,7 +177,7 @@ export default class ChatModel {
|
|||||||
};
|
};
|
||||||
|
|
||||||
handleMessage = (body: string): void => {
|
handleMessage = (body: string): void => {
|
||||||
const chatMessage: ChatMessage | null = ChatModel.parseMessage(body);
|
const chatMessage: ChatMessage | null = parseValidObject<ChatMessage>(body);
|
||||||
if (chatMessage == null) return;
|
if (chatMessage == null) return;
|
||||||
|
|
||||||
chatMessage.status = ChatMessageStatus.Received;
|
chatMessage.status = ChatMessageStatus.Received;
|
||||||
@@ -183,7 +194,12 @@ export default class ChatModel {
|
|||||||
chatMessage.body,
|
chatMessage.body,
|
||||||
this.info.encryptionKey
|
this.info.encryptionKey
|
||||||
);
|
);
|
||||||
|
const decryptedFile: string = await decryptString(
|
||||||
|
chatMessage.stringifiedFile ?? "",
|
||||||
|
this.info.encryptionKey
|
||||||
|
);
|
||||||
chatMessage.body = decryptedBody;
|
chatMessage.body = decryptedBody;
|
||||||
|
chatMessage.stringifiedFile = decryptedFile;
|
||||||
};
|
};
|
||||||
|
|
||||||
setMessageHandler = (handler: (chatMessage: ChatMessage) => void): void => {
|
setMessageHandler = (handler: (chatMessage: ChatMessage) => void): void => {
|
||||||
@@ -227,12 +243,14 @@ export default class ChatModel {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
static createChatMessage = (
|
static createChatMessage = async (
|
||||||
channel: string,
|
channel: string,
|
||||||
sender: string,
|
sender: string,
|
||||||
body: string
|
encryptionKey: string,
|
||||||
): ChatMessage => {
|
body: string,
|
||||||
return {
|
file?: File
|
||||||
|
): Promise<ChatMessage> => {
|
||||||
|
const chatMessage: ChatMessage = {
|
||||||
dataVersion: "v2",
|
dataVersion: "v2",
|
||||||
|
|
||||||
id: v4(),
|
id: v4(),
|
||||||
@@ -243,17 +261,22 @@ export default class ChatModel {
|
|||||||
dateSent: createTimestamp(),
|
dateSent: createTimestamp(),
|
||||||
|
|
||||||
status: ChatMessageStatus.Outbox,
|
status: ChatMessageStatus.Outbox,
|
||||||
|
stringifiedFile: "",
|
||||||
};
|
};
|
||||||
};
|
if (file != undefined) {
|
||||||
|
const stringifiedFile = stringify(file);
|
||||||
static parseMessage = (string: string): ChatMessage | null => {
|
chatMessage.stringifiedFile = stringifiedFile;
|
||||||
try {
|
|
||||||
const parsed: any = parse(string);
|
|
||||||
if (checkIsValidObject(parsed) == false) return null;
|
|
||||||
return parsed;
|
|
||||||
} catch {
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (encryptionKey != "") {
|
||||||
|
chatMessage.body = await encryptString(chatMessage.body, encryptionKey);
|
||||||
|
chatMessage.stringifiedFile = await encryptString(
|
||||||
|
chatMessage.stringifiedFile,
|
||||||
|
encryptionKey
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return chatMessage;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -284,5 +307,5 @@ export interface ChatMessage {
|
|||||||
|
|
||||||
status?: ChatMessageStatus;
|
status?: ChatMessageStatus;
|
||||||
|
|
||||||
stringifiedFile?: string;
|
stringifiedFile: string;
|
||||||
}
|
}
|
||||||
|
|||||||
+14
-1
@@ -1,10 +1,23 @@
|
|||||||
// this file is responsible for managing files within chats.
|
// this file is responsible for managing files within chats.
|
||||||
|
|
||||||
import ChatModel from "./chatModel";
|
import ChatModel, { ChatMessage } from "./chatModel";
|
||||||
|
|
||||||
|
import { parseValidObject } from "./Utility/utility";
|
||||||
|
|
||||||
export default class FileModel {
|
export default class FileModel {
|
||||||
chatModel: ChatModel;
|
chatModel: ChatModel;
|
||||||
|
|
||||||
|
// handler
|
||||||
|
handleStringifiedFile = (stringifiedFile: string): void => {
|
||||||
|
const file: File | null = parseValidObject<File>(stringifiedFile);
|
||||||
|
if (file == null) return;
|
||||||
|
};
|
||||||
|
|
||||||
|
// methods
|
||||||
|
addFile = (file: File): void => {
|
||||||
|
this.chatModel.sendMessage("", file);
|
||||||
|
};
|
||||||
|
|
||||||
// init
|
// init
|
||||||
constructor(chatModel: ChatModel) {
|
constructor(chatModel: ChatModel) {
|
||||||
this.chatModel = chatModel;
|
this.chatModel = chatModel;
|
||||||
|
|||||||
Reference in New Issue
Block a user