2024-07-27 00:33:42 +02:00
|
|
|
// this file is responsible for migrating data from v1 to v2.
|
|
|
|
|
|
|
|
|
|
import {
|
2026-04-01 08:29:39 +00:00
|
|
|
BoardInfoFileContent,
|
|
|
|
|
TaskFileContent,
|
2024-07-27 00:33:42 +02:00
|
|
|
} from "../Model/Files/boardsAndTasksModel";
|
|
|
|
|
import ChatModel, {
|
2026-04-01 08:29:39 +00:00
|
|
|
ChatMessage,
|
|
|
|
|
ChatMessageStatus,
|
2024-07-27 00:33:42 +02:00
|
|
|
} from "../Model/Chat/chatModel";
|
2026-04-01 08:29:39 +00:00
|
|
|
import {
|
|
|
|
|
getLocalStorageItemAndClear,
|
|
|
|
|
parseArray,
|
|
|
|
|
parseOrFallback,
|
|
|
|
|
} from "../Model/Utility/utility";
|
2024-07-27 00:33:42 +02:00
|
|
|
|
|
|
|
|
import ChatListModel from "../Model/Chat/chatListModel";
|
|
|
|
|
import ConnectionModel from "../Model/Global/connectionModel";
|
|
|
|
|
import FileModel from "../Model/Files/fileModel";
|
|
|
|
|
import SettingsModel from "../Model/Global/settingsModel";
|
|
|
|
|
import { checkMatchesObjectStructure } from "../Model/Utility/typeSafety";
|
|
|
|
|
import { translations } from "../View/translations";
|
|
|
|
|
import { v4 } from "uuid";
|
|
|
|
|
|
|
|
|
|
export default class v1Upgrader {
|
2026-04-01 08:29:39 +00:00
|
|
|
// general
|
|
|
|
|
migrateSettings = (): void => {
|
|
|
|
|
const name: string | null = getLocalStorageItemAndClear("sender-name");
|
|
|
|
|
if (name != null) {
|
|
|
|
|
const parsedName: string = parseOrFallback(name);
|
|
|
|
|
this.settingsModel.setName(parsedName);
|
|
|
|
|
}
|
2024-07-27 00:33:42 +02:00
|
|
|
|
2026-04-01 08:29:39 +00:00
|
|
|
const firstDayOfWeek: string | null =
|
|
|
|
|
getLocalStorageItemAndClear("first-day-of-week");
|
|
|
|
|
if (firstDayOfWeek != null) {
|
|
|
|
|
const parsedFirstDayOfWeek: string =
|
|
|
|
|
parseOrFallback(firstDayOfWeek);
|
|
|
|
|
this.settingsModel.setFirstDayOfWeek(parsedFirstDayOfWeek);
|
|
|
|
|
}
|
|
|
|
|
};
|
2024-07-27 00:33:42 +02:00
|
|
|
|
2026-04-01 08:29:39 +00:00
|
|
|
migrateConnections = (): void => {
|
|
|
|
|
const previousAddressString: string | null =
|
|
|
|
|
getLocalStorageItemAndClear("previous-addresses");
|
|
|
|
|
if (previousAddressString == null) return;
|
2024-07-27 00:33:42 +02:00
|
|
|
|
2026-04-01 08:29:39 +00:00
|
|
|
const previousAddresses: any[] = parseArray(previousAddressString);
|
|
|
|
|
for (const address of previousAddresses) {
|
|
|
|
|
if (typeof address != "string") continue;
|
|
|
|
|
this.connectionModel.storeAddress(address);
|
|
|
|
|
}
|
|
|
|
|
};
|
2024-07-27 00:33:42 +02:00
|
|
|
|
2026-04-01 08:29:39 +00:00
|
|
|
// chats
|
|
|
|
|
migrateChats = (): void => {
|
|
|
|
|
const chatIdString: string | null =
|
|
|
|
|
getLocalStorageItemAndClear("chat-ids");
|
|
|
|
|
if (chatIdString == null) return;
|
2024-07-27 00:33:42 +02:00
|
|
|
|
2026-04-01 08:29:39 +00:00
|
|
|
const chatIds: any[] = parseArray(chatIdString);
|
|
|
|
|
for (const chatId of chatIds) {
|
|
|
|
|
if (typeof chatId != "string") continue;
|
|
|
|
|
this.migrateChatById(chatId);
|
|
|
|
|
}
|
|
|
|
|
};
|
2024-07-27 00:33:42 +02:00
|
|
|
|
2026-04-01 08:29:39 +00:00
|
|
|
migrateChatById = (id: string): void => {
|
|
|
|
|
// get primary channel
|
|
|
|
|
const primaryChannel: string | null = getLocalStorageItemAndClear(
|
|
|
|
|
storageKeys.primaryChannel(id),
|
2024-07-27 00:33:42 +02:00
|
|
|
);
|
2026-04-01 08:29:39 +00:00
|
|
|
if (primaryChannel == null) return;
|
|
|
|
|
const parsedPriamryChannel: string = parseOrFallback(primaryChannel);
|
|
|
|
|
|
|
|
|
|
// create chat
|
|
|
|
|
const chatModel: ChatModel =
|
|
|
|
|
this.chatListModel.createChat(parsedPriamryChannel);
|
|
|
|
|
|
|
|
|
|
// secondary channels
|
|
|
|
|
const secondaryChannelString: string | null =
|
|
|
|
|
getLocalStorageItemAndClear(storageKeys.secondaryChannels(id));
|
|
|
|
|
if (secondaryChannelString != null) {
|
|
|
|
|
const potentialSecondaryChannels: any[] = parseArray(
|
|
|
|
|
secondaryChannelString,
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
const confirmedSecondaryChannels: string[] = [];
|
|
|
|
|
for (const secondaryChannel of potentialSecondaryChannels) {
|
|
|
|
|
if (typeof secondaryChannel != "string") continue;
|
|
|
|
|
confirmedSecondaryChannels.push(secondaryChannel);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
chatModel.setSecondaryChannels(confirmedSecondaryChannels);
|
2024-07-27 00:33:42 +02:00
|
|
|
}
|
|
|
|
|
|
2026-04-01 08:29:39 +00:00
|
|
|
// encryption key
|
|
|
|
|
const encryptionKey: string | null = getLocalStorageItemAndClear(
|
|
|
|
|
storageKeys.encyptionKey(id),
|
2024-07-27 00:33:42 +02:00
|
|
|
);
|
2026-04-01 08:29:39 +00:00
|
|
|
if (encryptionKey != null) {
|
|
|
|
|
const parsedEncryptionKey: string = parseOrFallback(encryptionKey);
|
|
|
|
|
chatModel.setEncryptionKey(parsedEncryptionKey);
|
|
|
|
|
}
|
2024-07-27 00:33:42 +02:00
|
|
|
|
2026-04-01 08:29:39 +00:00
|
|
|
// messages
|
|
|
|
|
const messagesString: string =
|
|
|
|
|
getLocalStorageItemAndClear(storageKeys.messages(id)) ?? "";
|
|
|
|
|
const messageOutboxString: string =
|
|
|
|
|
getLocalStorageItemAndClear(storageKeys.outbox(id)) ?? "";
|
|
|
|
|
const potentialMessages: any[] = parseArray(messagesString);
|
|
|
|
|
const potentialMessagesInOutbox: any[] =
|
|
|
|
|
parseArray(messageOutboxString);
|
|
|
|
|
|
|
|
|
|
const addMessages = (
|
|
|
|
|
potentialMessages: any[],
|
|
|
|
|
status: ChatMessageStatus,
|
|
|
|
|
) => {
|
|
|
|
|
for (const potentialMessage of potentialMessages) {
|
|
|
|
|
const isV1ChatMessage: boolean = checkMatchesObjectStructure(
|
|
|
|
|
potentialMessage,
|
|
|
|
|
V1ChatMessageReference,
|
|
|
|
|
);
|
|
|
|
|
if (isV1ChatMessage == false) continue;
|
|
|
|
|
const v1ChatMessage: typeof V1ChatMessageReference =
|
|
|
|
|
potentialMessage;
|
|
|
|
|
|
|
|
|
|
const convertedChatMessage: ChatMessage = {
|
|
|
|
|
dataVersion: "v2",
|
|
|
|
|
|
|
|
|
|
id: v4(),
|
|
|
|
|
|
|
|
|
|
channel: v1ChatMessage.channel,
|
|
|
|
|
sender: v1ChatMessage.sender,
|
|
|
|
|
body: v1ChatMessage.body,
|
|
|
|
|
dateSent: v1ChatMessage.isoDate,
|
|
|
|
|
|
|
|
|
|
status,
|
|
|
|
|
stringifiedFile: "",
|
|
|
|
|
};
|
|
|
|
|
chatModel.addMessage(convertedChatMessage);
|
|
|
|
|
if (status == ChatMessageStatus.Outbox) {
|
|
|
|
|
this.connectionModel.sendMessageOrStore(
|
|
|
|
|
convertedChatMessage,
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
};
|
2024-07-27 00:33:42 +02:00
|
|
|
|
2026-04-01 08:29:39 +00:00
|
|
|
addMessages(potentialMessages, ChatMessageStatus.Received);
|
|
|
|
|
addMessages(potentialMessagesInOutbox, ChatMessageStatus.Outbox);
|
|
|
|
|
|
|
|
|
|
// objects
|
|
|
|
|
const objectsString: string =
|
|
|
|
|
getLocalStorageItemAndClear(storageKeys.objects(id)) ?? "";
|
|
|
|
|
const objectOutboxString: string =
|
|
|
|
|
getLocalStorageItemAndClear(storageKeys.itemOutbox(id)) ?? "";
|
|
|
|
|
const potentialObjects: any[] = parseArray(objectsString);
|
|
|
|
|
const potentialObjectsInOutbox: any[] = parseArray(objectOutboxString);
|
|
|
|
|
|
|
|
|
|
const addObjects = (potentialObjects: any[]): void => {
|
|
|
|
|
const board: BoardInfoFileContent =
|
|
|
|
|
chatModel.fileModel.boardsAndTasksModel.createBoard(
|
|
|
|
|
translations.updater.migrated,
|
|
|
|
|
);
|
|
|
|
|
chatModel.fileModel.boardsAndTasksModel.updateBoard(board);
|
|
|
|
|
|
|
|
|
|
for (const potentialObjectEntry of potentialObjects) {
|
|
|
|
|
const potentialObject = potentialObjectEntry[1];
|
|
|
|
|
const isV1MessageObject: boolean =
|
|
|
|
|
checkIsV1MessageObject(potentialObject);
|
|
|
|
|
if (isV1MessageObject == false) continue;
|
|
|
|
|
|
|
|
|
|
const objectId: string = potentialObject.id;
|
|
|
|
|
const objectName: string = potentialObject.title;
|
|
|
|
|
|
|
|
|
|
const contentVersions: any[] = Object.values(
|
|
|
|
|
potentialObject.contentVersions,
|
|
|
|
|
);
|
|
|
|
|
for (const potentialVersion of contentVersions) {
|
|
|
|
|
const isV1MessageObjectContent: boolean =
|
|
|
|
|
checkIsV1MessageObjectContent(potentialVersion);
|
|
|
|
|
if (isV1MessageObjectContent == false) continue;
|
|
|
|
|
|
|
|
|
|
const convertedTaskFileContent: TaskFileContent = {
|
|
|
|
|
dataVersion: "v2",
|
|
|
|
|
|
|
|
|
|
fileId: objectId,
|
|
|
|
|
fileContentId: FileModel.generateFileContentId(
|
|
|
|
|
potentialVersion.isoDateVersionCreated,
|
|
|
|
|
),
|
|
|
|
|
creationDate: potentialVersion.isoDateVersionCreated,
|
|
|
|
|
type: "task",
|
|
|
|
|
|
|
|
|
|
name: objectName ?? "",
|
|
|
|
|
boardId: board.fileId ?? "",
|
|
|
|
|
|
|
|
|
|
description: potentialVersion.noteContent ?? "",
|
|
|
|
|
|
|
|
|
|
category: potentialVersion.categoryName ?? "",
|
|
|
|
|
status: potentialVersion.status ?? "",
|
|
|
|
|
priority: potentialVersion.priority ?? "",
|
|
|
|
|
|
|
|
|
|
date: potentialVersion.date ?? "",
|
|
|
|
|
time: potentialVersion.time ?? "",
|
|
|
|
|
};
|
|
|
|
|
console.log(convertedTaskFileContent);
|
|
|
|
|
chatModel.fileModel.handleFileContent(
|
|
|
|
|
convertedTaskFileContent,
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
};
|
2024-07-27 00:33:42 +02:00
|
|
|
|
2026-04-01 08:29:39 +00:00
|
|
|
addObjects([...potentialObjects, ...potentialObjectsInOutbox]);
|
2024-07-27 00:33:42 +02:00
|
|
|
};
|
|
|
|
|
|
2026-04-01 08:29:39 +00:00
|
|
|
// init
|
|
|
|
|
constructor(
|
|
|
|
|
public settingsModel: SettingsModel,
|
|
|
|
|
public connectionModel: ConnectionModel,
|
|
|
|
|
public chatListModel: ChatListModel,
|
|
|
|
|
) {
|
|
|
|
|
this.migrateSettings();
|
|
|
|
|
this.migrateConnections();
|
|
|
|
|
this.migrateChats();
|
|
|
|
|
}
|
2024-07-27 00:33:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const storageKeys = {
|
2026-04-01 08:29:39 +00:00
|
|
|
viewType(id: string): string {
|
|
|
|
|
return id + "view-type";
|
|
|
|
|
},
|
2024-07-27 00:33:42 +02:00
|
|
|
|
2026-04-01 08:29:39 +00:00
|
|
|
hasUnread(id: string): string {
|
|
|
|
|
return id + "has-unread-messages";
|
|
|
|
|
},
|
2024-07-27 00:33:42 +02:00
|
|
|
|
2026-04-01 08:29:39 +00:00
|
|
|
primaryChannel(id: string): string {
|
|
|
|
|
return id + "primary-channel";
|
|
|
|
|
},
|
2024-07-27 00:33:42 +02:00
|
|
|
|
2026-04-01 08:29:39 +00:00
|
|
|
secondaryChannels(id: string): string {
|
|
|
|
|
return id + "secondary-channels";
|
|
|
|
|
},
|
2024-07-27 00:33:42 +02:00
|
|
|
|
2026-04-01 08:29:39 +00:00
|
|
|
encyptionKey(id: string): string {
|
|
|
|
|
return id + "encryption-key";
|
|
|
|
|
},
|
2024-07-27 00:33:42 +02:00
|
|
|
|
2026-04-01 08:29:39 +00:00
|
|
|
messages(id: string): string {
|
|
|
|
|
return id + "messages";
|
|
|
|
|
},
|
2024-07-27 00:33:42 +02:00
|
|
|
|
2026-04-01 08:29:39 +00:00
|
|
|
objects(id: string): string {
|
|
|
|
|
return id + "items";
|
|
|
|
|
},
|
2024-07-27 00:33:42 +02:00
|
|
|
|
2026-04-01 08:29:39 +00:00
|
|
|
outbox(id: string): string {
|
|
|
|
|
return id + "outbox";
|
|
|
|
|
},
|
2024-07-27 00:33:42 +02:00
|
|
|
|
2026-04-01 08:29:39 +00:00
|
|
|
itemOutbox(id: string): string {
|
|
|
|
|
return id + "item-outbox";
|
|
|
|
|
},
|
2024-07-27 00:33:42 +02:00
|
|
|
|
2026-04-01 08:29:39 +00:00
|
|
|
composingMessage(id: string): string {
|
|
|
|
|
return id + "composing-message";
|
|
|
|
|
},
|
2024-07-27 00:33:42 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const V1ChatMessageReference = {
|
2026-04-01 08:29:39 +00:00
|
|
|
channel: "",
|
|
|
|
|
sender: "",
|
|
|
|
|
body: "",
|
|
|
|
|
isoDate: "",
|
2024-07-27 00:33:42 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
function checkIsV1MessageObject(object: any): boolean {
|
2026-04-01 08:29:39 +00:00
|
|
|
if (object.id == undefined) return false;
|
|
|
|
|
if (object.title == undefined) return false;
|
|
|
|
|
if (object.contentVersions == undefined) return false;
|
2024-07-27 00:33:42 +02:00
|
|
|
|
2026-04-01 08:29:39 +00:00
|
|
|
return true;
|
2024-07-27 00:33:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function checkIsV1MessageObjectContent(object: any): boolean {
|
2026-04-01 08:29:39 +00:00
|
|
|
if (object.id == undefined) return false;
|
|
|
|
|
if (object.isoDateVersionCreated == undefined) return false;
|
2024-07-27 00:33:42 +02:00
|
|
|
|
2026-04-01 08:29:39 +00:00
|
|
|
return true;
|
|
|
|
|
}
|