From 9622c196cd2fda72f967b2fbd87b1d3a7d649c08 Mon Sep 17 00:00:00 2001 From: marlon-erler Date: Sat, 26 Sep 2026 23:32:38 +0200 Subject: [PATCH] format --- src/Model/Chat/chatModel.ts | 557 +++--- src/Model/Files/calendarModel.ts | 10 +- src/Model/Files/fileModel.ts | 204 ++- src/Model/Global/fileTransferModel.ts | 2 +- src/Model/Global/storageModel.ts | 65 +- src/Model/Utility/utility.ts | 455 ++--- src/View/ChatPages/boardPage.tsx | 5 +- src/View/ChatPages/messagePage.css | 7 +- src/View/ChatPages/messagePage.tsx | 317 ++-- src/View/ChatPages/settingsPage.tsx | 23 +- src/View/ChatPages/taskPage.tsx | 13 +- src/View/Components/chatEntry.tsx | 8 +- src/View/Components/chatMessage.tsx | 9 +- src/View/Components/newItemEntry.tsx | 30 +- src/View/Components/replyLink.tsx | 31 +- src/View/Components/replyViewHeader.tsx | 58 +- src/View/Components/taskEntry.tsx | 82 +- src/View/Components/usageBar.tsx | 40 +- src/View/Modals/chatMessageInfoModal.tsx | 11 +- src/View/Modals/searchModal.tsx | 187 +- src/View/Modals/settingsModal.tsx | 135 +- src/View/Modals/storageModal.tsx | 151 +- src/View/homePage.tsx | 350 ++-- src/View/translations.ts | 1576 +++++++++-------- src/ViewModel/Chat/chatListViewModel.ts | 12 +- src/ViewModel/Chat/chatMessageViewModel.ts | 178 +- src/ViewModel/Chat/chatViewModel.ts | 243 +-- src/ViewModel/Global/coreViewModel.ts | 196 +- src/ViewModel/Global/fileTransferViewModel.ts | 4 +- src/ViewModel/Global/notificationViewModel.ts | 17 +- src/ViewModel/Global/settingsViewModel.ts | 174 +- src/ViewModel/Global/storageViewModel.ts | 10 +- src/ViewModel/Pages/boardViewModel.ts | 8 +- src/ViewModel/Pages/calendarPageViewModel.ts | 86 +- src/ViewModel/Pages/messagePageViewModel.ts | 259 +-- src/ViewModel/Pages/settingsPageViewModel.ts | 27 +- src/ViewModel/Pages/taskPageViewModel.ts | 9 +- src/ViewModel/Pages/taskViewModel.ts | 12 +- src/base.css | 5 +- src/colors.css | 6 +- 40 files changed, 2866 insertions(+), 2706 deletions(-) diff --git a/src/Model/Chat/chatModel.ts b/src/Model/Chat/chatModel.ts index e6e6c0a3..f3e250c9 100644 --- a/src/Model/Chat/chatModel.ts +++ b/src/Model/Chat/chatModel.ts @@ -37,433 +37,442 @@ export default class ChatModel { info: ChatInfoFileContent; /* load function called in constructor */ get secondaryChannels(): string[] { - return this.info.secondaryChannels.sort(localeCompare); + return this.info.secondaryChannels.sort(localeCompare); } get color(): Colors { - const color = this.info.color as Colors; - if ([...Object.values(Colors)].includes(color)) return color; - return Colors.Standard; + const color = this.info.color as Colors; + if ([...Object.values(Colors)].includes(color)) return color; + return Colors.Standard; } // handler managers readonly chatMessageHandlerManager: HandlerManager = - new HandlerManager(); + new HandlerManager(); readonly reactionHandlerManager: HandlerManager = - new HandlerManager(); + new HandlerManager(); readonly changeHandlerManager: HandlerManager = new HandlerManager(); // paths readonly getBasePath = (): string[] => { - return StorageModel.getPath( - StorageModelSubPaths.Chat, - filePaths.chat.chatBase(this.id), - ); + return StorageModel.getPath( + StorageModelSubPaths.Chat, + filePaths.chat.chatBase(this.id), + ); }; readonly getInfoPath = (): string[] => { - return StorageModel.getPath( - StorageModelSubPaths.Chat, - filePaths.chat.info(this.id), - ); + return StorageModel.getPath( + StorageModelSubPaths.Chat, + filePaths.chat.info(this.id), + ); }; readonly getColorPath = (): string[] => { - return StorageModel.getPath( - StorageModelSubPaths.Chat, - filePaths.chat.color(this.id), - ); + return StorageModel.getPath( + StorageModelSubPaths.Chat, + filePaths.chat.color(this.id), + ); }; readonly getMessageDirPath = (): string[] => { - return StorageModel.getPath( - StorageModelSubPaths.Chat, - filePaths.chat.messages(this.id), - ); + return StorageModel.getPath( + StorageModelSubPaths.Chat, + filePaths.chat.messages(this.id), + ); }; readonly getMessagePath = (id: string): string[] => { - return [...this.getMessageDirPath(), id]; + return [...this.getMessageDirPath(), id]; }; readonly getReactionDirPath = (): string[] => { - return StorageModel.getPath( - StorageModelSubPaths.Chat, - filePaths.chat.reactions(this.id), - ); + return StorageModel.getPath( + StorageModelSubPaths.Chat, + filePaths.chat.reactions(this.id), + ); }; readonly getReactionPath = (id: string): string[] => { - return [...this.getReactionDirPath(), id]; + return [...this.getReactionDirPath(), id]; }; readonly getPreviousFilterPath = (): string[] => { - return [StorageModelSubPaths.Chat, ...filePaths.chat.previousFilter(this.id)]; - } + return [ + StorageModelSubPaths.Chat, + ...filePaths.chat.previousFilter(this.id), + ]; + }; // handlers readonly handleMessage = (body: string): void => { - const chatMessage: ChatMessage | null = parseValidObject( - body, - ChatMessageReference, - ); - if (chatMessage == null) return; + const chatMessage: ChatMessage | null = parseValidObject( + body, + ChatMessageReference, + ); + if (chatMessage == null) return; - chatMessage.status = ChatMessageStatuses.Received; + chatMessage.status = ChatMessageStatuses.Received; - this.addMessage(chatMessage); + this.addMessage(chatMessage); - if (chatMessage.stringifiedFile) return; - this.setReadStatus(true); + if (chatMessage.stringifiedFile) return; + this.setReadStatus(true); }; readonly handleReaction = (reaction: ChatMessageReaction | any): void => { - if ( - !checkMatchesObjectStructure(reaction, ChatMessageReactionReference) - ) - return; - const reactionPath: string[] = this.getReactionPath(reaction.fileId); + if ( + !checkMatchesObjectStructure(reaction, ChatMessageReactionReference) + ) + return; + const reactionPath: string[] = this.getReactionPath(reaction.fileId); - if (reaction.isDeleting == true) { - this.storageModel.remove(reactionPath); - } else { - this.storageModel.writeStringifiable(reactionPath, reaction); - } - this.reactionHandlerManager.trigger(reaction); + if (reaction.isDeleting == true) { + this.storageModel.remove(reactionPath); + } else { + this.storageModel.writeStringifiable(reactionPath, reaction); + } + this.reactionHandlerManager.trigger(reaction); }; readonly handleMessageSent = (chatMessage: ChatMessage): void => { - chatMessage.status = ChatMessageStatuses.Sent; - this.addMessage(chatMessage); + chatMessage.status = ChatMessageStatuses.Sent; + this.addMessage(chatMessage); }; // settings readonly setName = (name: string): void => { - this.info.name = name; - this.storeInfo(); - this.syncInfo(); - this.subscribe(); + this.info.name = name; + this.storeInfo(); + this.syncInfo(); + this.subscribe(); }; readonly setSecondaryChannels = (secondaryChannels: string[]): void => { - this.info.secondaryChannels = secondaryChannels; - this.storeInfo(); + this.info.secondaryChannels = secondaryChannels; + this.storeInfo(); }; readonly setEncryptionKey = (key: string): void => { - this.info.encryptionKey = key; - this.storeInfo(); + this.info.encryptionKey = key; + this.storeInfo(); }; readonly setColor = (color: Colors): void => { - this.info.color = color; - this.syncInfo(); - this.storeInfo(); + this.info.color = color; + this.syncInfo(); + this.storeInfo(); }; // messaging readonly addMessage = async (chatMessage: ChatMessage): Promise => { - await this.decryptMessage(chatMessage); + await this.decryptMessage(chatMessage); - // message - if (chatMessage.body != "") { - const messagePath: string[] = this.getMessagePath(chatMessage.id); - this.storageModel.writeStringifiable(messagePath, chatMessage); - this.chatMessageHandlerManager.trigger(chatMessage); - } + // message + if (chatMessage.body != "") { + const messagePath: string[] = this.getMessagePath(chatMessage.id); + this.storageModel.writeStringifiable(messagePath, chatMessage); + this.chatMessageHandlerManager.trigger(chatMessage); + } - // file - this.fileModel.handleStringifiedFileContent( - chatMessage.stringifiedFile, - ); + // file + this.fileModel.handleStringifiedFileContent( + chatMessage.stringifiedFile, + ); }; readonly getNameAndChannel = (): [string, string] | false => { - const senderName: string = this.settingsModel.username; - if (senderName == "") return false; + const senderName: string = this.settingsModel.username; + if (senderName == "") return false; - const allChannels: string[] = [this.id]; - for (const secondaryChannel of this.info.secondaryChannels) { - allChannels.push(secondaryChannel); - } + const allChannels: string[] = [this.id]; + for (const secondaryChannel of this.info.secondaryChannels) { + allChannels.push(secondaryChannel); + } - const combinedChannel: string = allChannels.join("/"); + const combinedChannel: string = allChannels.join("/"); - return [senderName, combinedChannel]; + return [senderName, combinedChannel]; }; readonly sendMessage = async ( - body: string, - inlineReplyId?: string, - fileContent?: FileContent, - ): Promise => { - const nameAndChannel = this.getNameAndChannel(); - if (nameAndChannel == false) return false; - const [senderName, combinedChannel] = nameAndChannel; + body: string, + inlineReplyId?: string, + fileContent?: FileContent, + ): Promise => { + const nameAndChannel = this.getNameAndChannel(); + if (nameAndChannel == false) return false; + const [senderName, combinedChannel] = nameAndChannel; - const chatMessage: ChatMessage = await ChatModel.createChatMessage( - combinedChannel, - senderName, - this.info.encryptionKey, - body, - inlineReplyId, - fileContent, - ); + const chatMessage: ChatMessage = await ChatModel.createChatMessage( + combinedChannel, + senderName, + this.info.encryptionKey, + body, + inlineReplyId, + fileContent, + ); - this.addMessage(chatMessage); - this.connectionModel.sendMessageOrStore(chatMessage); - return chatMessage.id; + this.addMessage(chatMessage); + this.connectionModel.sendMessageOrStore(chatMessage); + return chatMessage.id; }; readonly decryptMessage = async ( - chatMessage: ChatMessage, + chatMessage: ChatMessage, ): Promise => { - const decryptedBody: string = await decryptString( - chatMessage.body, - this.info.encryptionKey, - ); - const decryptedFile: string = await decryptString( - chatMessage.stringifiedFile ?? "", - this.info.encryptionKey, - ); - chatMessage.body = decryptedBody; - chatMessage.stringifiedFile = decryptedFile; + const decryptedBody: string = await decryptString( + chatMessage.body, + this.info.encryptionKey, + ); + const decryptedFile: string = await decryptString( + chatMessage.stringifiedFile ?? "", + this.info.encryptionKey, + ); + chatMessage.body = decryptedBody; + chatMessage.stringifiedFile = decryptedFile; }; readonly sendReaction = async ( - messageId: string, - content: ReactionSymbols, - isDeleting: boolean = false, + messageId: string, + content: ReactionSymbols, + isDeleting: boolean = false, ): Promise => { - const nameAndChannel = this.getNameAndChannel(); - if (nameAndChannel == false) return; - const [senderName] = nameAndChannel; + const nameAndChannel = this.getNameAndChannel(); + if (nameAndChannel == false) return; + const [senderName] = nameAndChannel; - const reaction = ChatModel.createMessageReaction( - messageId, - senderName, - content, - isDeleting, - ); - this.sendMessage("", undefined, reaction); - this.handleReaction(reaction); + const reaction = ChatModel.createMessageReaction( + messageId, + senderName, + content, + isDeleting, + ); + this.sendMessage("", undefined, reaction); + this.handleReaction(reaction); }; readonly subscribe = (): void => { - this.connectionModel.addChannel(this.id); + this.connectionModel.addChannel(this.id); }; readonly setReadStatus = (hasUnreadMessages: boolean): void => { - this.info.hasUnreadMessages = hasUnreadMessages; - this.storeInfo(); + this.info.hasUnreadMessages = hasUnreadMessages; + this.storeInfo(); }; // storage readonly storeInfo = (): void => { - this.storageModel.writeStringifiable(this.getInfoPath(), this.info); + this.storageModel.writeStringifiable(this.getInfoPath(), this.info); }; readonly syncInfo = (): void => { - this.sendMessage("", undefined, this.info); - } + this.sendMessage("", undefined, this.info); + }; readonly storeFilter = (filter: string): void => { - this.storageModel.write(this.getPreviousFilterPath(), filter); - } + this.storageModel.write(this.getPreviousFilterPath(), filter); + }; - readonly getFilter = (): string=> { - return this.storageModel.read(this.getPreviousFilterPath()) || ""; - } + readonly getFilter = (): string => { + return this.storageModel.read(this.getPreviousFilterPath()) || ""; + }; readonly delete = () => { - // untrack - this.chatListModel.untrackChat(this); + // untrack + this.chatListModel.untrackChat(this); - // delete - const dirPath: string[] = this.getBasePath(); - this.storageModel.removeRecursively(dirPath); + // delete + const dirPath: string[] = this.getBasePath(); + this.storageModel.removeRecursively(dirPath); }; // load readonly loadInfo = (): void => { - let info: ChatInfoFileContent | null = this.storageModel.readStringifiable( - this.getInfoPath(), - ChatInfoReference, - ); - this.info = (info || ChatModel.generateChatInfo("0", "0", Colors.Standard)); - this.storeInfo(); + let info: ChatInfoFileContent | null = + this.storageModel.readStringifiable( + this.getInfoPath(), + ChatInfoReference, + ); + this.info = + info || ChatModel.generateChatInfo("0", "0", Colors.Standard); + this.storeInfo(); }; readonly handleInfo = (info: ChatInfoFileContent): void => { - this.info = info; - this.changeHandlerManager.trigger(null); - this.storeInfo(); - } + this.info = info; + this.changeHandlerManager.trigger(null); + this.storeInfo(); + }; get messages(): ChatMessage[] { - const messageIds: string[] = this.storageModel.list( - this.getMessageDirPath(), - ); - if (!Array.isArray(messageIds)) return []; + const messageIds: string[] = this.storageModel.list( + this.getMessageDirPath(), + ); + if (!Array.isArray(messageIds)) return []; - const chatMessages: ChatMessage[] = []; - for (const messageId of messageIds) { - const messagePath: string[] = this.getMessagePath(messageId); - const chatMessage: ChatMessage | null = - this.storageModel.readStringifiable( - messagePath, - ChatMessageReference, - ); - if (chatMessage == null) continue; - chatMessages.push(chatMessage); - } + const chatMessages: ChatMessage[] = []; + for (const messageId of messageIds) { + const messagePath: string[] = this.getMessagePath(messageId); + const chatMessage: ChatMessage | null = + this.storageModel.readStringifiable( + messagePath, + ChatMessageReference, + ); + if (chatMessage == null) continue; + chatMessages.push(chatMessage); + } - const sorted = chatMessages.sort((a, b) => - a.dateSent.localeCompare(b.dateSent), - ); - return sorted; + const sorted = chatMessages.sort((a, b) => + a.dateSent.localeCompare(b.dateSent), + ); + return sorted; } get reactions(): ChatMessageReaction[] { - const reactionIds: string[] = this.storageModel.list( - this.getReactionDirPath(), - ); - if (!Array.isArray(reactionIds)) return []; + const reactionIds: string[] = this.storageModel.list( + this.getReactionDirPath(), + ); + if (!Array.isArray(reactionIds)) return []; - const reactions: ChatMessageReaction[] = []; - for (const reactionId of reactionIds) { - const reactionPath: string[] = this.getReactionPath(reactionId); - const reaction: ChatMessageReaction | null = - this.storageModel.readStringifiable( - reactionPath, - ChatMessageReactionReference, - ); - if (reaction == null) continue; - reactions.push(reaction); - } + const reactions: ChatMessageReaction[] = []; + for (const reactionId of reactionIds) { + const reactionPath: string[] = this.getReactionPath(reactionId); + const reaction: ChatMessageReaction | null = + this.storageModel.readStringifiable( + reactionPath, + ChatMessageReactionReference, + ); + if (reaction == null) continue; + reactions.push(reaction); + } - return reactions; + return reactions; } // init constructor( - storageModel: StorageModel, - connectionModel: ConnectionModel, - settingsModel: SettingsModel, - chatListModel: ChatListModel, - chatId: string, + storageModel: StorageModel, + connectionModel: ConnectionModel, + settingsModel: SettingsModel, + chatListModel: ChatListModel, + chatId: string, ) { - this.id = chatId; - this.connectionModel = connectionModel; - this.settingsModel = settingsModel; - this.storageModel = storageModel; - this.chatListModel = chatListModel; + this.id = chatId; + this.connectionModel = connectionModel; + this.settingsModel = settingsModel; + this.storageModel = storageModel; + this.chatListModel = chatListModel; - this.loadInfo(); - this.subscribe(); + this.loadInfo(); + this.subscribe(); - this.fileModel = new FileModel( - this.storageModel, - this.settingsModel, - this, - ); + this.fileModel = new FileModel( + this.storageModel, + this.settingsModel, + this, + ); } // utility static splitChannel(channelString: string): string[] { - return channelString.split("/"); + return channelString.split("/"); } - static generateChatInfo = (name: string, id: string, color: Colors): ChatInfoFileContent => { - const file = FileModel.createFileContent(id, "chat-info"); + static generateChatInfo = ( + name: string, + id: string, + color: Colors, + ): ChatInfoFileContent => { + const file = FileModel.createFileContent(id, "chat-info"); - return { - ...file, + return { + ...file, - name, - secondaryChannels: [], - encryptionKey: "", - color, - hasUnreadMessages: false, - }; + name, + secondaryChannels: [], + encryptionKey: "", + color, + hasUnreadMessages: false, + }; }; static createChatMessage = async ( - channel: string, - sender: string, - encryptionKey: string, - body: string, - inlineReplyId?: string, - fileContent?: FileContent, + channel: string, + sender: string, + encryptionKey: string, + body: string, + inlineReplyId?: string, + fileContent?: FileContent, ): Promise => { - const chatMessage: ChatMessage = { - dataVersion: DATA_VERSION, + const chatMessage: ChatMessage = { + dataVersion: DATA_VERSION, - id: v4(), + id: v4(), - channel, - sender, - body, - dateSent: createTimestamp(), - inlineReplyId, + channel, + sender, + body, + dateSent: createTimestamp(), + inlineReplyId, - status: ChatMessageStatuses.Outbox, - stringifiedFile: "", - }; - if (fileContent != undefined) { - const stringifiedFile: string = stringify(fileContent); - chatMessage.stringifiedFile = stringifiedFile; - } + status: ChatMessageStatuses.Outbox, + stringifiedFile: "", + }; + if (fileContent != undefined) { + const stringifiedFile: string = stringify(fileContent); + chatMessage.stringifiedFile = stringifiedFile; + } - if (encryptionKey != "") { - chatMessage.body = await encryptString( - chatMessage.body, - encryptionKey, - ); - chatMessage.stringifiedFile = await encryptString( - chatMessage.stringifiedFile, - encryptionKey, - ); - } + if (encryptionKey != "") { + chatMessage.body = await encryptString( + chatMessage.body, + encryptionKey, + ); + chatMessage.stringifiedFile = await encryptString( + chatMessage.stringifiedFile, + encryptionKey, + ); + } - return chatMessage; + return chatMessage; }; static createMessageReaction = ( - messageId: string, - sender: string, - content: ReactionSymbols, - isDeleting: boolean, + messageId: string, + sender: string, + content: ReactionSymbols, + isDeleting: boolean, ): ChatMessageReaction => { - const fileContent: FileContent<"reaction"> = - FileModel.createFileContent(v4(), "reaction"); - const reaction: ChatMessageReaction = { - ...fileContent, - fileId: ChatModel.createMessageReactionId(messageId, sender), + const fileContent: FileContent<"reaction"> = + FileModel.createFileContent(v4(), "reaction"); + const reaction: ChatMessageReaction = { + ...fileContent, + fileId: ChatModel.createMessageReactionId(messageId, sender), - messageId, - sender, - content, - isDeleting, - }; - return reaction; + messageId, + sender, + content, + isDeleting, + }; + return reaction; }; static createMessageReactionId = ( - messageId: string, - sender: string, + messageId: string, + sender: string, ): string => { - return messageId + sender; + return messageId + sender; }; } // types export enum ReactionSymbols { ThumbsUp = "👍", - Check = "✅", - Stop = "🛑", - Attention = "❗️", - DoubleAttention = "‼️", - Question = "❓", + Check = "✅", + Stop = "🛑", + Attention = "❗️", + DoubleAttention = "‼️", + Question = "❓", } export interface ChatInfoFileContent extends FileContent<"chat-info"> { @@ -478,9 +487,9 @@ export interface ChatInfoFileContent extends FileContent<"chat-info"> { export enum ChatMessageStatuses { Outbox = "outbox", - Sent = "sent", - Received = "received", - Other = "other", + Sent = "sent", + Received = "received", + Other = "other", } export interface ChatMessage extends ValidObject { @@ -498,7 +507,7 @@ export interface ChatMessage extends ValidObject { } export interface ChatMessageReaction -extends ValidObject, FileContent<"reaction"> { + extends ValidObject, FileContent<"reaction"> { readonly messageId: string; readonly sender: string; readonly content: ReactionSymbols | string; @@ -552,4 +561,4 @@ export const ChatMessageReactionReference: ChatMessageReaction = { content: "", isDeleting: false, -} +}; diff --git a/src/Model/Files/calendarModel.ts b/src/Model/Files/calendarModel.ts index dbe4ae05..e177581f 100644 --- a/src/Model/Files/calendarModel.ts +++ b/src/Model/Files/calendarModel.ts @@ -2,10 +2,10 @@ import FileModel, { FileModelSubPath } from "./fileModel"; import { TaskFileContent } from "./boardsAndTasksModel"; +import { isoToMonthString, padZero } from "../Utility/utility"; import StorageModel from "../Global/storageModel"; import SettingsModel from "../Global/settingsModel"; import CoreViewModel from "../../ViewModel/Global/coreViewModel"; -import {isoToMonthString, padZero} from "../Utility/utility"; export default class CalendarModel { readonly storageModel: StorageModel; @@ -35,9 +35,7 @@ export default class CalendarModel { readonly storeTaskReference = (taskFileContent: TaskFileContent): void => { if (taskFileContent.date == undefined) return; - const monthString: string = isoToMonthString( - taskFileContent.date, - ); + const monthString: string = isoToMonthString(taskFileContent.date); const monthPath: string[] = this.getMonthPath(monthString); const referencePath: string[] = [...monthPath, taskFileContent.fileId]; @@ -103,9 +101,7 @@ export default class CalendarModel { }; for (let i = 0; i < daysInMonth; i++) { - const paddedDate: string = padZero( - (i + 1).toString(), 2 - ); + const paddedDate: string = padZero((i + 1).toString(), 2); grid.days[paddedDate] = defaultValueCreator(); } diff --git a/src/Model/Files/fileModel.ts b/src/Model/Files/fileModel.ts index 54be8183..cd1af218 100644 --- a/src/Model/Files/fileModel.ts +++ b/src/Model/Files/fileModel.ts @@ -8,13 +8,21 @@ import { parseValidObject, stringify, } from "../Utility/utility"; -import { checkIsValidObject, checkMatchesObjectStructure, DATA_VERSION, ValidObject } from "../Utility/typeSafety"; +import { + checkIsValidObject, + checkMatchesObjectStructure, + DATA_VERSION, + ValidObject, +} from "../Utility/typeSafety"; import StorageModel, { StorageModelSubPaths, filePaths, } from "../Global/storageModel"; import SettingsModel from "../Global/settingsModel"; -import ChatModel, {ChatInfoFileContent, ChatInfoReference} from "../Chat/chatModel"; +import ChatModel, { + ChatInfoFileContent, + ChatInfoReference, +} from "../Chat/chatModel"; export default class FileModel { readonly storageModel: StorageModel; @@ -67,161 +75,165 @@ export default class FileModel { }; readonly handleFileContent = (fileContent: FileContent): void => { - console.log(fileContent.type); + console.log(fileContent.type); - if (fileContent.type == "chat-info") { - if (checkMatchesObjectStructure(fileContent, ChatInfoReference) == false) return; - this.chatModel.handleInfo(fileContent as ChatInfoFileContent); - } + if (fileContent.type == "chat-info") { + if ( + checkMatchesObjectStructure(fileContent, ChatInfoReference) == + false + ) + return; + this.chatModel.handleInfo(fileContent as ChatInfoFileContent); + } - const didStore: boolean = this.storeFileContent(fileContent); - if (didStore == false) return; + const didStore: boolean = this.storeFileContent(fileContent); + if (didStore == false) return; - switch (fileContent.type) { - case "board-info": - case "task": - this.boardsAndTasksModel.handleFileContent(fileContent); - break; - case "reaction": - this.chatModel.handleReaction(fileContent); - break; - } + switch (fileContent.type) { + case "board-info": + case "task": + this.boardsAndTasksModel.handleFileContent(fileContent); + break; + case "reaction": + this.chatModel.handleReaction(fileContent); + break; + } }; // methods readonly addFileContentAndSend = ( - fileContent: FileContent, + fileContent: FileContent, ): void => { - this.handleFileContent(fileContent); - this.chatModel.sendMessage("", undefined, fileContent); + this.handleFileContent(fileContent); + this.chatModel.sendMessage("", undefined, fileContent); }; // storage readonly storeFileContent = (fileContent: FileContent): boolean => { - const fileContentPath: string[] = this.getFileContentPath( - fileContent.fileId, - fileContent.fileContentId, - ); + const fileContentPath: string[] = this.getFileContentPath( + fileContent.fileId, + fileContent.fileContentId, + ); - // check if fileContent already exists - const existingFileContent: string | null = - this.storageModel.read(fileContentPath); - if (existingFileContent != null) return false; + // check if fileContent already exists + const existingFileContent: string | null = + this.storageModel.read(fileContentPath); + if (existingFileContent != null) return false; - const stringifiedContent: string = stringify(fileContent); - this.storageModel.write(fileContentPath, stringifiedContent); - return true; + const stringifiedContent: string = stringify(fileContent); + this.storageModel.write(fileContentPath, stringifiedContent); + return true; }; readonly listFileIds = (): string[] => { - return this.storageModel.list(this.basePath); + return this.storageModel.list(this.basePath); }; readonly listFileContentIds = (fileId: string): string[] => { - const filePath: string[] = this.getFilePath(fileId); - return this.storageModel.list(filePath); + const filePath: string[] = this.getFilePath(fileId); + return this.storageModel.list(filePath); }; readonly selectLatestFileContentId = ( - fileContentIds: string[], + fileContentIds: string[], ): string | undefined => { - return fileContentIds[fileContentIds.length - 1]; + return fileContentIds[fileContentIds.length - 1]; }; readonly getFileContent = >( - fileId: string, - fileContentName: string, - reference: T, + fileId: string, + fileContentName: string, + reference: T, ): T | null => { - const filePath: string[] = this.getFileContentPath( - fileId, - fileContentName, - ); - const fileContentOrNull: T | null = this.storageModel.readStringifiable( - filePath, - reference, - ); - return fileContentOrNull; + const filePath: string[] = this.getFileContentPath( + fileId, + fileContentName, + ); + const fileContentOrNull: T | null = this.storageModel.readStringifiable( + filePath, + reference, + ); + return fileContentOrNull; }; readonly getLatestFileContent = >( - fileId: string, - reference: T, + fileId: string, + reference: T, ): T | null => { - const fileContentsIds: string[] = this.listFileContentIds(fileId); - const latestFileContentId: string | undefined = - this.selectLatestFileContentId(fileContentsIds); - if (latestFileContentId == undefined) return null; + const fileContentsIds: string[] = this.listFileContentIds(fileId); + const latestFileContentId: string | undefined = + this.selectLatestFileContentId(fileContentsIds); + if (latestFileContentId == undefined) return null; - const fileContent: T | null = this.getFileContent( - fileId, - latestFileContentId, - reference, - ); - return fileContent; + const fileContent: T | null = this.getFileContent( + fileId, + latestFileContentId, + reference, + ); + return fileContent; }; // init constructor( - storageModel: StorageModel, - settingsModel: SettingsModel, - chatModel: ChatModel, + storageModel: StorageModel, + settingsModel: SettingsModel, + chatModel: ChatModel, ) { - this.chatModel = chatModel; - this.settingsModel = settingsModel; - this.storageModel = storageModel; + this.chatModel = chatModel; + this.settingsModel = settingsModel; + this.storageModel = storageModel; - this.boardsAndTasksModel = new BoardsAndTasksModel( - this.storageModel, - this.settingsModel, - chatModel, - this, - ); + this.boardsAndTasksModel = new BoardsAndTasksModel( + this.storageModel, + this.settingsModel, + chatModel, + this, + ); } // utility static generateFileContentId = (creationDate: string): string => { - return creationDate + v4(); + return creationDate + v4(); }; static createFileContent = ( - fileId: string, - type: T, + fileId: string, + type: T, ): FileContent => { - const creationDate: string = createTimestamp(); - const fileContentId: string = - FileModel.generateFileContentId(creationDate); + const creationDate: string = createTimestamp(); + const fileContentId: string = + FileModel.generateFileContentId(creationDate); - return { - dataVersion: DATA_VERSION, + return { + dataVersion: DATA_VERSION, - fileId, - fileContentId, - creationDate, - type, - }; + fileId, + fileContentId, + creationDate, + type, + }; }; } // paths export enum FileModelSubPath { Data = "data", - Model = "model", - Chat = "chat", - ModelView = "view", - ModelTask = "tasks", - ModelCalendar = "calendar", + Model = "model", + Chat = "chat", + ModelView = "view", + ModelTask = "tasks", + ModelCalendar = "calendar", } // types export interface FileContent extends ValidObject, StringEntryObject { - readonly fileId: string; - readonly fileContentId: string; - readonly creationDate: string; + readonly fileId: string; + readonly fileContentId: string; + readonly creationDate: string; - readonly type: T; - } + readonly type: T; +} // references export const FileContentReference: FileContent = { diff --git a/src/Model/Global/fileTransferModel.ts b/src/Model/Global/fileTransferModel.ts index a3990053..c9d98bda 100644 --- a/src/Model/Global/fileTransferModel.ts +++ b/src/Model/Global/fileTransferModel.ts @@ -103,7 +103,7 @@ export default class FileTransferModel { }; readonly handleDecryptedFile = (data: string): void => { - const parsed: any = parse(data); + const parsed: any = parse(data); const isFileData: boolean = checkMatchesObjectStructure( parsed, FileDataReference, diff --git a/src/Model/Global/storageModel.ts b/src/Model/Global/storageModel.ts index 3e660b19..7a76621a 100644 --- a/src/Model/Global/storageModel.ts +++ b/src/Model/Global/storageModel.ts @@ -1,5 +1,9 @@ - -import { bytesToMB, localeCompare, parseValidObject, stringify } from "../Utility/utility"; +import { + bytesToMB, + localeCompare, + parseValidObject, + stringify, +} from "../Utility/utility"; import { DATA_VERSION, ValidObject } from "../Utility/typeSafety"; export const PATH_COMPONENT_SEPARATOR = "\\"; @@ -152,36 +156,36 @@ export default class StorageModel { }; readonly determineCapacity = (): number => { - const KEY = "storage-capacity-check"; + const KEY = "storage-capacity-check"; - let chunk = "0"; - for (let i = 0; i < 1024*256; i++) { - chunk += "0"; - } + let chunk = "0"; + for (let i = 0; i < 1024 * 256; i++) { + chunk += "0"; + } - localStorage.setItem(KEY, ""); - while (true) { - try { - const current = localStorage.getItem(KEY); - console.log(current); - localStorage.setItem(KEY, current + chunk); - } catch (e) { - const capacity = this.calculateUsage(); - localStorage.removeItem(KEY); - return capacity; - } - } - } + localStorage.setItem(KEY, ""); + while (true) { + try { + const current = localStorage.getItem(KEY); + console.log(current); + localStorage.setItem(KEY, current + chunk); + } catch (e) { + const capacity = this.calculateUsage(); + localStorage.removeItem(KEY); + return capacity; + } + } + }; readonly calculateUsage = (): number => { - let data = JSON.stringify(localStorage); - const encoder = new TextEncoder(); - const encoded = encoder.encode(data); - const bytes = encoded.byteLength; - const mb = bytesToMB(bytes); - const rounded = Math.round(mb * 100)/100; - return rounded; - } + let data = JSON.stringify(localStorage); + const encoder = new TextEncoder(); + const encoded = encoder.encode(data); + const bytes = encoded.byteLength; + const mb = bytesToMB(bytes); + const rounded = Math.round(mb * 100) / 100; + return rounded; + }; // tree readonly initializeTree = (): void => { @@ -285,7 +289,10 @@ export const filePaths = { ...filePaths.chat.chatBase(id), "reactions", ], - previousFilter: (id: string) => [...filePaths.chat.chatBase(id), "previous-filter"], + previousFilter: (id: string) => [ + ...filePaths.chat.chatBase(id), + "previous-filter", + ], lastUsedPage: (id: string) => [ ...filePaths.chat.chatBase(id), "last-used-page", diff --git a/src/Model/Utility/utility.ts b/src/Model/Utility/utility.ts index 7d5f3e85..6a988390 100644 --- a/src/Model/Utility/utility.ts +++ b/src/Model/Utility/utility.ts @@ -1,7 +1,7 @@ import { checkIsValidObject, checkMatchesObjectStructure } from "./typeSafety"; -import * as React from "../../react"; -import {CalendarPage} from "../../View/ChatPages/calendarPage"; import CalendarModel from "../Files/calendarModel"; +import * as React from "../../react"; +import { CalendarPage } from "../../View/ChatPages/calendarPage"; export interface Stringifiable { toString(): string; @@ -20,37 +20,48 @@ export function createTimestamp(): string { return new Date().toISOString(); } -export function isoToDateString (dateISOString: string): string { +export function isoToDateString(dateISOString: string): string { const [year, month, date] = dateISOString.split("-"); const paddedDate = padZero(date ?? "", 2); return paddedDate; -}; +} -export function isoToMonthString (dateISOString: string): string { +export function isoToMonthString(dateISOString: string): string { const [year, month, _] = dateISOString.split("-"); return formatMonthStringFromParts(year, month); -}; +} export function formatISO(date: Date): string { - return formatISOFromParts(date.getFullYear(), date.getMonth()+1, date.getDate()) + return formatISOFromParts( + date.getFullYear(), + date.getMonth() + 1, + date.getDate(), + ); } -export function formatISOFromParts(year: number|string, month: number|string, date: number|string): string { +export function formatISOFromParts( + year: number | string, + month: number | string, + date: number | string, +): string { return [year, month, date] - .map((x, i) => i == 0 ? x : padZero(x.toString(), 2)) - .join("-"); + .map((x, i) => (i == 0 ? x : padZero(x.toString(), 2))) + .join("-"); +} + +export function formatMonthStringFromParts( + year: string = "", + month: string = "", +): string { + const paddedYear: string = padZero(year, 4); + const paddedMonth: string = padZero(month, 2); + return `${paddedYear}-${paddedMonth}`; } - -export function formatMonthStringFromParts (year: string = "", month: string = ""): string { - const paddedYear: string = padZero(year, 4); - const paddedMonth: string = padZero(month, 2); - return `${paddedYear}-${paddedMonth}`; - }; export function formatTime(date: Date): string { return [date.getHours(), date.getMinutes()] - .map(x => padZero(x.toString(), 2)) - .join(":"); + .map((x) => padZero(x.toString(), 2)) + .join(":"); } // filters @@ -64,11 +75,11 @@ export function filterObjectsByStringEntries( const matches: Set = new Set(); for (const object of objects) { - const doesMatch: boolean = checkDoesObjectMatchReference( - reference, - converter(object), - ); - if (doesMatch) matches.add(object); + const doesMatch: boolean = checkDoesObjectMatchReference( + reference, + converter(object), + ); + if (doesMatch) matches.add(object); } return matches; @@ -82,12 +93,12 @@ export function filterObjectsByWords( const matches: Set = new Set(); for (const object of objects) { - const doesMatch: boolean = checkDoesObjectMatchSearch( - query, - getStringsOfObject, - object, - ); - if (doesMatch) matches.add(object); + const doesMatch: boolean = checkDoesObjectMatchSearch( + query, + getStringsOfObject, + object, + ); + if (doesMatch) matches.add(object); } return matches; @@ -103,50 +114,55 @@ export function checkDoesObjectMatchSearch( const stringsInObject: string[] = getStringsOfObject(object); const wordsInObject: string[] = []; for (const string of stringsInObject) { - const lowercaseWordsInString = string - .toString() - .toLowerCase() - .split(" ") - .filter((word) => word != ""); - wordsInObject.push(...lowercaseWordsInString); + const lowercaseWordsInString = string + .toString() + .toLowerCase() + .split(" ") + .filter((word) => word != ""); + wordsInObject.push(...lowercaseWordsInString); } const lowercaseWordsInQuery = query - .toLowerCase() - .split(" ") - .filter((word) => word != ""); + .toLowerCase() + .split(" ") + .filter((word) => word != ""); for (const queryWord of lowercaseWordsInQuery) { - if (queryWord[0] == "-") { - // exclusion - const wordContent = queryWord.substring(1); - if (wordsInObject.includes(wordContent)) { - return false; - } - } else { - if (wordsInObject.includes(queryWord) == false) { - return false; - } - } + if (queryWord[0] == "-") { + // exclusion + const wordContent = queryWord.substring(1); + if (wordsInObject.includes(wordContent)) { + return false; + } + } else { + if (wordsInObject.includes(queryWord) == false) { + return false; + } + } } return true; } export default function implementFilter( - allItems: React.ListState|React.MapState, + allItems: React.ListState | React.MapState, matches: React.ListState, query: React.State, itemToString: (item: T) => string, ) { function update() { - matches.clear(); - allItems.value.forEach((item: T) => { - if (!itemToString(item).toLowerCase().includes(query.value.toLowerCase())) return; - matches.add(item); - allItems.handleRemoval(item, () => { - matches.remove(item); - }); - }); + matches.clear(); + allItems.value.forEach((item: T) => { + if ( + !itemToString(item) + .toLowerCase() + .includes(query.value.toLowerCase()) + ) + return; + matches.add(item); + allItems.handleRemoval(item, () => { + matches.remove(item); + }); + }); } query.subscribe(update); allItems.handleAddition(update); @@ -160,16 +176,16 @@ export class HandlerManager { // manage setHandler = (id: string, handler: Handler): void => { - this.handlers.set(id, handler); + this.handlers.set(id, handler); }; deleteHandler = (id: string): void => { - this.handlers.delete(id); + this.handlers.delete(id); }; // trigger trigger = (item: T): void => { - [...this.handlers.values()].forEach((handler) => handler(item)); + [...this.handlers.values()].forEach((handler) => handler(item)); }; } @@ -181,26 +197,26 @@ export class IndexManager { // methods update = (items: T[]): void => { - this.sortedStrings = []; + this.sortedStrings = []; - let strings: string[] = []; - for (const item of items) { - const string: string = this.itemToString(item); - strings.push(string); - } + let strings: string[] = []; + for (const item of items) { + const string: string = this.itemToString(item); + strings.push(string); + } - this.sortedStrings = strings.sort(localeCompare); + this.sortedStrings = strings.sort(localeCompare); }; getIndex = (item: T): number => { - const string: string = this.itemToString(item); - const index: number = this.sortedStrings.indexOf(string); - return index; + const string: string = this.itemToString(item); + const index: number = this.sortedStrings.indexOf(string); + return index; }; // init constructor(itemToString: (item: T) => string) { - this.itemToString = itemToString; + this.itemToString = itemToString; } } @@ -213,7 +229,7 @@ export function getLocalStorageItemAndClear(key: string): string | null { } export function bytesToMB(bytes: number): number { - return bytes / (1024*1024); + return bytes / (1024 * 1024); } // string & parsing @@ -227,9 +243,9 @@ export function padZero(string: string | undefined, length: number): string { export function parse(string: string): any { try { - return JSON.parse(string); + return JSON.parse(string); } catch { - return {}; + return {}; } } @@ -238,8 +254,8 @@ export function parseValidObject(string: string, reference: T): T | null { if (checkIsValidObject(parsed) == false) return null; const doesMatchReference: boolean = checkMatchesObjectStructure( - parsed, - reference, + parsed, + reference, ); if (doesMatchReference == false) return null; @@ -248,9 +264,9 @@ export function parseValidObject(string: string, reference: T): T | null { export function parseOrFallback(inputString: string): any { try { - return JSON.parse(inputString); + return JSON.parse(inputString); } catch { - return inputString; + return inputString; } } @@ -271,27 +287,30 @@ export interface PinchToZoomData { x: number; y: number; } -export function implementPinchZoom(canvas: HTMLElement, data: React.State) { +export function implementPinchZoom( + canvas: HTMLElement, + data: React.State, +) { let pinching = false; let dragging = false; let lastElement: HTMLElement | undefined = undefined; let initialDistance: number, - initialZoom: number, - initialX: number, - initialY: number, - initialTouchX: number, - initialTouchY: number; + initialZoom: number, + initialX: number, + initialY: number, + initialTouchX: number, + initialTouchY: number; function reset() { - initialDistance = 0; + initialDistance = 0; - initialZoom = 1; + initialZoom = 1; - initialX = 0; - initialY = 0; - initialTouchX = 0; - initialTouchY = 0; + initialX = 0; + initialY = 0; + initialTouchX = 0; + initialTouchY = 0; } reset(); @@ -301,117 +320,117 @@ export function implementPinchZoom(canvas: HTMLElement, data: React.State canvas.querySelector(".zoom"); const distance = (e: TouchEvent) => - Math.hypot( - e.touches[0].pageX - e.touches[1].pageX, - e.touches[0].pageY - e.touches[1].pageY, - ); + Math.hypot( + e.touches[0].pageX - e.touches[1].pageX, + e.touches[0].pageY - e.touches[1].pageY, + ); const point = (e: TouchEvent, direction: "x" | "y", i: number) => - e.touches[i][direction == "x" ? "clientX" : "clientY"]; + e.touches[i][direction == "x" ? "clientX" : "clientY"]; const midpoint = (e: TouchEvent, direction: "x" | "y") => - (point(e, direction, 0) + point(e, direction, 1)) / 2; + (point(e, direction, 0) + point(e, direction, 1)) / 2; function apply(zoom: number, _offset?: [number, number]) { - if (zoom < MIN) return apply(MIN, _offset); - if (zoom > MAX) return apply(5, _offset); + if (zoom < MIN) return apply(MIN, _offset); + if (zoom > MAX) return apply(5, _offset); - let {x, y} = data.value; - if (_offset) [x, y] = _offset; + let { x, y } = data.value; + if (_offset) [x, y] = _offset; - data.value = { - zoom, x, y - } + data.value = { + zoom, + x, + y, + }; } data.subscribe((data) => { - const el = element(); - if (!el) return; - el.style.transform = `scale(${data.zoom.toString()}) translate(${data.x}px, ${data.y}px)`; - }) + const el = element(); + if (!el) return; + el.style.transform = `scale(${data.zoom.toString()}) translate(${data.x}px, ${data.y}px)`; + }); canvas.addEventListener("wheel", (event: WheelEvent) => { - event.preventDefault(); + event.preventDefault(); - initialZoom = data.value.zoom; - initialX = data.value.x; - initialY = data.value.y; + initialZoom = data.value.zoom; + initialX = data.value.x; + initialY = data.value.y; - apply(data.value.zoom - event.deltaY * 0.005); + apply(data.value.zoom - event.deltaY * 0.005); }); canvas.addEventListener("scroll", (event: Event) => { - event.preventDefault(); + event.preventDefault(); }); canvas.addEventListener("mousedown", (event: MouseEvent) => { - const target = event.target as HTMLElement|undefined; - console.log(target); - if (!target || !target.classList.contains("allow-drag-move")) return; - event.preventDefault(); - initialZoom = data.value.zoom; - initialX = data.value.x; - initialY = data.value.y; - initialTouchX = event.clientX; - initialTouchY = event.clientY; - dragging = true; - }) + const target = event.target as HTMLElement | undefined; + console.log(target); + if (!target || !target.classList.contains("allow-drag-move")) return; + event.preventDefault(); + initialZoom = data.value.zoom; + initialX = data.value.x; + initialY = data.value.y; + initialTouchX = event.clientX; + initialTouchY = event.clientY; + dragging = true; + }); canvas.addEventListener("mouseup", () => { - dragging = false; - }) + dragging = false; + }); canvas.addEventListener("mousemove", (event: MouseEvent) => { - if (!dragging) return; - event.preventDefault(); - apply(data.value.zoom, [ - initialX + - (event.clientX - initialTouchX) / initialZoom, - initialY + - (event.clientY - initialTouchY) / initialZoom, - ]); - }) + if (!dragging) return; + event.preventDefault(); + apply(data.value.zoom, [ + initialX + (event.clientX - initialTouchX) / initialZoom, + initialY + (event.clientY - initialTouchY) / initialZoom, + ]); + }); canvas.addEventListener("touchstart", (event: TouchEvent) => { - (document.activeElement as HTMLElement)?.blur(); + (document.activeElement as HTMLElement)?.blur(); - const el = element(); - if (!el) return; - if (lastElement != undefined && lastElement != el) reset(); - lastElement = el; + const el = element(); + if (!el) return; + if (lastElement != undefined && lastElement != el) reset(); + lastElement = el; - initialZoom = data.value.zoom; - initialX = data.value.x; - initialY = data.value.y; + initialZoom = data.value.zoom; + initialX = data.value.x; + initialY = data.value.y; - if (event.touches.length != 2) { - pinching = false; - initialTouchX = event.touches[0].clientX; - initialTouchY = event.touches[0].clientY; - return; - } + if (event.touches.length != 2) { + pinching = false; + initialTouchX = event.touches[0].clientX; + initialTouchY = event.touches[0].clientY; + return; + } - pinching = true; - initialDistance = distance(event); - initialTouchX = midpoint(event, "x"); - initialTouchY = midpoint(event, "y"); + pinching = true; + initialDistance = distance(event); + initialTouchX = midpoint(event, "x"); + initialTouchY = midpoint(event, "y"); }); canvas.addEventListener("touchmove", (event: TouchEvent) => { - if (!pinching) { - apply(data.value.zoom, [ - initialX + - (event.touches[0].clientX - initialTouchX) / initialZoom, - initialY + - (event.touches[0].clientY - initialTouchY) / initialZoom, - ]); - return; - } - if (event.touches.length < 2) return; - event.preventDefault(); - const currentDistance = distance(event); - const midX = midpoint(event, "x"); - const midY = midpoint(event, "y"); - const ratio = currentDistance / initialDistance; - const difference = currentDistance - initialDistance; - apply(initialZoom * ratio, [ - initialX + (midX - difference - initialTouchX) / initialZoom / 2, - initialY + (midY - difference - initialTouchY) / initialZoom / 2, - ]); + if (!pinching) { + apply(data.value.zoom, [ + initialX + + (event.touches[0].clientX - initialTouchX) / initialZoom, + initialY + + (event.touches[0].clientY - initialTouchY) / initialZoom, + ]); + return; + } + if (event.touches.length < 2) return; + event.preventDefault(); + const currentDistance = distance(event); + const midX = midpoint(event, "x"); + const midY = midpoint(event, "y"); + const ratio = currentDistance / initialDistance; + const difference = currentDistance - initialDistance; + apply(initialZoom * ratio, [ + initialX + (midX - difference - initialTouchX) / initialZoom / 2, + initialY + (midY - difference - initialTouchY) / initialZoom / 2, + ]); }); } @@ -424,12 +443,12 @@ export function collectObjectValuesForKey( const values: Set = new Set(); for (const object of objects) { - const stringEntryObject: StringEntryObject = converter(object); - const stringEntryObjectValue: Stringifiable | undefined = - stringEntryObject[key]; - if (stringEntryObjectValue == undefined) continue; + const stringEntryObject: StringEntryObject = converter(object); + const stringEntryObjectValue: Stringifiable | undefined = + stringEntryObject[key]; + if (stringEntryObjectValue == undefined) continue; - values.add(stringEntryObjectValue.toString()); + values.add(stringEntryObjectValue.toString()); } return [...values.values()]; @@ -442,50 +461,50 @@ export function checkDoesObjectMatchReference( explicitEmptyValue: boolean = false, ): boolean { reference_entry_loop: for (const referenceEntry of Object.entries( - reference, + reference, )) { - const [referenceKey, referenceValue] = referenceEntry; - const stringEntryObjectValue: Stringifiable | undefined = - stringEntryObject[referenceKey]; + const [referenceKey, referenceValue] = referenceEntry; + const stringEntryObjectValue: Stringifiable | undefined = + stringEntryObject[referenceKey]; - if (referenceValue == undefined) return false; + if (referenceValue == undefined) return false; - if (referenceValue[0] == "-") { - const strippedReferenceValue: string = referenceValue - .toString() - .substring(1); - // property may not exist - if ( - strippedReferenceValue == "" && - stringEntryObjectValue != undefined && - stringEntryObjectValue != "" - ) { - return false; - } + if (referenceValue[0] == "-") { + const strippedReferenceValue: string = referenceValue + .toString() + .substring(1); + // property may not exist + if ( + strippedReferenceValue == "" && + stringEntryObjectValue != undefined && + stringEntryObjectValue != "" + ) { + return false; + } - // property may not match - if (stringEntryObjectValue == strippedReferenceValue) { - return false; - } - } else { - if (explicitEmptyValue == false) { - // property must exist but be anything - if ( - referenceValue == "" && - (stringEntryObjectValue == undefined || - stringEntryObjectValue == "") - ) { - return false; - } else if (referenceValue == "") { - continue reference_entry_loop; - } - } + // property may not match + if (stringEntryObjectValue == strippedReferenceValue) { + return false; + } + } else { + if (explicitEmptyValue == false) { + // property must exist but be anything + if ( + referenceValue == "" && + (stringEntryObjectValue == undefined || + stringEntryObjectValue == "") + ) { + return false; + } else if (referenceValue == "") { + continue reference_entry_loop; + } + } - // property must match - if (stringEntryObjectValue != referenceValue) { - return false; - } - } + // property must match + if (stringEntryObjectValue != referenceValue) { + return false; + } + } } return true; } diff --git a/src/View/ChatPages/boardPage.tsx b/src/View/ChatPages/boardPage.tsx index daa7f4a6..7e791f9f 100644 --- a/src/View/ChatPages/boardPage.tsx +++ b/src/View/ChatPages/boardPage.tsx @@ -46,7 +46,10 @@ export function BoardPage( ); const wrapper = ( -
+
); Utility.implementPinchZoom(wrapper, boardViewModel.pinchToZoomData); diff --git a/src/View/ChatPages/messagePage.css b/src/View/ChatPages/messagePage.css index 519e878a..63f23eec 100644 --- a/src/View/ChatPages/messagePage.css +++ b/src/View/ChatPages/messagePage.css @@ -36,11 +36,11 @@ width: 100%; padding-left: var(--content-padding); gap: var(--gap-in-controls); - + display: flex; align-items: center; justify-content: space-between; - + background: var(--surface); } @@ -285,7 +285,8 @@ padding: var(--gap-between-tiles); } -#message-page[reply-view] :is(.reply-link, .inline-reply, #composer .reply-preview-wrapper) { +#message-page[reply-view] + :is(.reply-link, .inline-reply, #composer .reply-preview-wrapper) { display: none; } diff --git a/src/View/ChatPages/messagePage.tsx b/src/View/ChatPages/messagePage.tsx index bba6c7ab..77b9d090 100644 --- a/src/View/ChatPages/messagePage.tsx +++ b/src/View/ChatPages/messagePage.tsx @@ -15,156 +15,177 @@ export function MessagePage( messagePageViewModel.loadData(); const ChatMessageViewModelToView: React.StateItemConverter< - ChatMessageViewModel -> = (chatMessageViewModel: ChatMessageViewModel) => { - return ChatMessage(coreViewModel, chatMessageViewModel); -}; + ChatMessageViewModel + > = (chatMessageViewModel: ChatMessageViewModel) => { + return ChatMessage(coreViewModel, chatMessageViewModel); + }; -const messageContainer = ( -
-); + const messageContainer = ( +
+ ); -const persistenceId = messagePageViewModel.chatViewModel.chatModel.id; -const replyPreview = ViewController.inlineReplies.setState( - persistenceId, - () => - React.createProxyState( - [messagePageViewModel.replyingMessage], - () => { - if (messagePageViewModel.replyingMessage.value == undefined) - return
; - return ReplyPreview( - coreViewModel, - messagePageViewModel.replyingMessage.value, - ); - }, - ), -); + const persistenceId = messagePageViewModel.chatViewModel.chatModel.id; + const replyPreview = ViewController.inlineReplies.setState( + persistenceId, + () => + React.createProxyState( + [messagePageViewModel.replyingMessage], + () => { + if (messagePageViewModel.replyingMessage.value == undefined) + return
; + return ReplyPreview( + coreViewModel, + messagePageViewModel.replyingMessage.value, + ); + }, + ), + ); -function scrollDown(hard: boolean = false) { - if (hard) { - messageContainer.setAttribute("scroll-hard", ""); + function scrollDown(hard: boolean = false) { + if (hard) { + messageContainer.setAttribute("scroll-hard", ""); + } + messageContainer.scrollTop = messageContainer.scrollHeight; + messageContainer.removeAttribute("scroll-hard"); } - messageContainer.scrollTop = messageContainer.scrollHeight; - messageContainer.removeAttribute("scroll-hard"); -} -function scrollDownIfApplicable() { - const scrollFromBottom = - messageContainer.scrollHeight - - (messageContainer.scrollTop + messageContainer.offsetHeight); - if (scrollFromBottom > 400) return; - - scrollDown(); -} -messagePageViewModel.filteredMessageViewModels.subscribeSilent( - scrollDownIfApplicable, -); -React.bulkSubscribe([messagePageViewModel.reactionFilter, messagePageViewModel.searchViewModel.appliedQuery], scrollDown) -messagePageViewModel.replyViewSelectedMessage.subscribeSilent(selectedMessage => { - if (selectedMessage != undefined) return; - setTimeout(scrollDown, 100); -}) -setTimeout(() => scrollDown(true), 100); - -messagePageViewModel.focusSetter.subscribeSilent(() => { - ViewController.setFocusWithDelay(); -}); - -const isInReplyView = React.createProxyState([messagePageViewModel.replyViewSelectedMessage], ()=>messagePageViewModel.replyViewSelectedMessage.value != undefined); - -const title = React.createProxyState([messagePageViewModel.isReplyViewActive], ()=>messagePageViewModel.isReplyViewActive.value ? coreViewModel.translations.chatPage.message.replyHeaderLabel((messagePageViewModel.replyViewSelectedMessage.value!).body.value) : coreViewModel.translations.chatPage.message.messagesHeadline); - -return ( -
-
-
-
- - - - - - -
-
- {messageContainer} -
-
-
-
- - -
-
-
-
-
-
- - {MessageFilterModal( - coreViewModel, - messagePageViewModel, - ChatMessageViewModelToView, - )} -
-); + function scrollDownIfApplicable() { + const scrollFromBottom = + messageContainer.scrollHeight - + (messageContainer.scrollTop + messageContainer.offsetHeight); + if (scrollFromBottom > 400) return; + + scrollDown(); + } + messagePageViewModel.filteredMessageViewModels.subscribeSilent( + scrollDownIfApplicable, + ); + React.bulkSubscribe( + [ + messagePageViewModel.reactionFilter, + messagePageViewModel.searchViewModel.appliedQuery, + ], + scrollDown, + ); + messagePageViewModel.replyViewSelectedMessage.subscribeSilent( + (selectedMessage) => { + if (selectedMessage != undefined) return; + setTimeout(scrollDown, 100); + }, + ); + setTimeout(() => scrollDown(true), 100); + + messagePageViewModel.focusSetter.subscribeSilent(() => { + ViewController.setFocusWithDelay(); + }); + + const isInReplyView = React.createProxyState( + [messagePageViewModel.replyViewSelectedMessage], + () => messagePageViewModel.replyViewSelectedMessage.value != undefined, + ); + + const title = React.createProxyState( + [messagePageViewModel.isReplyViewActive], + () => + messagePageViewModel.isReplyViewActive.value + ? coreViewModel.translations.chatPage.message.replyHeaderLabel( + messagePageViewModel.replyViewSelectedMessage.value!.body + .value, + ) + : coreViewModel.translations.chatPage.message.messagesHeadline, + ); + + return ( +
+
+
+
+ + + + + +
+
+ {messageContainer} +
+
+
+
+ + +
+
+
+
+
+
+ + {MessageFilterModal( + coreViewModel, + messagePageViewModel, + ChatMessageViewModelToView, + )} +
+ ); } diff --git a/src/View/ChatPages/settingsPage.tsx b/src/View/ChatPages/settingsPage.tsx index f378ef88..c60bf5b5 100644 --- a/src/View/ChatPages/settingsPage.tsx +++ b/src/View/ChatPages/settingsPage.tsx @@ -47,12 +47,8 @@ export function SettingsPage( } @@ -63,9 +59,7 @@ export function SettingsPage( coreViewModel.translations.chatPage.settings .setNameButtonAudioLabel } - on:click={ - settingsPageViewModel.setName - } + on:click={settingsPageViewModel.setName} toggle:disabled={ settingsPageViewModel.cannotSetPrimaryChannel } @@ -177,7 +171,7 @@ export function SettingsPage(
- {ColorPicker(settingsPageViewModel.color)} + {ColorPicker(settingsPageViewModel.color)}
-
diff --git a/src/View/ChatPages/taskPage.tsx b/src/View/ChatPages/taskPage.tsx index 7dbcbc41..b5eec35e 100644 --- a/src/View/ChatPages/taskPage.tsx +++ b/src/View/ChatPages/taskPage.tsx @@ -2,11 +2,11 @@ import "./taskPage.css"; import { BoardPage } from "./boardPage"; import { ViewController } from "../viewController"; import { PlaceholderView } from "../Components/placeholderView"; +import { NewItemEntry } from "../Components/newItemEntry"; import { BoardViewModelToEntry } from "../Components/boardEntry"; import * as React from "../../react"; import TaskPageViewModel from "../../ViewModel/Pages/taskPageViewModel"; import CoreViewModel from "../../ViewModel/Global/coreViewModel"; -import {NewItemEntry} from "../Components/newItemEntry"; export function TaskPage( coreViewModel: CoreViewModel, @@ -66,13 +66,18 @@ export function TaskPage( bind:value={taskPageViewModel.boardQuery} on:enter={taskPageViewModel.createBoard} placeholder={ - coreViewModel.translations.general.filterOrCreateLabel + coreViewModel.translations.general + .filterOrCreateLabel } >
-
- {NewItemEntry(coreViewModel, taskPageViewModel.boardQuery, taskPageViewModel.createBoard)} +
+ {NewItemEntry( + coreViewModel, + taskPageViewModel.boardQuery, + taskPageViewModel.createBoard, + )}

); diff --git a/src/View/Components/chatMessage.tsx b/src/View/Components/chatMessage.tsx index 416db768..9e0e60d4 100644 --- a/src/View/Components/chatMessage.tsx +++ b/src/View/Components/chatMessage.tsx @@ -1,3 +1,4 @@ +import { ReplyLink } from "./replyLink"; import { MessageReactionButtonRow } from "./messageReactionButtonRow"; import { InlineReply } from "./inlineReply"; import { ChatMessageInfoModal } from "../Modals/chatMessageInfoModal"; @@ -5,7 +6,6 @@ import * as React from "../../react"; import CoreViewModel from "../../ViewModel/Global/coreViewModel"; import ChatMessageViewModel from "../../ViewModel/Chat/chatMessageViewModel"; import { ChatMessageStatuses } from "../../Model/Chat/chatModel"; -import {ReplyLink} from "./replyLink"; export function ChatMessage( coreViewModel: CoreViewModel, @@ -69,8 +69,11 @@ export function ChatMessage( aria-label={ coreViewModel.translations.chatPage.message .replyToMessageButton - } - toggle:hidden={chatMessageViewModel.messagePageViewModel.isReplyViewActive} + } + toggle:hidden={ + chatMessageViewModel.messagePageViewModel + .isReplyViewActive + } > reply diff --git a/src/View/Components/newItemEntry.tsx b/src/View/Components/newItemEntry.tsx index e97ddf59..fa1c97b9 100644 --- a/src/View/Components/newItemEntry.tsx +++ b/src/View/Components/newItemEntry.tsx @@ -1,16 +1,24 @@ import * as React from "../../react"; import CoreViewModel from "../../ViewModel/Global/coreViewModel"; -export function NewItemEntry(coreViewModel: CoreViewModel, query: React.State, fn: ()=>void) { - const isHidden = React.createProxyState([query],()=>query.value == ""); - const label = React.createProxyState([query],()=>coreViewModel.translations.general.createLabel(query.value)); +export function NewItemEntry( + coreViewModel: CoreViewModel, + query: React.State, + fn: () => void, +) { + const isHidden = React.createProxyState([query], () => query.value == ""); + const label = React.createProxyState([query], () => + coreViewModel.translations.general.createLabel(query.value), + ); - return + return ( + + ); } diff --git a/src/View/Components/replyLink.tsx b/src/View/Components/replyLink.tsx index 3dc1c8e0..15955ef0 100644 --- a/src/View/Components/replyLink.tsx +++ b/src/View/Components/replyLink.tsx @@ -1,22 +1,31 @@ import * as React from "../../react"; -import ChatMessageViewModel from "../../ViewModel/Chat/chatMessageViewModel"; import CoreViewModel from "../../ViewModel/Global/coreViewModel"; +import ChatMessageViewModel from "../../ViewModel/Chat/chatMessageViewModel"; -export function ReplyLink(coreViewModel: CoreViewModel, chatMessageViewModel: ChatMessageViewModel) { - const isHidden = React.createProxyState([chatMessageViewModel.replyCount], ()=>chatMessageViewModel.replyCount.value == 0); +export function ReplyLink( + coreViewModel: CoreViewModel, + chatMessageViewModel: ChatMessageViewModel, +) { + const isHidden = React.createProxyState( + [chatMessageViewModel.replyCount], + () => chatMessageViewModel.replyCount.value == 0, + ); function select() { - chatMessageViewModel.messagePageViewModel.setReplyView(chatMessageViewModel); + chatMessageViewModel.messagePageViewModel.setReplyView( + chatMessageViewModel, + ); } return ( - + +
+
+

+ { + coreViewModel.translations.general + .searchSuggestionsLabel + } +

+
+ SuggestionView( + suggestion, + searchViewModel, + coreViewModel, + ), + ]} + >
+
+ + +
+
); } @@ -108,26 +108,29 @@ function SuggestionView( coreViewModel: CoreViewModel, ) { const isApplied = React.createProxyState( - [searchViewModel.appliedQuery], - () => searchViewModel.appliedQuery.value == suggestion, + [searchViewModel.appliedQuery], + () => searchViewModel.appliedQuery.value == suggestion, ); function deleteSuggestion() { - searchViewModel.deleteSuggestion(suggestion); + searchViewModel.deleteSuggestion(suggestion); } function applySuggestion() { - searchViewModel.search(suggestion); + searchViewModel.search(suggestion); } - return DeletableListItem(coreViewModel, suggestion, - - , deleteSuggestion) + return DeletableListItem( + coreViewModel, + suggestion, + , + deleteSuggestion, + ); } diff --git a/src/View/Modals/settingsModal.tsx b/src/View/Modals/settingsModal.tsx index 5b57e49c..72e7f84b 100644 --- a/src/View/Modals/settingsModal.tsx +++ b/src/View/Modals/settingsModal.tsx @@ -125,25 +125,20 @@ function SettingsInfoPane( settingsViewModel.coreViewModel.version, )} - + - -
- + + + ); } @@ -152,30 +147,30 @@ function SettingsRegionalPane( settingsViewModel: SettingsViewModel, ) { return ( -
-

{coreViewModel.translations.settings.pages.regional}

+
+

{coreViewModel.translations.settings.pages.regional}

-
-

{coreViewModel.translations.settings.language}

- {OptionButtonList( - new React.ListState<[string, string]>( - Object.values(Languages).map((x) => [languageNames[x], x]), - ), - settingsViewModel.language, - )} +
+

{coreViewModel.translations.settings.language}

+ {OptionButtonList( + new React.ListState<[string, string]>( + Object.values(Languages).map((x) => [languageNames[x], x]), + ), + settingsViewModel.language, + )} -
-

{coreViewModel.translations.settings.firstDayOfWeekLabel}

- {OptionButtonList( - new React.ListState<[string, string]>( - coreViewModel.translations.regional.weekdays.full.map( - (x, i) => [x, i.toString()], - ), - ), - settingsViewModel.firstDayOfWeek, - )} -
-); +
+

{coreViewModel.translations.settings.firstDayOfWeekLabel}

+ {OptionButtonList( + new React.ListState<[string, string]>( + coreViewModel.translations.regional.weekdays.full.map( + (x, i) => [x, i.toString()], + ), + ), + settingsViewModel.firstDayOfWeek, + )} +
+ ); } function SettingsAppearancePane( @@ -183,34 +178,34 @@ function SettingsAppearancePane( settingsViewModel: SettingsViewModel, ) { return ( -
-

{coreViewModel.translations.settings.pages.appearance}

-
- {OptionButtonList( - new React.ListState<[string, string]>([ - [ - coreViewModel.translations.settings.themes.dynamic, - ThemeSettings.Dynamic, - ], - [ - coreViewModel.translations.settings.themes.system, - ThemeSettings.System, - ], - [ - coreViewModel.translations.settings.themes.dark, - ThemeSettings.Dark, - ], - [ - coreViewModel.translations.settings.themes.light, - ThemeSettings.Light, - ], - [ - coreViewModel.translations.settings.themes.black, - ThemeSettings.Black, - ], - ]), - settingsViewModel.theme, - )} -
-); +
+

{coreViewModel.translations.settings.pages.appearance}

+
+ {OptionButtonList( + new React.ListState<[string, string]>([ + [ + coreViewModel.translations.settings.themes.dynamic, + ThemeSettings.Dynamic, + ], + [ + coreViewModel.translations.settings.themes.system, + ThemeSettings.System, + ], + [ + coreViewModel.translations.settings.themes.dark, + ThemeSettings.Dark, + ], + [ + coreViewModel.translations.settings.themes.light, + ThemeSettings.Light, + ], + [ + coreViewModel.translations.settings.themes.black, + ThemeSettings.Black, + ], + ]), + settingsViewModel.theme, + )} +
+ ); } diff --git a/src/View/Modals/storageModal.tsx b/src/View/Modals/storageModal.tsx index 6ce5cfaa..94480601 100644 --- a/src/View/Modals/storageModal.tsx +++ b/src/View/Modals/storageModal.tsx @@ -1,94 +1,105 @@ import { SplitModal } from "./splitModal"; +import { UsageBar } from "../Components/usageBar"; import { DirectoryItemList } from "../Components/directoryItemList"; import { DangerousActionButton } from "../Components/dangerousActionButton"; import * as React from "../../react"; import StorageViewModel from "../../ViewModel/Global/storageViewModel"; import CoreViewModel from "../../ViewModel/Global/coreViewModel"; import { PATH_COMPONENT_SEPARATOR } from "../../Model/Global/storageModel"; -import {UsageBar} from "../Components/usageBar"; export function StorageModal( coreViewModel: CoreViewModel, storageViewModel: StorageViewModel, ) { - const usageValueLabel = React.createProxyState([storageViewModel.occupiedSpaceMB, storageViewModel.maximumSpaceMB], ()=> - coreViewModel.translations.storage.usageVauleLabel(storageViewModel.occupiedSpaceMB.value, storageViewModel.maximumSpaceMB.value)); + const usageValueLabel = React.createProxyState( + [storageViewModel.occupiedSpaceMB, storageViewModel.maximumSpaceMB], + () => + coreViewModel.translations.storage.usageVauleLabel( + storageViewModel.occupiedSpaceMB.value, + storageViewModel.maximumSpaceMB.value, + ), + ); const detailView = React.createProxyState( - [storageViewModel.selectedPath], - () => { - if (storageViewModel.selectedPath.value == PATH_COMPONENT_SEPARATOR) - return ( -
- - {coreViewModel.translations.storage.noItemSelected} - + [storageViewModel.selectedPath], + () => { + if (storageViewModel.selectedPath.value == PATH_COMPONENT_SEPARATOR) + return ( +
+ + {coreViewModel.translations.storage.noItemSelected} + -
+
- {UsageBar(coreViewModel.translations.storage.usageLabel, usageValueLabel, storageViewModel.occupiedSpaceMB, storageViewModel.maximumSpaceMB)} + {UsageBar( + coreViewModel.translations.storage.usageLabel, + usageValueLabel, + storageViewModel.occupiedSpaceMB, + storageViewModel.maximumSpaceMB, + )} -
+
- {DangerousActionButton( - coreViewModel, - coreViewModel.translations.storage.removeJunkButton, - "delete_forever", - storageViewModel.removeJunk, - )} -
- ); + {DangerousActionButton( + coreViewModel, + coreViewModel.translations.storage.removeJunkButton, + "delete_forever", + storageViewModel.removeJunk, + )} +
+ ); - return ( -
-
-
- {coreViewModel.translations.storage.path} - -
-
-
-
- {coreViewModel.translations.storage.content} - -
-
+ return ( +
+
+
+ {coreViewModel.translations.storage.path} + +
+
+
+
+ {coreViewModel.translations.storage.content} + +
+
- {DangerousActionButton( - coreViewModel, - coreViewModel.translations.storage.deleteItem, - "delete_forever", - storageViewModel.deleteSelectedItem, - )} -
- ); - }, + {DangerousActionButton( + coreViewModel, + coreViewModel.translations.storage.deleteItem, + "delete_forever", + storageViewModel.deleteSelectedItem, + )} +
+ ); + }, ); return ( - + ); } diff --git a/src/View/homePage.tsx b/src/View/homePage.tsx index cc53962a..0d08e24c 100644 --- a/src/View/homePage.tsx +++ b/src/View/homePage.tsx @@ -20,195 +20,193 @@ export function HomePage( ) { // sections const overviewSection = ( -
-

{coreViewModel.translations.homePage.overviewHeadline}

+
+

{coreViewModel.translations.homePage.overviewHeadline}

- + -
- - - -
+
+ + + +
-
+
- -
- -
+ +
+ +
-
+
- {HomePageButton( - settingsViewModel.showSettingsModal, - coreViewModel.translations.homePage.settingsButton, - "settings", - )} - {HomePageButton( - fileTransferViewModel.showDirectionSelectionModal, - coreViewModel.translations.homePage.transferDataButton, - "sync_alt", - )} - {HomePageButton( - storageViewModel.showStorageModal, - coreViewModel.translations.homePage.manageStorageButton, - "hard_drive", - )} + {HomePageButton( + settingsViewModel.showSettingsModal, + coreViewModel.translations.homePage.settingsButton, + "settings", + )} + {HomePageButton( + fileTransferViewModel.showDirectionSelectionModal, + coreViewModel.translations.homePage.transferDataButton, + "sync_alt", + )} + {HomePageButton( + storageViewModel.showStorageModal, + coreViewModel.translations.homePage.manageStorageButton, + "hard_drive", + )} - + -
-
+
+
-
- -
-
-
-); +
+ +
+
+
+ ); -const chatSection = ( -
-

{coreViewModel.translations.homePage.chatsHeadline}

+ const chatSection = ( +
+

{coreViewModel.translations.homePage.chatsHeadline}

-
- - -
+
+ + +
-
-
-); +
+
+ ); -// methods -function scrollToChat() { - chatSection.scrollIntoView(); -} + // methods + function scrollToChat() { + chatSection.scrollIntoView(); + } -// final -return ( -
-
- {overviewSection} - {chatSection} -
-
+ // final + return ( +
+
+ {overviewSection} + {chatSection} +
+
); } diff --git a/src/View/translations.ts b/src/View/translations.ts index fd6f579f..ce8b145f 100644 --- a/src/View/translations.ts +++ b/src/View/translations.ts @@ -1,346 +1,346 @@ const englishTranslations = { updater: { - migrated: "Migrated", + migrated: "Migrated", }, general: { - deleteItemButtonAudioLabel: "delete item", - searchButtonAudioLabel: "search", - searchButtonClearAudioLabel: "clear search query", + deleteItemButtonAudioLabel: "delete item", + searchButtonAudioLabel: "search", + searchButtonClearAudioLabel: "clear search query", - abortButton: "Abort", - applyButton: "Apply", - backButton: "Back", - cancelButton: "Cancel", - confirmButton: "Confirm", - continueButton: "Continue", - closeButton: "Close", - deleteButton: "Delete", - exitButton: "Exit", - fullscreenButton: "Fullscreen", - refreshButton: "Refresh", - saveButton: "Save", - setButton: "Set", + abortButton: "Abort", + applyButton: "Apply", + backButton: "Back", + cancelButton: "Cancel", + confirmButton: "Confirm", + continueButton: "Continue", + closeButton: "Close", + deleteButton: "Delete", + exitButton: "Exit", + fullscreenButton: "Fullscreen", + refreshButton: "Refresh", + saveButton: "Save", + setButton: "Set", - filterOrCreateLabel: "Search or create", - createLabel: (query: string) => `Create "${query}"`, + filterOrCreateLabel: "Search or create", + createLabel: (query: string) => `Create "${query}"`, - reloadAppButton: "Reload App", + reloadAppButton: "Reload App", - fileVersionLabel: "Version", - searchLabel: "Search", - searchSuggestionsLabel: "Recent searches", - waitingLabel: "Waiting...", + fileVersionLabel: "Version", + searchLabel: "Search", + searchSuggestionsLabel: "Recent searches", + waitingLabel: "Waiting...", - restoreConnection: "Restore connection", + restoreConnection: "Restore connection", - noPageSelected: "No page selected", + noPageSelected: "No page selected", }, regional: { - weekdays: { - full: [ - "Sunday", - "Monday", - "Tuesday", - "Wednesday", - "Thursday", - "Friday", - "Saturday", - ], - abbreviated: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"], - }, + weekdays: { + full: [ + "Sunday", + "Monday", + "Tuesday", + "Wednesday", + "Thursday", + "Friday", + "Saturday", + ], + abbreviated: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"], + }, }, homePage: { - appName: "Coordination Tool", + appName: "Coordination Tool", - /// + /// - overviewHeadline: "Overview", + overviewHeadline: "Overview", - serverAddress: "Server address", - serverAddressPlaceholder: "wss://192.168.0.69:3000", - connectAudioLabel: "connect to server", - disconnectAudioLabel: "disconnect from server", - manageConnectionsAudioLabel: "manage connections", + serverAddress: "Server address", + serverAddressPlaceholder: "wss://192.168.0.69:3000", + connectAudioLabel: "connect to server", + disconnectAudioLabel: "disconnect from server", + manageConnectionsAudioLabel: "manage connections", - yourNameLabel: "Your name", - yourNamePlaceholder: "Jane Doe", - setNameButtonAudioLabel: "set name", + yourNameLabel: "Your name", + yourNamePlaceholder: "Jane Doe", + setNameButtonAudioLabel: "set name", - settingsButton: "Settings", - manageStorageButton: "Manage storage", - transferDataButton: "Transfer or export data", + settingsButton: "Settings", + manageStorageButton: "Manage storage", + transferDataButton: "Transfer or export data", - updateButton: (version: string) => `Update to ${version}`, + updateButton: (version: string) => `Update to ${version}`, - scrollToChatButton: "Chats", + scrollToChatButton: "Chats", - /// + /// - backToOverviewAudioLabel: "go back to overview", - chatsHeadline: "Chats", + backToOverviewAudioLabel: "go back to overview", + chatsHeadline: "Chats", - addChatAudioLabel: "name of new chat", - addChatPlaceholder: "Add chat", - addChatButton: "Add chat", + addChatAudioLabel: "name of new chat", + addChatPlaceholder: "Add chat", + addChatButton: "Add chat", }, settings: { - pages: { - appearance: "Appearance", - regional: "Language & Region", - info: "About CT", - }, - themes: { - dynamic: "Dynamic", - dark: "Dark", - light: "Light", - system: "Device theme", - black: "Black", - }, + pages: { + appearance: "Appearance", + regional: "Language & Region", + info: "About CT", + }, + themes: { + dynamic: "Dynamic", + dark: "Dark", + light: "Light", + system: "Device theme", + black: "Black", + }, - version: "Version", - language: "Language", + version: "Version", + language: "Language", - firstDayOfWeekLabel: "First day of week", + firstDayOfWeekLabel: "First day of week", - checkUpdatesButton: "Check for updates", + checkUpdatesButton: "Check for updates", }, connectionModal: { - connectionModalHeadline: "Manage Connections", + connectionModalHeadline: "Manage Connections", - /// + /// - connectButtonAudioLabel: "connect", + connectButtonAudioLabel: "connect", }, dataTransferModal: { - transferDataHeadline: "Data Transfer", - sendHeadline: "Transfer to other device", - receiveHeadline: "Transfer to This Device", - exportHeadline: "Export Data", - importHeadline: "Import Data", - selectionDescription: "Select the data that you want to transfer.", - exportSelectionDescription: "Select the data that you want to export.", - dataEntryDescription: "Enter this data on the other device.", - dataEntryInputDescription: - "Enter the data displayed on the other device.", + transferDataHeadline: "Data Transfer", + sendHeadline: "Transfer to other device", + receiveHeadline: "Transfer to This Device", + exportHeadline: "Export Data", + importHeadline: "Import Data", + selectionDescription: "Select the data that you want to transfer.", + exportSelectionDescription: "Select the data that you want to export.", + dataEntryDescription: "Enter this data on the other device.", + dataEntryInputDescription: + "Enter the data displayed on the other device.", - /// + /// - fromThisDeviceButton: "Send to other device", - toThisDeviceButton: "Send to this device", - exportButton: "Export to file", - importButton: "Import from file", + fromThisDeviceButton: "Send to other device", + toThisDeviceButton: "Send to this device", + exportButton: "Export to file", + importButton: "Import from file", - /// + /// - generalHeadline: "General", + generalHeadline: "General", - connectionData: "Connection Data", - settingsData: "Settings Data", + connectionData: "Connection Data", + settingsData: "Settings Data", - chatsHeadline: "Chats", + chatsHeadline: "Chats", - /// + /// - transferChannelHeadline: "Transfer Chanel", - transferKeyHeadline: "Transfer Encryption Key", + transferChannelHeadline: "Transfer Chanel", + transferKeyHeadline: "Transfer Encryption Key", - sendButton: "Send", - sendAgainButton: "Send again", + sendButton: "Send", + sendAgainButton: "Send again", - /// + /// - filesSentCount: (count: number) => `Files sent: ${count}.`, - allFilesSent: "Done.", + filesSentCount: (count: number) => `Files sent: ${count}.`, + allFilesSent: "Done.", - filesReceivedCount: (count: number) => `Files processed: ${count}.`, + filesReceivedCount: (count: number) => `Files processed: ${count}.`, - // + // - exportKey: "Encryption key", - exportKeyConfirmation: "Confirm", - downloadFileButton: "Download", - importFileButton: "Import", - decryptImportButton: "Decrypt", - incorrectPassphraseError: "The encryption key is incorrect", + exportKey: "Encryption key", + exportKeyConfirmation: "Confirm", + downloadFileButton: "Download", + importFileButton: "Import", + decryptImportButton: "Decrypt", + incorrectPassphraseError: "The encryption key is incorrect", }, storage: { - noItemSelected: "No item selected", - notAFile: "(not a file)", - contentEmpty: "(empty)", + noItemSelected: "No item selected", + notAFile: "(not a file)", + contentEmpty: "(empty)", - usageLabel: "Usage", - usageVauleLabel: (used: number, max: number) => `${used} of ${max} MB`, + usageLabel: "Usage", + usageVauleLabel: (used: number, max: number) => `${used} of ${max} MB`, - path: "Path", - content: "Content", + path: "Path", + content: "Content", - deleteItem: "Delete item", + deleteItem: "Delete item", - removeJunkButton: "Delete junk files", + removeJunkButton: "Delete junk files", }, chatPage: { - closeChatAudioLabe: "close chat", - chatSettingsAudioLabel: "chat settings", + closeChatAudioLabe: "close chat", + chatSettingsAudioLabel: "chat settings", - pages: { - settings: "Settings", - messages: "Messages", - tasks: "Tasks", - calendar: "Calendar", - }, + pages: { + settings: "Settings", + messages: "Messages", + tasks: "Tasks", + calendar: "Calendar", + }, - settings: { - settingsHeadline: "Settings", + settings: { + settingsHeadline: "Settings", - nameLabel: "Chat name", - setNameButtonAudioLabel: "set name", + nameLabel: "Chat name", + setNameButtonAudioLabel: "set name", - newSecondaryChannelPlaceholder: "Add secondary channel", - newSecondaryChannelAudioLabel: "name of new secondary channel", - addSecondaryChannelButtonAudioLabel: "add secondary channel", + newSecondaryChannelPlaceholder: "Add secondary channel", + newSecondaryChannelAudioLabel: "name of new secondary channel", + addSecondaryChannelButtonAudioLabel: "add secondary channel", - encryptionKeyLabel: "Encryption key", - setEncryptionKeyButtonAudioLabel: "set encryption key", - showEncryptionKey: "Show encryption key", + encryptionKeyLabel: "Encryption key", + setEncryptionKeyButtonAudioLabel: "set encryption key", + showEncryptionKey: "Show encryption key", - setColorButtonAudioLabel: "set color", + setColorButtonAudioLabel: "set color", - deleteChatButton: "Delete entire chat", - }, + deleteChatButton: "Delete entire chat", + }, - message: { - messagesHeadline: "Messages", + message: { + messagesHeadline: "Messages", - messageFilterHeadline: "Filter messages", - messageFilterReactionsHadline: "Reactions", - messageFilterAllReactionsButton: "Show all", + messageFilterHeadline: "Filter messages", + messageFilterReactionsHadline: "Reactions", + messageFilterAllReactionsButton: "Show all", - /// + /// - composerInputPlaceholder: "Type a message...", - sendMessageButtonAudioLabel: "send message", - filterMessagesButtonAudioLabel: "filter messages", + composerInputPlaceholder: "Type a message...", + sendMessageButtonAudioLabel: "send message", + filterMessagesButtonAudioLabel: "filter messages", - /// + /// - showMessageInfoButtonAudioLabel: "show message info", - messageInfoHeadline: "Message Info", - cancelReplyAudioLabel: "cancel reply", + showMessageInfoButtonAudioLabel: "show message info", + messageInfoHeadline: "Message Info", + cancelReplyAudioLabel: "cancel reply", - sentBy: "Sent by", - timeSent: "Time sent", - channel: "Channel", - messageContent: "Message content", + sentBy: "Sent by", + timeSent: "Time sent", + channel: "Channel", + messageContent: "Message content", - copyMessageButton: "Copy message", - resendMessageButton: "Resend message", - decryptMessageButton: "Decrypt message", - replyToMessageButton: "Reply to message", - deleteMessageButton: "Delete message", + copyMessageButton: "Copy message", + resendMessageButton: "Resend message", + decryptMessageButton: "Decrypt message", + replyToMessageButton: "Reply to message", + deleteMessageButton: "Delete message", - // + // - thumbsUpReaction: "Reaction: thumbs up", - checkReaction: "Reaction: check", - stopReaction: "Reaction: stop sign", - attentionReaction: "Reaction: exclamation mark", - doubleAttentionReaction: "Reaction: double exclamation mark", - questionReaction: "Reaction: question mark", + thumbsUpReaction: "Reaction: thumbs up", + checkReaction: "Reaction: check", + stopReaction: "Reaction: stop sign", + attentionReaction: "Reaction: exclamation mark", + doubleAttentionReaction: "Reaction: double exclamation mark", + questionReaction: "Reaction: question mark", - // + // - replyPrefixLabel: "Replies: ", - replyHeaderLabel: (message: string) => `Replies to "${message}"`, - }, + replyPrefixLabel: "Replies: ", + replyHeaderLabel: (message: string) => `Replies to "${message}"`, + }, - task: { - noBoardSelected: "No board selected", - boardNotFound: "Board not found", + task: { + noBoardSelected: "No board selected", + boardNotFound: "Board not found", - /// + /// - closeBoardButtonAudioLabel: "close board", - toggleBoardButtonAudioLabel: "toggle board list", - showBoardSettingsButtonAudioLabel: "show board settigns", + closeBoardButtonAudioLabel: "close board", + toggleBoardButtonAudioLabel: "toggle board list", + showBoardSettingsButtonAudioLabel: "show board settigns", - listViewButtonAudioLabel: "list view", - kanbanViewButtonAudioLabel: "kanban view", - statusViewButtonAudioLabel: "status grid view", + listViewButtonAudioLabel: "list view", + kanbanViewButtonAudioLabel: "kanban view", + statusViewButtonAudioLabel: "status grid view", - filterTasksButtonAudioLabel: "filter tasks", - createTaskButtonAudioLabel: "create new task", + filterTasksButtonAudioLabel: "filter tasks", + createTaskButtonAudioLabel: "create new task", - /// + /// - boardSettingsHeadline: "Board Settings", - boardNameInputLabel: "Board name", - deleteBoardButton: "Delete board and all tasks", + boardSettingsHeadline: "Board Settings", + boardNameInputLabel: "Board name", + deleteBoardButton: "Delete board and all tasks", - /// + /// - taskSettingsHeadline: "Edit Task", + taskSettingsHeadline: "Edit Task", - taskNameLabel: "Title", - taskBoardLabel: "Board", + taskNameLabel: "Title", + taskBoardLabel: "Board", - taskCategoryLabel: "Category", - taskStatusLabel: "Status", - taskPriorityLabel: "Priority", + taskCategoryLabel: "Category", + taskStatusLabel: "Status", + taskPriorityLabel: "Priority", - taskDescriptionLabel: "Description", + taskDescriptionLabel: "Description", - taskDateLabel: "Date", - taskTimeLabel: "Time", + taskDateLabel: "Date", + taskTimeLabel: "Time", - deleteTaskButton: "Delete task", + deleteTaskButton: "Delete task", - /// + /// - filterTasksHeadline: "Filter Tasks", + filterTasksHeadline: "Filter Tasks", - /// + /// - renameCategoryInputPlaceholder: "Rename category", - renameStatusInputPlaceholder: "Rename status", - }, + renameCategoryInputPlaceholder: "Rename category", + renameStatusInputPlaceholder: "Rename status", + }, - calendar: { - eventsBoard: "Events", + calendar: { + eventsBoard: "Events", - /// + /// - todayButtonAudioLabel: "go to today", + todayButtonAudioLabel: "go to today", - previousMonthButtonAudioLabel: "previous month", - nextMonthButtonAudioLabel: "next month", + previousMonthButtonAudioLabel: "previous month", + nextMonthButtonAudioLabel: "next month", - yearInputAudioLabel: "year", - monthInputAudioLabel: "month", + yearInputAudioLabel: "year", + monthInputAudioLabel: "month", - yearInputPlaceholder: "2000", - monthInputPlaceholder: "01", + yearInputPlaceholder: "2000", + monthInputPlaceholder: "01", - /// + /// - searchEventsHeadline: "Search Events", + searchEventsHeadline: "Search Events", - /// + /// - events: "Events", - noEvents: "No events", + events: "Events", + noEvents: "No events", - // + // - eventNext: "Up next", - }, + eventNext: "Up next", + }, }, }; @@ -350,631 +350,635 @@ export const allTranslations: { en: englishTranslations, de: { - updater: { - migrated: "Migriert", - }, - - general: { - deleteItemButtonAudioLabel: "element löschen", - searchButtonAudioLabel: "suchen", - searchButtonClearAudioLabel: "suche zurücksetzen", - - abortButton: "Abbrechen", - applyButton: "Anwenden", - backButton: "Zurück", - cancelButton: "Abbrechen", - continueButton: "Weiter", - confirmButton: "Bestätigen", - closeButton: "Schließen", - deleteButton: "Löschen", - exitButton: "Schließen", - fullscreenButton: "Vollbild", - refreshButton: "Aktualisieren", - saveButton: "Speichern", - setButton: "OK", - - filterOrCreateLabel: "Suchen oder erstellen", - createLabel: (query: string) => `"${query}" erstellen`, - - reloadAppButton: "Neu laden", - - fileVersionLabel: "Version", - searchLabel: "Suche", - searchSuggestionsLabel: "Vorherige Suchen", - waitingLabel: "Warten...", - - restoreConnection: "Verbindung wiederherstellen", - - noPageSelected: "Keine Seite ausgewählt", - }, - - regional: { - weekdays: { - full: [ - "Sonntag", - "Montag", - "Dienstag", - "Mittwoch", - "Donnerstag", - "Freitag", - "Samstag", - ], - abbreviated: ["So", "Mo", "Di", "Mi", "Do", "Fr", "Sa"], - }, - }, - - homePage: { - appName: "Coordination Tool", - - overviewHeadline: "Übersicht", - - serverAddress: "Serveradresse", - serverAddressPlaceholder: "wss://192.168.0.69:3000", - connectAudioLabel: "mit Server verbinden", - disconnectAudioLabel: "vom Server trennen", - manageConnectionsAudioLabel: "Verbindungen verwalten", - - yourNameLabel: "Dein Name", - yourNamePlaceholder: "Max Mustermann", - setNameButtonAudioLabel: "Name speichern", - - settingsButton: "Einstellungen", - manageStorageButton: "Daten verwalten", - transferDataButton: "Daten übertragen", - - updateButton: (version: string) => `Aktualisieren: ${version}`, - - scrollToChatButton: "Chats", - - backToOverviewAudioLabel: "zurück zur übersicht", - chatsHeadline: "Chats", - - addChatAudioLabel: "Name des neuen Chats", - addChatPlaceholder: "Chat hinzufügen", - addChatButton: "Chat hinzufügen", - }, - - settings: { - pages: { - appearance: "Erscheinungsbild", - regional: "Sprache & Region", - info: "Über CT", - }, - themes: { - dynamic: "Dynamisch", - dark: "Dunkel", - light: "Hell", - system: "Geräteeinstellung", - black: "Schwarz", - }, - - version: "Version", - language: "Sprache", - - firstDayOfWeekLabel: "Erster Wochentag", - - checkUpdatesButton: "Nach updates suchen", - }, - - connectionModal: { - connectionModalHeadline: "Verbindungen verwalten", - - connectButtonAudioLabel: "verbinden", - }, - - dataTransferModal: { - transferDataHeadline: "Datenübertragung", - sendHeadline: "An anderes Gerät senden", - receiveHeadline: "An dieses Gerät senden", - exportHeadline: "Daten exportieren", - importHeadline: "Daten importieren", - selectionDescription: - "Wähle die Daten aus, die du übertragen möchtest.", - exportSelectionDescription: - "Wähle die Daten aus, die du exportieren möchtest.", - dataEntryDescription: - "Gib diese Informationen auf dem anderen Gerät ein.", - dataEntryInputDescription: - "Gib die auf dem anderen Gerät angezeigten Informationen ein.", - - fromThisDeviceButton: "An anderes Gerät senden", - toThisDeviceButton: "An dieses Gerät senden", - exportButton: "Als Datei exportieren", - importButton: "Aus Datei importieren", - - generalHeadline: "Allgemein", - - connectionData: "Verbindungsdaten", - settingsData: "Einstellungen", - - chatsHeadline: "Chats", - - transferChannelHeadline: "Übertragungskanal", - transferKeyHeadline: "Schlüssel", - - sendButton: "Senden", - sendAgainButton: "Erneut senden", - - filesSentCount: (count) => `Dateien gesendet: ${count}.`, - allFilesSent: "Fertig.", - - filesReceivedCount: (count) => `Dateien empfangen: ${count}.`, - - exportKey: "Schlüssel", - exportKeyConfirmation: "Schlüssel bestätigen", - downloadFileButton: "Herunterladen", - importFileButton: "Importieren", - decryptImportButton: "Entschlüsseln", - incorrectPassphraseError: "Der Schlüssel ist nicht korrekt", - }, - - storage: { - noItemSelected: "Kein Element ausgewählt", - notAFile: "(keine Datei)", - contentEmpty: "(leer)", - - usageLabel: "Speicher", - usageVauleLabel: (used: number, max: number) => `${used} von ${max} MB belegt`, - - path: "Pfad", - content: "Inhalt", - - deleteItem: "Element löschen", - - removeJunkButton: "Datenmüll löschen", - }, - - chatPage: { - closeChatAudioLabe: "Chat schließen", - chatSettingsAudioLabel: "Chateinstellungen", - - pages: { - settings: "Einstellungen", - messages: "Nachrichten", - tasks: "Aufgaben", - calendar: "Kalender", - }, - - settings: { - settingsHeadline: "Einstellungen", + updater: { + migrated: "Migriert", + }, + + general: { + deleteItemButtonAudioLabel: "element löschen", + searchButtonAudioLabel: "suchen", + searchButtonClearAudioLabel: "suche zurücksetzen", + + abortButton: "Abbrechen", + applyButton: "Anwenden", + backButton: "Zurück", + cancelButton: "Abbrechen", + continueButton: "Weiter", + confirmButton: "Bestätigen", + closeButton: "Schließen", + deleteButton: "Löschen", + exitButton: "Schließen", + fullscreenButton: "Vollbild", + refreshButton: "Aktualisieren", + saveButton: "Speichern", + setButton: "OK", + + filterOrCreateLabel: "Suchen oder erstellen", + createLabel: (query: string) => `"${query}" erstellen`, + + reloadAppButton: "Neu laden", + + fileVersionLabel: "Version", + searchLabel: "Suche", + searchSuggestionsLabel: "Vorherige Suchen", + waitingLabel: "Warten...", + + restoreConnection: "Verbindung wiederherstellen", + + noPageSelected: "Keine Seite ausgewählt", + }, + + regional: { + weekdays: { + full: [ + "Sonntag", + "Montag", + "Dienstag", + "Mittwoch", + "Donnerstag", + "Freitag", + "Samstag", + ], + abbreviated: ["So", "Mo", "Di", "Mi", "Do", "Fr", "Sa"], + }, + }, + + homePage: { + appName: "Coordination Tool", + + overviewHeadline: "Übersicht", + + serverAddress: "Serveradresse", + serverAddressPlaceholder: "wss://192.168.0.69:3000", + connectAudioLabel: "mit Server verbinden", + disconnectAudioLabel: "vom Server trennen", + manageConnectionsAudioLabel: "Verbindungen verwalten", + + yourNameLabel: "Dein Name", + yourNamePlaceholder: "Max Mustermann", + setNameButtonAudioLabel: "Name speichern", + + settingsButton: "Einstellungen", + manageStorageButton: "Daten verwalten", + transferDataButton: "Daten übertragen", + + updateButton: (version: string) => `Aktualisieren: ${version}`, + + scrollToChatButton: "Chats", + + backToOverviewAudioLabel: "zurück zur übersicht", + chatsHeadline: "Chats", + + addChatAudioLabel: "Name des neuen Chats", + addChatPlaceholder: "Chat hinzufügen", + addChatButton: "Chat hinzufügen", + }, + + settings: { + pages: { + appearance: "Erscheinungsbild", + regional: "Sprache & Region", + info: "Über CT", + }, + themes: { + dynamic: "Dynamisch", + dark: "Dunkel", + light: "Hell", + system: "Geräteeinstellung", + black: "Schwarz", + }, + + version: "Version", + language: "Sprache", + + firstDayOfWeekLabel: "Erster Wochentag", + + checkUpdatesButton: "Nach updates suchen", + }, + + connectionModal: { + connectionModalHeadline: "Verbindungen verwalten", + + connectButtonAudioLabel: "verbinden", + }, + + dataTransferModal: { + transferDataHeadline: "Datenübertragung", + sendHeadline: "An anderes Gerät senden", + receiveHeadline: "An dieses Gerät senden", + exportHeadline: "Daten exportieren", + importHeadline: "Daten importieren", + selectionDescription: + "Wähle die Daten aus, die du übertragen möchtest.", + exportSelectionDescription: + "Wähle die Daten aus, die du exportieren möchtest.", + dataEntryDescription: + "Gib diese Informationen auf dem anderen Gerät ein.", + dataEntryInputDescription: + "Gib die auf dem anderen Gerät angezeigten Informationen ein.", + + fromThisDeviceButton: "An anderes Gerät senden", + toThisDeviceButton: "An dieses Gerät senden", + exportButton: "Als Datei exportieren", + importButton: "Aus Datei importieren", + + generalHeadline: "Allgemein", + + connectionData: "Verbindungsdaten", + settingsData: "Einstellungen", + + chatsHeadline: "Chats", + + transferChannelHeadline: "Übertragungskanal", + transferKeyHeadline: "Schlüssel", + + sendButton: "Senden", + sendAgainButton: "Erneut senden", + + filesSentCount: (count) => `Dateien gesendet: ${count}.`, + allFilesSent: "Fertig.", + + filesReceivedCount: (count) => `Dateien empfangen: ${count}.`, + + exportKey: "Schlüssel", + exportKeyConfirmation: "Schlüssel bestätigen", + downloadFileButton: "Herunterladen", + importFileButton: "Importieren", + decryptImportButton: "Entschlüsseln", + incorrectPassphraseError: "Der Schlüssel ist nicht korrekt", + }, + + storage: { + noItemSelected: "Kein Element ausgewählt", + notAFile: "(keine Datei)", + contentEmpty: "(leer)", + + usageLabel: "Speicher", + usageVauleLabel: (used: number, max: number) => + `${used} von ${max} MB belegt`, + + path: "Pfad", + content: "Inhalt", + + deleteItem: "Element löschen", - nameLabel: "Name", - setNameButtonAudioLabel: "namen festlegen", + removeJunkButton: "Datenmüll löschen", + }, + + chatPage: { + closeChatAudioLabe: "Chat schließen", + chatSettingsAudioLabel: "Chateinstellungen", + + pages: { + settings: "Einstellungen", + messages: "Nachrichten", + tasks: "Aufgaben", + calendar: "Kalender", + }, - newSecondaryChannelPlaceholder: "Sekundären Kanal hinzufügen", - newSecondaryChannelAudioLabel: - "Name des neuen sekundären Kanals", - addSecondaryChannelButtonAudioLabel: - "Sekundären Kanal hinzufügen", + settings: { + settingsHeadline: "Einstellungen", - encryptionKeyLabel: "Schlüssel", - setEncryptionKeyButtonAudioLabel: "Schlüssel festlegen", - showEncryptionKey: "Schlüssel anzeigen", - - setColorButtonAudioLabel: "Farbe festlegen", + nameLabel: "Name", + setNameButtonAudioLabel: "namen festlegen", - deleteChatButton: "Gesamten Chat löschen", - }, + newSecondaryChannelPlaceholder: "Sekundären Kanal hinzufügen", + newSecondaryChannelAudioLabel: + "Name des neuen sekundären Kanals", + addSecondaryChannelButtonAudioLabel: + "Sekundären Kanal hinzufügen", - message: { - messagesHeadline: "Nachrichten", + encryptionKeyLabel: "Schlüssel", + setEncryptionKeyButtonAudioLabel: "Schlüssel festlegen", + showEncryptionKey: "Schlüssel anzeigen", - messageFilterHeadline: "Nachrichten filtern", - messageFilterReactionsHadline: "Reaktionen", - messageFilterAllReactionsButton: "Alle anzeigen", + setColorButtonAudioLabel: "Farbe festlegen", - composerInputPlaceholder: "Schreib eine Nachricht...", - sendMessageButtonAudioLabel: "nachricht senden", - filterMessagesButtonAudioLabel: "nachrichten filtern", + deleteChatButton: "Gesamten Chat löschen", + }, - showMessageInfoButtonAudioLabel: "nachrichteninfo anzeigen", - messageInfoHeadline: "Nachrichteninfo", - cancelReplyAudioLabel: "antwort abbrechen", + message: { + messagesHeadline: "Nachrichten", - sentBy: "Gesendet von", - timeSent: "Sendezeit", - channel: "Kanal", - messageContent: "Nachrichteninhalt", + messageFilterHeadline: "Nachrichten filtern", + messageFilterReactionsHadline: "Reaktionen", + messageFilterAllReactionsButton: "Alle anzeigen", - copyMessageButton: "Nachricht kopieren", - resendMessageButton: "Nachricht erneut senden", - decryptMessageButton: "Nachricht entschlüsseln", - replyToMessageButton: "Auf Nachricht antworten", - deleteMessageButton: "Nachricht löschen", + composerInputPlaceholder: "Schreib eine Nachricht...", + sendMessageButtonAudioLabel: "nachricht senden", + filterMessagesButtonAudioLabel: "nachrichten filtern", - // + showMessageInfoButtonAudioLabel: "nachrichteninfo anzeigen", + messageInfoHeadline: "Nachrichteninfo", + cancelReplyAudioLabel: "antwort abbrechen", - thumbsUpReaction: "Reaktion: Daumen hoch", - checkReaction: "Reaktion: Haken", - stopReaction: "Reaktion: Stopp", - attentionReaction: "Reaktion: Ausrufezeichen", - doubleAttentionReaction: "Reaktion: doppeltes Ausrufezeichen", - questionReaction: "Reaktion: Fragezeichen", + sentBy: "Gesendet von", + timeSent: "Sendezeit", + channel: "Kanal", + messageContent: "Nachrichteninhalt", - replyPrefixLabel: "Antworten: ", - replyHeaderLabel: (message: string) => `Antworten an "${message}"`, - }, + copyMessageButton: "Nachricht kopieren", + resendMessageButton: "Nachricht erneut senden", + decryptMessageButton: "Nachricht entschlüsseln", + replyToMessageButton: "Auf Nachricht antworten", + deleteMessageButton: "Nachricht löschen", - task: { - noBoardSelected: "Kein Board ausgewählt", - boardNotFound: "Board nicht gefunden", + // - closeBoardButtonAudioLabel: "board schließen", - toggleBoardButtonAudioLabel: "board-liste ein/ausblenden", - showBoardSettingsButtonAudioLabel: - "Board-Einstellungen anzeigen", + thumbsUpReaction: "Reaktion: Daumen hoch", + checkReaction: "Reaktion: Haken", + stopReaction: "Reaktion: Stopp", + attentionReaction: "Reaktion: Ausrufezeichen", + doubleAttentionReaction: "Reaktion: doppeltes Ausrufezeichen", + questionReaction: "Reaktion: Fragezeichen", - listViewButtonAudioLabel: "Listenansicht", - kanbanViewButtonAudioLabel: "Kanban-Ansicht", - statusViewButtonAudioLabel: "Statusrasteransicht", + replyPrefixLabel: "Antworten: ", + replyHeaderLabel: (message: string) => + `Antworten an "${message}"`, + }, - filterTasksButtonAudioLabel: "Aufgaben filtern", - createTaskButtonAudioLabel: "Neue Aufgabe erstellen", + task: { + noBoardSelected: "Kein Board ausgewählt", + boardNotFound: "Board nicht gefunden", - boardSettingsHeadline: "Board-Einstellungen", - boardNameInputLabel: "Boardname", - deleteBoardButton: "Board und alle Aufgaben löschen", + closeBoardButtonAudioLabel: "board schließen", + toggleBoardButtonAudioLabel: "board-liste ein/ausblenden", + showBoardSettingsButtonAudioLabel: + "Board-Einstellungen anzeigen", - taskSettingsHeadline: "Aufgabe bearbeiten", + listViewButtonAudioLabel: "Listenansicht", + kanbanViewButtonAudioLabel: "Kanban-Ansicht", + statusViewButtonAudioLabel: "Statusrasteransicht", - taskNameLabel: "Titel", - taskBoardLabel: "Board", + filterTasksButtonAudioLabel: "Aufgaben filtern", + createTaskButtonAudioLabel: "Neue Aufgabe erstellen", - taskCategoryLabel: "Kategorie", - taskStatusLabel: "Status", - taskPriorityLabel: "Priorität", + boardSettingsHeadline: "Board-Einstellungen", + boardNameInputLabel: "Boardname", + deleteBoardButton: "Board und alle Aufgaben löschen", - taskDescriptionLabel: "Beschreibung", + taskSettingsHeadline: "Aufgabe bearbeiten", - taskDateLabel: "Datum", - taskTimeLabel: "Uhrzeit", + taskNameLabel: "Titel", + taskBoardLabel: "Board", - deleteTaskButton: "Aufgabe löschen", + taskCategoryLabel: "Kategorie", + taskStatusLabel: "Status", + taskPriorityLabel: "Priorität", - filterTasksHeadline: "Aufgaben filtern", + taskDescriptionLabel: "Beschreibung", - renameCategoryInputPlaceholder: "Kategorie umbenennen", - renameStatusInputPlaceholder: "Status umbenennen", - }, + taskDateLabel: "Datum", + taskTimeLabel: "Uhrzeit", - calendar: { - eventsBoard: "Ereignisse", + deleteTaskButton: "Aufgabe löschen", - /// + filterTasksHeadline: "Aufgaben filtern", - todayButtonAudioLabel: "gehe zu heute", + renameCategoryInputPlaceholder: "Kategorie umbenennen", + renameStatusInputPlaceholder: "Status umbenennen", + }, - previousMonthButtonAudioLabel: "vorheriger monat", - nextMonthButtonAudioLabel: "nächster monat", + calendar: { + eventsBoard: "Ereignisse", - yearInputAudioLabel: "Jahr", - monthInputAudioLabel: "Monat", + /// - yearInputPlaceholder: "2000", - monthInputPlaceholder: "01", + todayButtonAudioLabel: "gehe zu heute", - searchEventsHeadline: "Ereignisse suchen", + previousMonthButtonAudioLabel: "vorheriger monat", + nextMonthButtonAudioLabel: "nächster monat", - events: "Ereignisse", - noEvents: "Keine Ereignisse", - - eventNext: "Als nächstes", - }, - }, + yearInputAudioLabel: "Jahr", + monthInputAudioLabel: "Monat", + + yearInputPlaceholder: "2000", + monthInputPlaceholder: "01", + + searchEventsHeadline: "Ereignisse suchen", + + events: "Ereignisse", + noEvents: "Keine Ereignisse", + + eventNext: "Als nächstes", + }, + }, }, es: { - updater: { - migrated: "Migrado", - }, - - general: { - deleteItemButtonAudioLabel: "eliminar elemento", - searchButtonAudioLabel: "buscar", - searchButtonClearAudioLabel: "borrar büsqueda", - - abortButton: "Abortar", - applyButton: "Guardar", - backButton: "Atrás", - cancelButton: "Cancelar", - continueButton: "Continuar", - confirmButton: "Confirmar", - closeButton: "Cerrar", - deleteButton: "Borrar", - exitButton: "Salir", - fullscreenButton: "Pantalla completa", - refreshButton: "Actualizar", - saveButton: "Guardar", - setButton: "OK", - - filterOrCreateLabel: "Buscar o crear", - createLabel: (query: string) => `Crear "${query}"`, - - reloadAppButton: "Recargar app", - - fileVersionLabel: "Versión", - searchLabel: "Buscar", - searchSuggestionsLabel: "Búsquedas anteriores", - waitingLabel: "Esperando...", - - restoreConnection: "Conectar de nuevo", - - noPageSelected: "No página seleccionada", - }, - - regional: { - weekdays: { - full: [ - "Domingo", - "Lunes", - "Martes", - "Miércoles", - "Jueves", - "Viernes", - "Sábado", - ], - abbreviated: ["Dom", "Lun", "Mar", "Mié", "Jue", "Vie", "Sáb"], - }, - }, - - homePage: { - appName: "Coordination Tool", - - overviewHeadline: "Resumen", - - serverAddress: "Dirección del servidor", - serverAddressPlaceholder: "wss://192.168.0.69:3000", - connectAudioLabel: "conectar al servidor", - disconnectAudioLabel: "desconectar del servidor", - manageConnectionsAudioLabel: "gestionar conexiones", - - yourNameLabel: "Tu nombre", - yourNamePlaceholder: "Juan Pérez", - setNameButtonAudioLabel: "establecer nombre", - - settingsButton: "Ajustes", - manageStorageButton: "Gestionar almacenamiento", - transferDataButton: "Enviar o exportar archivos", - - updateButton: (version: string) => `Actualizar a ${version}`, - - scrollToChatButton: "Chats", - - backToOverviewAudioLabel: "volver al resumen", - chatsHeadline: "Chats", - - addChatAudioLabel: "nombre del nuevo chat", - addChatPlaceholder: "Añadir chat", - addChatButton: "Añadir chat", - }, - - settings: { - pages: { - appearance: "Aspecto", - regional: "Idioma y Región", - info: "Sobre CT", - }, - themes: { - dynamic: "Dinámico", - dark: "Oscuro", - light: "Claro", - system: "Según dispositivo", - black: "Negro", - }, - - version: "Versión", - language: "Idioma", - - firstDayOfWeekLabel: "Primer día de la semana", - - checkUpdatesButton: "Buscar actualizaciones", - }, - connectionModal: { - connectionModalHeadline: "Gestionar Conexiones", - - connectButtonAudioLabel: "conectar", - }, - - dataTransferModal: { - transferDataHeadline: "Transferencia de datos", - sendHeadline: "Enviar a otro dispositivo", - receiveHeadline: "Enviar a este dispositivo", - exportHeadline: "Exportar archivo", - importHeadline: "Importar archivo", - selectionDescription: - "Selecciona los datos que quieres transferir.", - exportSelectionDescription: - "Selecciona los datos que quieres exportar.", - dataEntryDescription: - "Introduce estos datos en el otro dispositivo.", - dataEntryInputDescription: - "Introduce los datos mostrados en el otro dispositivo.", - - fromThisDeviceButton: "Enviar a otro dispositivo", - toThisDeviceButton: "Enviar a este dispositivo", - exportButton: "Exportar archivo", - importButton: "Importar archivo", - - generalHeadline: "General", - - connectionData: "Datos de Conexión", - settingsData: "Datos de Configuración", - - chatsHeadline: "Chats", - - transferChannelHeadline: "Canal de Transferencia", - transferKeyHeadline: "Clave de encriptación de transferencia", - - sendButton: "Enviar", - sendAgainButton: "Enviar otra vez", - - filesSentCount: (count) => `Archivos enviados: ${count}.`, - allFilesSent: "Hecho.", - - filesReceivedCount: (count) => `Archivos recibidos: ${count}.`, - - exportKey: "Clave de encriptación", - exportKeyConfirmation: "Confirmar clave", - downloadFileButton: "Descargar", - importFileButton: "Importar", - decryptImportButton: "Descifrar", - incorrectPassphraseError: "La clave no es correcta", - }, - - storage: { - noItemSelected: "Ningún elemento seleccionado", - notAFile: "(no es un archivo)", - contentEmpty: "(vacío)", - - usageLabel: "Almacenamiento", - usageVauleLabel: (used: number, max: number) => `${used} de ${max} MB en uso`, - - path: "Ruta", - content: "Contenido", - - deleteItem: "Eliminar elemento", - - removeJunkButton: "Eliminar archivos basura", - }, - - chatPage: { - closeChatAudioLabe: "cerrar chat", - chatSettingsAudioLabel: "configuración del chat", - - pages: { - settings: "Configuración", - messages: "Mensajes", - tasks: "Tareas", - calendar: "Calendario", - }, - - settings: { - settingsHeadline: "Configuración", - - nameLabel: "Nombre del chat", - setNameButtonAudioLabel: "establecer nombre", - - newSecondaryChannelPlaceholder: "Añadir canal secundario", - newSecondaryChannelAudioLabel: - "nombre del nuevo canal secundario", - addSecondaryChannelButtonAudioLabel: "añadir canal secundario", + updater: { + migrated: "Migrado", + }, + + general: { + deleteItemButtonAudioLabel: "eliminar elemento", + searchButtonAudioLabel: "buscar", + searchButtonClearAudioLabel: "borrar büsqueda", + + abortButton: "Abortar", + applyButton: "Guardar", + backButton: "Atrás", + cancelButton: "Cancelar", + continueButton: "Continuar", + confirmButton: "Confirmar", + closeButton: "Cerrar", + deleteButton: "Borrar", + exitButton: "Salir", + fullscreenButton: "Pantalla completa", + refreshButton: "Actualizar", + saveButton: "Guardar", + setButton: "OK", + + filterOrCreateLabel: "Buscar o crear", + createLabel: (query: string) => `Crear "${query}"`, + + reloadAppButton: "Recargar app", + + fileVersionLabel: "Versión", + searchLabel: "Buscar", + searchSuggestionsLabel: "Búsquedas anteriores", + waitingLabel: "Esperando...", + + restoreConnection: "Conectar de nuevo", + + noPageSelected: "No página seleccionada", + }, + + regional: { + weekdays: { + full: [ + "Domingo", + "Lunes", + "Martes", + "Miércoles", + "Jueves", + "Viernes", + "Sábado", + ], + abbreviated: ["Dom", "Lun", "Mar", "Mié", "Jue", "Vie", "Sáb"], + }, + }, + + homePage: { + appName: "Coordination Tool", + + overviewHeadline: "Resumen", + + serverAddress: "Dirección del servidor", + serverAddressPlaceholder: "wss://192.168.0.69:3000", + connectAudioLabel: "conectar al servidor", + disconnectAudioLabel: "desconectar del servidor", + manageConnectionsAudioLabel: "gestionar conexiones", + + yourNameLabel: "Tu nombre", + yourNamePlaceholder: "Juan Pérez", + setNameButtonAudioLabel: "establecer nombre", + + settingsButton: "Ajustes", + manageStorageButton: "Gestionar almacenamiento", + transferDataButton: "Enviar o exportar archivos", + + updateButton: (version: string) => `Actualizar a ${version}`, + + scrollToChatButton: "Chats", + + backToOverviewAudioLabel: "volver al resumen", + chatsHeadline: "Chats", + + addChatAudioLabel: "nombre del nuevo chat", + addChatPlaceholder: "Añadir chat", + addChatButton: "Añadir chat", + }, + + settings: { + pages: { + appearance: "Aspecto", + regional: "Idioma y Región", + info: "Sobre CT", + }, + themes: { + dynamic: "Dinámico", + dark: "Oscuro", + light: "Claro", + system: "Según dispositivo", + black: "Negro", + }, + + version: "Versión", + language: "Idioma", + + firstDayOfWeekLabel: "Primer día de la semana", + + checkUpdatesButton: "Buscar actualizaciones", + }, + connectionModal: { + connectionModalHeadline: "Gestionar Conexiones", + + connectButtonAudioLabel: "conectar", + }, + + dataTransferModal: { + transferDataHeadline: "Transferencia de datos", + sendHeadline: "Enviar a otro dispositivo", + receiveHeadline: "Enviar a este dispositivo", + exportHeadline: "Exportar archivo", + importHeadline: "Importar archivo", + selectionDescription: + "Selecciona los datos que quieres transferir.", + exportSelectionDescription: + "Selecciona los datos que quieres exportar.", + dataEntryDescription: + "Introduce estos datos en el otro dispositivo.", + dataEntryInputDescription: + "Introduce los datos mostrados en el otro dispositivo.", + + fromThisDeviceButton: "Enviar a otro dispositivo", + toThisDeviceButton: "Enviar a este dispositivo", + exportButton: "Exportar archivo", + importButton: "Importar archivo", + + generalHeadline: "General", + + connectionData: "Datos de Conexión", + settingsData: "Datos de Configuración", + + chatsHeadline: "Chats", + + transferChannelHeadline: "Canal de Transferencia", + transferKeyHeadline: "Clave de encriptación de transferencia", + + sendButton: "Enviar", + sendAgainButton: "Enviar otra vez", + + filesSentCount: (count) => `Archivos enviados: ${count}.`, + allFilesSent: "Hecho.", + + filesReceivedCount: (count) => `Archivos recibidos: ${count}.`, + + exportKey: "Clave de encriptación", + exportKeyConfirmation: "Confirmar clave", + downloadFileButton: "Descargar", + importFileButton: "Importar", + decryptImportButton: "Descifrar", + incorrectPassphraseError: "La clave no es correcta", + }, + + storage: { + noItemSelected: "Ningún elemento seleccionado", + notAFile: "(no es un archivo)", + contentEmpty: "(vacío)", + + usageLabel: "Almacenamiento", + usageVauleLabel: (used: number, max: number) => + `${used} de ${max} MB en uso`, + + path: "Ruta", + content: "Contenido", + + deleteItem: "Eliminar elemento", + + removeJunkButton: "Eliminar archivos basura", + }, + + chatPage: { + closeChatAudioLabe: "cerrar chat", + chatSettingsAudioLabel: "configuración del chat", + + pages: { + settings: "Configuración", + messages: "Mensajes", + tasks: "Tareas", + calendar: "Calendario", + }, + + settings: { + settingsHeadline: "Configuración", + + nameLabel: "Nombre del chat", + setNameButtonAudioLabel: "establecer nombre", - encryptionKeyLabel: "Clave de encriptación", - setEncryptionKeyButtonAudioLabel: - "establecer clave de encriptación", - showEncryptionKey: "Mostrar clave de encriptación", - - setColorButtonAudioLabel: "establecer color", + newSecondaryChannelPlaceholder: "Añadir canal secundario", + newSecondaryChannelAudioLabel: + "nombre del nuevo canal secundario", + addSecondaryChannelButtonAudioLabel: "añadir canal secundario", - deleteChatButton: "Eliminar todo el chat", - }, + encryptionKeyLabel: "Clave de encriptación", + setEncryptionKeyButtonAudioLabel: + "establecer clave de encriptación", + showEncryptionKey: "Mostrar clave de encriptación", - message: { - messagesHeadline: "Mensajes", + setColorButtonAudioLabel: "establecer color", - messageFilterHeadline: "Filtrar mensajes", - messageFilterReactionsHadline: "Reacciones", - messageFilterAllReactionsButton: "Mostrar todas", + deleteChatButton: "Eliminar todo el chat", + }, - composerInputPlaceholder: "Escribe un mensaje...", - sendMessageButtonAudioLabel: "enviar mensaje", - filterMessagesButtonAudioLabel: "filtrar mensajes", + message: { + messagesHeadline: "Mensajes", - showMessageInfoButtonAudioLabel: - "mostrar información del mensaje", - messageInfoHeadline: "Información del Mensaje", - cancelReplyAudioLabel: "abortar la respuesta", + messageFilterHeadline: "Filtrar mensajes", + messageFilterReactionsHadline: "Reacciones", + messageFilterAllReactionsButton: "Mostrar todas", - sentBy: "Enviado por", - timeSent: "Hora de envío", - channel: "Canal", - messageContent: "Contenido del mensaje", + composerInputPlaceholder: "Escribe un mensaje...", + sendMessageButtonAudioLabel: "enviar mensaje", + filterMessagesButtonAudioLabel: "filtrar mensajes", - copyMessageButton: "Copiar mensaje", - resendMessageButton: "Reenviar mensaje", - decryptMessageButton: "Desencriptar mensaje", - replyToMessageButton: "Responder al mensaje", - deleteMessageButton: "Eliminar mensaje", + showMessageInfoButtonAudioLabel: + "mostrar información del mensaje", + messageInfoHeadline: "Información del Mensaje", + cancelReplyAudioLabel: "abortar la respuesta", - // + sentBy: "Enviado por", + timeSent: "Hora de envío", + channel: "Canal", + messageContent: "Contenido del mensaje", - thumbsUpReaction: "Reacción: pulgar hacia arriba", - checkReaction: "Reacción: marca de verificación", - stopReaction: "Reacción: signo de parada", - attentionReaction: "Reaccion: signo de atención", - doubleAttentionReaction: "Reaccion: signo de atención doble", - questionReaction: "Reaccion: signo de interrogación", + copyMessageButton: "Copiar mensaje", + resendMessageButton: "Reenviar mensaje", + decryptMessageButton: "Desencriptar mensaje", + replyToMessageButton: "Responder al mensaje", + deleteMessageButton: "Eliminar mensaje", - replyPrefixLabel: "Respuestas: ", - replyHeaderLabel: (message: string) => `Respuestas a "${message}"`, - }, + // - task: { - noBoardSelected: "Ningún tablero seleccionado", - boardNotFound: "Tablero no encontrado", + thumbsUpReaction: "Reacción: pulgar hacia arriba", + checkReaction: "Reacción: marca de verificación", + stopReaction: "Reacción: signo de parada", + attentionReaction: "Reaccion: signo de atención", + doubleAttentionReaction: "Reaccion: signo de atención doble", + questionReaction: "Reaccion: signo de interrogación", - closeBoardButtonAudioLabel: "cerrar tablero", - toggleBoardButtonAudioLabel: - "mostrar o ocultar lista de tableros", - showBoardSettingsButtonAudioLabel: - "mostrar configuración del tablero", + replyPrefixLabel: "Respuestas: ", + replyHeaderLabel: (message: string) => + `Respuestas a "${message}"`, + }, - listViewButtonAudioLabel: "vista de lista", - kanbanViewButtonAudioLabel: "vista kanban", - statusViewButtonAudioLabel: "vista de cuadrícula de estado", + task: { + noBoardSelected: "Ningún tablero seleccionado", + boardNotFound: "Tablero no encontrado", - filterTasksButtonAudioLabel: "filtrar tareas", - createTaskButtonAudioLabel: "crear nueva tarea", + closeBoardButtonAudioLabel: "cerrar tablero", + toggleBoardButtonAudioLabel: + "mostrar o ocultar lista de tableros", + showBoardSettingsButtonAudioLabel: + "mostrar configuración del tablero", - boardSettingsHeadline: "Configuración del Tablero", - boardNameInputLabel: "Nombre del tablero", - deleteBoardButton: "Eliminar tablero y todas las tareas", + listViewButtonAudioLabel: "vista de lista", + kanbanViewButtonAudioLabel: "vista kanban", + statusViewButtonAudioLabel: "vista de cuadrícula de estado", - taskSettingsHeadline: "Editar Tarea", + filterTasksButtonAudioLabel: "filtrar tareas", + createTaskButtonAudioLabel: "crear nueva tarea", - taskNameLabel: "Título", - taskBoardLabel: "Tablero", + boardSettingsHeadline: "Configuración del Tablero", + boardNameInputLabel: "Nombre del tablero", + deleteBoardButton: "Eliminar tablero y todas las tareas", - taskCategoryLabel: "Categoría", - taskStatusLabel: "Estado", - taskPriorityLabel: "Prioridad", + taskSettingsHeadline: "Editar Tarea", - taskDescriptionLabel: "Descripción", + taskNameLabel: "Título", + taskBoardLabel: "Tablero", - taskDateLabel: "Fecha", - taskTimeLabel: "Hora", + taskCategoryLabel: "Categoría", + taskStatusLabel: "Estado", + taskPriorityLabel: "Prioridad", - deleteTaskButton: "Eliminar tarea", + taskDescriptionLabel: "Descripción", - filterTasksHeadline: "Filtrar Tareas", + taskDateLabel: "Fecha", + taskTimeLabel: "Hora", - renameCategoryInputPlaceholder: "Renombrar categoría", - renameStatusInputPlaceholder: "Renombrar estado", - }, + deleteTaskButton: "Eliminar tarea", - calendar: { - eventsBoard: "Eventos", + filterTasksHeadline: "Filtrar Tareas", - /// + renameCategoryInputPlaceholder: "Renombrar categoría", + renameStatusInputPlaceholder: "Renombrar estado", + }, - todayButtonAudioLabel: "ir a hoy", + calendar: { + eventsBoard: "Eventos", - previousMonthButtonAudioLabel: "mes anterior", - nextMonthButtonAudioLabel: "mes siguiente", + /// - yearInputAudioLabel: "año", - monthInputAudioLabel: "mes", + todayButtonAudioLabel: "ir a hoy", - yearInputPlaceholder: "2000", - monthInputPlaceholder: "01", + previousMonthButtonAudioLabel: "mes anterior", + nextMonthButtonAudioLabel: "mes siguiente", - searchEventsHeadline: "Buscar Eventos", + yearInputAudioLabel: "año", + monthInputAudioLabel: "mes", - events: "Eventos", - noEvents: "No hay eventos", - - eventNext: "A continuación", - }, - }, + yearInputPlaceholder: "2000", + monthInputPlaceholder: "01", + + searchEventsHeadline: "Buscar Eventos", + + events: "Eventos", + noEvents: "No hay eventos", + + eventNext: "A continuación", + }, + }, }, }; diff --git a/src/ViewModel/Chat/chatListViewModel.ts b/src/ViewModel/Chat/chatListViewModel.ts index 1ed53705..0abbd33e 100644 --- a/src/ViewModel/Chat/chatListViewModel.ts +++ b/src/ViewModel/Chat/chatListViewModel.ts @@ -105,11 +105,11 @@ export default class ChatListViewModel { // utility getDisplayName = (fullChannel: string): string => { - for (const vm of this.chatViewModels.value) { - const fullReference = vm.chatModel.id; - if (fullReference == fullChannel) return vm.chatModel.info.name; - } + for (const vm of this.chatViewModels.value) { + const fullReference = vm.chatModel.id; + if (fullReference == fullChannel) return vm.chatModel.info.name; + } - return fullChannel; - } + return fullChannel; + }; } diff --git a/src/ViewModel/Chat/chatMessageViewModel.ts b/src/ViewModel/Chat/chatMessageViewModel.ts index f90b794c..68e058d6 100644 --- a/src/ViewModel/Chat/chatMessageViewModel.ts +++ b/src/ViewModel/Chat/chatMessageViewModel.ts @@ -17,7 +17,10 @@ export default class ChatMessageViewModel { body: React.State = new React.State(""); inlineReply: ChatMessageViewModel | undefined = undefined; replies: React.MapState = new React.MapState(); - replyCount: React.State = React.createProxyState([this.replies], ()=>this.replies.value.size); + replyCount: React.State = React.createProxyState( + [this.replies], + () => this.replies.value.size, + ); status: React.State = new React.State( undefined, ); @@ -100,106 +103,119 @@ export default class ChatMessageViewModel { }; toggleHiding = (): void => { - let hideForReactions: boolean = false; - let hideForReplyView: boolean = false; + let hideForReactions: boolean = false; + let hideForReplyView: boolean = false; - // reactions - const reactionFilter = this.messagePageViewModel.reactionFilter.value; - if (reactionFilter == undefined) { - hideForReactions = false; - } else { - let count: number = 0; - switch (reactionFilter) { - case ReactionSymbols.ThumbsUp: { - count = this.reactionsThumbsUpCount.value; - break; - } - case ReactionSymbols.Check: { - count = this.reactionsCheckCount.value; - break; - } - case ReactionSymbols.Stop: { - count = this.reactionsStopCount.value; - break; - } - case ReactionSymbols.Attention: { - count = this.reactionsAttentionCount.value; - break; - } - case ReactionSymbols.DoubleAttention: { - count = this.reactionsDoubleAttentionCount.value; - break; - } - case ReactionSymbols.Question: { - count = this.reactionsQuestionCount.value; - break; - } - } - hideForReactions = count == 0; - } + // reactions + const reactionFilter = this.messagePageViewModel.reactionFilter.value; + if (reactionFilter == undefined) { + hideForReactions = false; + } else { + let count: number = 0; + switch (reactionFilter) { + case ReactionSymbols.ThumbsUp: { + count = this.reactionsThumbsUpCount.value; + break; + } + case ReactionSymbols.Check: { + count = this.reactionsCheckCount.value; + break; + } + case ReactionSymbols.Stop: { + count = this.reactionsStopCount.value; + break; + } + case ReactionSymbols.Attention: { + count = this.reactionsAttentionCount.value; + break; + } + case ReactionSymbols.DoubleAttention: { + count = this.reactionsDoubleAttentionCount.value; + break; + } + case ReactionSymbols.Question: { + count = this.reactionsQuestionCount.value; + break; + } + } + hideForReactions = count == 0; + } - // reply - const selectedMessage = this.messagePageViewModel.replyViewSelectedMessage.value; - if (selectedMessage == undefined) hideForReplyView = false; - else if (selectedMessage.chatMessage.id == this.chatMessage.id) hideForReplyView = false; - else if (this.inlineReply != undefined && selectedMessage.chatMessage.id == this.inlineReply.chatMessage.id) hideForReplyView = false; - else hideForReplyView = true; + // reply + const selectedMessage = + this.messagePageViewModel.replyViewSelectedMessage.value; + if (selectedMessage == undefined) hideForReplyView = false; + else if (selectedMessage.chatMessage.id == this.chatMessage.id) + hideForReplyView = false; + else if ( + this.inlineReply != undefined && + selectedMessage.chatMessage.id == this.inlineReply.chatMessage.id + ) + hideForReplyView = false; + else hideForReplyView = true; - this.isHidden.value = hideForReactions || hideForReplyView; - } + this.isHidden.value = hideForReactions || hideForReplyView; + }; // reactions handleReaction = (reaction: ChatMessageReaction): void => { - if (reaction.isDeleting) { - this.allReactions.remove(reaction.sender); - } else { - this.allReactions.set(reaction.sender, reaction); - } + if (reaction.isDeleting) { + this.allReactions.remove(reaction.sender); + } else { + this.allReactions.set(reaction.sender, reaction); + } - if (reaction.sender != this.coreViewModel.settingsModel.username) - return; - this.userReaction.value = reaction.isDeleting - ? undefined - : reaction.content; + if (reaction.sender != this.coreViewModel.settingsModel.username) + return; + this.userReaction.value = reaction.isDeleting + ? undefined + : reaction.content; }; sendReaction = (content: ReactionSymbols, isDeleting: boolean): void => { - this.messagePageViewModel.sendReaction( - this.chatMessage.id, - content, - isDeleting, - ); + this.messagePageViewModel.sendReaction( + this.chatMessage.id, + content, + isDeleting, + ); }; // load loadData = (): void => { - this.channel = this.chatMessage.channel; - this.sender = this.chatMessage.sender; - this.dateSent = new Date(this.chatMessage.dateSent).toLocaleString(); - this.body.value = this.chatMessage.body; - this.status.value = this.chatMessage.status; + this.channel = this.chatMessage.channel; + this.sender = this.chatMessage.sender; + this.dateSent = new Date(this.chatMessage.dateSent).toLocaleString(); + this.body.value = this.chatMessage.body; + this.status.value = this.chatMessage.status; - if (this.chatMessage.inlineReplyId) { - this.inlineReply = - this.messagePageViewModel.chatMessageViewModels.value.get( - this.chatMessage.inlineReplyId, - ); - this.inlineReply?.replies.set(this.chatMessage.id, this); - } + if (this.chatMessage.inlineReplyId) { + this.inlineReply = + this.messagePageViewModel.chatMessageViewModels.value.get( + this.chatMessage.inlineReplyId, + ); + this.inlineReply?.replies.set(this.chatMessage.id, this); + } }; // init constructor( - public readonly coreViewModel: CoreViewModel, - public readonly messagePageViewModel: MessagePageViewModel, - chatMessage: ChatMessage, - sentByUser: boolean, + public readonly coreViewModel: CoreViewModel, + public readonly messagePageViewModel: MessagePageViewModel, + chatMessage: ChatMessage, + sentByUser: boolean, ) { - this.chatMessage = chatMessage; - this.sentByUser = sentByUser; - this.loadData(); + this.chatMessage = chatMessage; + this.sentByUser = sentByUser; + this.loadData(); - React.bulkSubscribe([this.messagePageViewModel.reactionFilter, this.messagePageViewModel.replyViewSelectedMessage, this.allReactions], this.toggleHiding); - this.toggleHiding(); + React.bulkSubscribe( + [ + this.messagePageViewModel.reactionFilter, + this.messagePageViewModel.replyViewSelectedMessage, + this.allReactions, + ], + this.toggleHiding, + ); + this.toggleHiding(); } } diff --git a/src/ViewModel/Chat/chatViewModel.ts b/src/ViewModel/Chat/chatViewModel.ts index 934ad951..625b900f 100644 --- a/src/ViewModel/Chat/chatViewModel.ts +++ b/src/ViewModel/Chat/chatViewModel.ts @@ -31,7 +31,7 @@ export default class ChatViewModel extends ContextHost { // state displayedColor: React.State = new React.State(Colors.Standard); selectedPage: React.State = new React.State( - ChatPageTypes.Messages, + ChatPageTypes.Messages, ); pageContexts = new React.MapState(); @@ -42,186 +42,189 @@ export default class ChatViewModel extends ContextHost { // context get isOpen(): boolean { - return this.chatListViewModel.selectedChat.value == this; + return this.chatListViewModel.selectedChat.value == this; } get contextSelection(): ChatPageTypes { - return this.selectedPage.value; + return this.selectedPage.value; } // view open = (): void => { - this.coreViewModel.context = this; - this.chatListViewModel.openChat(this); - //this.selectedPage.callSubscriptions(); + this.coreViewModel.context = this; + this.chatListViewModel.openChat(this); + //this.selectedPage.callSubscriptions(); }; openPage = (page: ChatPageTypes): void => { - this.closeCurrentContext(); - this.selectedPage.value = page; + this.closeCurrentContext(); + this.selectedPage.value = page; }; setColor = (color: Colors): void => { - this.setDisplayedColor(color); - this.chatModel.setColor(color); + this.setDisplayedColor(color); + this.chatModel.setColor(color); }; setDisplayedColor = (color: Colors): void => { - this.displayedColor.value = color; + this.displayedColor.value = color; }; resetColor = (): void => { - this.displayedColor.value = this.settingsPageViewModel.color.value; + this.displayedColor.value = this.settingsPageViewModel.color.value; }; updateIndex = (): void => { - const index: number = - this.chatListViewModel.chatIndexManager.getIndex(this); - this.index.value = index; + const index: number = + this.chatListViewModel.chatIndexManager.getIndex(this); + this.index.value = index; }; // load loadPageSelection = (): void => { - const path: string[] = StorageModel.getPath( - StorageModelSubPaths.Chat, - filePaths.chat.lastUsedPage(this.chatModel.id), - ); - const lastUsedPage: string | null = - this.coreViewModel.storageModel.read(path); - if (lastUsedPage != null) { - this.openPage(lastUsedPage as ChatPageTypes); - } + const path: string[] = StorageModel.getPath( + StorageModelSubPaths.Chat, + filePaths.chat.lastUsedPage(this.chatModel.id), + ); + const lastUsedPage: string | null = + this.coreViewModel.storageModel.read(path); + if (lastUsedPage != null) { + this.openPage(lastUsedPage as ChatPageTypes); + } - this.selectedPage.subscribeSilent((newPage) => { - this.coreViewModel.storageModel.write(path, newPage); - this.resetColor(); - }); + this.selectedPage.subscribeSilent((newPage) => { + this.coreViewModel.storageModel.write(path, newPage); + this.resetColor(); + }); }; loadInfo = (): void => { - this.updateReadStatus(); - this.taskBoardSuggestions.set(CALENDAR_EVENT_BOARD_ID, [ - CALENDAR_EVENT_BOARD_ID, - this.coreViewModel.translations.chatPage.calendar.eventsBoard, - ]); + this.updateReadStatus(); + this.taskBoardSuggestions.set(CALENDAR_EVENT_BOARD_ID, [ + CALENDAR_EVENT_BOARD_ID, + this.coreViewModel.translations.chatPage.calendar.eventsBoard, + ]); }; updateReadStatus = (): void => { - if ( - this.chatListViewModel.selectedChat.value == this && - this.selectedPage.value == ChatPageTypes.Messages - ) { - this.chatModel.setReadStatus(false); - } - this.hasUnreadMessages.value = this.chatModel.info.hasUnreadMessages; + if ( + this.chatListViewModel.selectedChat.value == this && + this.selectedPage.value == ChatPageTypes.Messages + ) { + this.chatModel.setReadStatus(false); + } + this.hasUnreadMessages.value = this.chatModel.info.hasUnreadMessages; }; setReadStatus = (hasUnreadMessages: boolean): void => { - this.chatModel.setReadStatus(hasUnreadMessages); - this.hasUnreadMessages.value = hasUnreadMessages; + this.chatModel.setReadStatus(hasUnreadMessages); + this.hasUnreadMessages.value = hasUnreadMessages; }; subscribeReadStatus = (): void => { - React.createProxyState( - [this.selectedPage, this.chatListViewModel.selectedChat], - () => { - if (this.chatListViewModel.selectedChat.value != this) return; - if (this.selectedPage.value != ChatPageTypes.Messages) return; - this.setReadStatus(false); - }, - ); + React.createProxyState( + [this.selectedPage, this.chatListViewModel.selectedChat], + () => { + if (this.chatListViewModel.selectedChat.value != this) return; + if (this.selectedPage.value != ChatPageTypes.Messages) return; + this.setReadStatus(false); + }, + ); }; // exit close = (): void => { - this.coreViewModel.closeContext(this.contextId); + this.coreViewModel.closeContext(this.contextId); }; handleContextClose = (): void => { - this.chatListViewModel.closeChat(); + this.chatListViewModel.closeChat(); }; // init constructor( - readonly coreViewModel: CoreViewModel, - public readonly chatModel: ChatModel, - public readonly settingsViewModel: SettingsViewModel, - public readonly notificationViewModel: NotificationViewModel, - public readonly connectionViewModel: ConnectionViewModel, - public readonly chatListViewModel: ChatListViewModel, + readonly coreViewModel: CoreViewModel, + public readonly chatModel: ChatModel, + public readonly settingsViewModel: SettingsViewModel, + public readonly notificationViewModel: NotificationViewModel, + public readonly connectionViewModel: ConnectionViewModel, + public readonly chatListViewModel: ChatListViewModel, ) { - super("chat", coreViewModel); + super("chat", coreViewModel); - // page viewModels - this.calendarViewModel = new CalendarPageViewModel( - coreViewModel, - this, - this.chatModel.fileModel.boardsAndTasksModel.calendarModel, - this.chatModel.fileModel.boardsAndTasksModel, - ); - this.taskPageViewModel = new TaskPageViewModel( - this.coreViewModel, - this, - this.chatModel.fileModel.boardsAndTasksModel, - ); - this.messagePageViewModel = new MessagePageViewModel( - this.coreViewModel, - this, - ); - this.settingsPageViewModel = new SettingsPageViewModel( - this.coreViewModel, - this, - ); + // page viewModels + this.calendarViewModel = new CalendarPageViewModel( + coreViewModel, + this, + this.chatModel.fileModel.boardsAndTasksModel.calendarModel, + this.chatModel.fileModel.boardsAndTasksModel, + ); + this.taskPageViewModel = new TaskPageViewModel( + this.coreViewModel, + this, + this.chatModel.fileModel.boardsAndTasksModel, + ); + this.messagePageViewModel = new MessagePageViewModel( + this.coreViewModel, + this, + ); + this.settingsPageViewModel = new SettingsPageViewModel( + this.coreViewModel, + this, + ); - // handlers - chatModel.chatMessageHandlerManager.setHandler( - this.chatModel.id, - (chatMessage: ChatMessage) => { - this.messagePageViewModel.showChatMessage(chatMessage); - this.updateReadStatus(); + // handlers + chatModel.chatMessageHandlerManager.setHandler( + this.chatModel.id, + (chatMessage: ChatMessage) => { + this.messagePageViewModel.showChatMessage(chatMessage); + this.updateReadStatus(); - this.notificationViewModel.showNotification(chatMessage); - }, - ); - chatModel.reactionHandlerManager.setHandler( - this.chatModel.id, - (reaction: ChatMessageReaction) => { - this.messagePageViewModel.handleReaction(reaction); - }, - ); - chatModel.changeHandlerManager.setHandler(this.chatModel.id, this.settingsPageViewModel.updateData); + this.notificationViewModel.showNotification(chatMessage); + }, + ); + chatModel.reactionHandlerManager.setHandler( + this.chatModel.id, + (reaction: ChatMessageReaction) => { + this.messagePageViewModel.handleReaction(reaction); + }, + ); + chatModel.changeHandlerManager.setHandler( + this.chatModel.id, + this.settingsPageViewModel.updateData, + ); - // load - this.loadPageSelection(); - this.resetColor(); - this.loadInfo(); - this.subscribeReadStatus(); + // load + this.loadPageSelection(); + this.resetColor(); + this.loadInfo(); + this.subscribeReadStatus(); - // keystrokes - this.registerKeyStroke(CommonKeys.Home, this.close); - this.registerKeyStroke("u", () => - this.openPage(ChatPageTypes.Messages), - ); - this.registerKeyStroke("i", () => this.openPage(ChatPageTypes.Tasks)); - this.registerKeyStroke("o", () => - this.openPage(ChatPageTypes.Calendar), - ); - this.registerKeyStroke(CommonKeys.Settings, () => - this.openPage(ChatPageTypes.Settings), - ); + // keystrokes + this.registerKeyStroke(CommonKeys.Home, this.close); + this.registerKeyStroke("u", () => + this.openPage(ChatPageTypes.Messages), + ); + this.registerKeyStroke("i", () => this.openPage(ChatPageTypes.Tasks)); + this.registerKeyStroke("o", () => + this.openPage(ChatPageTypes.Calendar), + ); + this.registerKeyStroke(CommonKeys.Settings, () => + this.openPage(ChatPageTypes.Settings), + ); - // context - this.chatListViewModel.selectedChat.subscribeSilent( - this.updateContexts, - ); - this.selectedPage.subscribeSilent(this.updateContexts); + // context + this.chatListViewModel.selectedChat.subscribeSilent( + this.updateContexts, + ); + this.selectedPage.subscribeSilent(this.updateContexts); } } // types export enum ChatPageTypes { Settings = "settings", - Messages = "messages", - Tasks = "tasks", - Calendar = "calendar", + Messages = "messages", + Tasks = "tasks", + Calendar = "calendar", } diff --git a/src/ViewModel/Global/coreViewModel.ts b/src/ViewModel/Global/coreViewModel.ts index 45ad00cd..7d20d8db 100644 --- a/src/ViewModel/Global/coreViewModel.ts +++ b/src/ViewModel/Global/coreViewModel.ts @@ -9,13 +9,19 @@ import ConnectionModel from "../../Model/Global/connectionModel"; import ChatListModel from "../../Model/Chat/chatListModel"; export default class CoreViewModel { - swRegistration: ServiceWorkerRegistration|undefined = undefined; + swRegistration: ServiceWorkerRegistration | undefined = undefined; - version: React.State = new React.State(""); - latestVersion: React.State = new React.State(""); - noUpdateAvailable: React.State = React.createProxyState([this.latestVersion], () => { - return (this.latestVersion.value == "" || this.latestVersion.value == this.version.value) - }) + version: React.State = new React.State(""); + latestVersion: React.State = new React.State(""); + noUpdateAvailable: React.State = React.createProxyState( + [this.latestVersion], + () => { + return ( + this.latestVersion.value == "" || + this.latestVersion.value == this.version.value + ); + }, + ); updateText: React.State = new React.State(""); translations: Translations; @@ -82,11 +88,11 @@ export default class CoreViewModel { }; handleChron = (): void => { - const newDate = new Date(); - if (this.unwrappedTodayDate.toDateString() != newDate.toDateString()) - this.todayDate.value = new Date(); - if (formatTime(newDate) != this.time.value) - this.time.value = formatTime(newDate); + const newDate = new Date(); + if (this.unwrappedTodayDate.toDateString() != newDate.toDateString()) + this.todayDate.value = new Date(); + if (formatTime(newDate) != this.time.value) + this.time.value = formatTime(newDate); }; // DRAG & DROP @@ -94,75 +100,79 @@ export default class CoreViewModel { // OFFLINE MODE & UPDATE configureServiceWorker = async (): Promise => { - if ("serviceWorker" in navigator) { - try { - this.swRegistration = await navigator.serviceWorker.register( - "sw.js", - { - scope: "/", - }, - ); - if (this.swRegistration.active) { - console.log("Service worker active"); - } - } catch (error) { - console.error(`Could not install service worker: ${error}`); - } - } - } + if ("serviceWorker" in navigator) { + try { + this.swRegistration = await navigator.serviceWorker.register( + "sw.js", + { + scope: "/", + }, + ); + if (this.swRegistration.active) { + console.log("Service worker active"); + } + } catch (error) { + console.error(`Could not install service worker: ${error}`); + } + } + }; checkUpdates = (): void => { - fetch("/version").then(async response => { - this.version.value = await response.text(); - }); - fetch("/latestVersion").then(async response => { - this.latestVersion.value = (await response.text()).replace("\n", ""); - }) - } + fetch("/version").then(async (response) => { + this.version.value = await response.text(); + }); + fetch("/latestVersion").then(async (response) => { + this.latestVersion.value = (await response.text()).replace( + "\n", + "", + ); + }); + }; update = async (): Promise => { - if (!this.swRegistration) return; - await this.swRegistration.update(); - setTimeout(()=>{ - window.location.reload(); - }, 500); - } + if (!this.swRegistration) return; + await this.swRegistration.update(); + setTimeout(() => { + window.location.reload(); + }, 500); + }; // init constructor( - public readonly storageModel: StorageModel, - public readonly settingsModel: SettingsModel, - public readonly connectionModel: ConnectionModel, - public readonly chatListModel: ChatListModel, - public readonly fileTransferModel: FileTransferModel, + public readonly storageModel: StorageModel, + public readonly settingsModel: SettingsModel, + public readonly connectionModel: ConnectionModel, + public readonly chatListModel: ChatListModel, + public readonly fileTransferModel: FileTransferModel, ) { - this.translations = - allTranslations[settingsModel.language] || allTranslations.en; + this.translations = + allTranslations[settingsModel.language] || allTranslations.en; - this.latestVersion.subscribe(latestVersion => { - this.updateText.value = this.translations.homePage.updateButton(latestVersion); - }); + this.latestVersion.subscribe((latestVersion) => { + this.updateText.value = + this.translations.homePage.updateButton(latestVersion); + }); - document.body.addEventListener("keydown", this.handleKeyDown); + document.body.addEventListener("keydown", this.handleKeyDown); - window.onpopstate = () => { - if (!this.context) return; - this.closeContext(this.context.contextId, true); - }; + window.onpopstate = () => { + if (!this.context) return; + this.closeContext(this.context.contextId, true); + }; - this.configureServiceWorker(); - this.checkUpdates(); + this.configureServiceWorker(); + this.checkUpdates(); - this.startChron(); - this.chronHandlerManager.setHandler( - "core-view-model", - this.handleChron, - ); + this.startChron(); + this.chronHandlerManager.setHandler( + "core-view-model", + this.handleChron, + ); } // util static checkIsKeystroke(e: KeyboardEvent): boolean { - return (e.metaKey || e.altKey) && e.ctrlKey; + return (e.metaKey || e.altKey) && e.ctrlKey; } } @@ -171,19 +181,19 @@ export class Context { keystrokes = new Map void>(); handleKeystroke = (e: KeyboardEvent): boolean => { - const fn: (() => void) | undefined = this.keystrokes.get( - e.key.toLowerCase(), - ); - if (!fn) return false; - fn(); - return true; + const fn: (() => void) | undefined = this.keystrokes.get( + e.key.toLowerCase(), + ); + if (!fn) return false; + fn(); + return true; }; close = (): void => {}; handleContextClose = (fromHistoryEvent: boolean): void => {}; registerKeyStroke = (key: string, fn: () => void): void => { - this.keystrokes.set(key, fn); + this.keystrokes.set(key, fn); }; constructor(public contextDebugDescription: string) {} @@ -194,45 +204,45 @@ export class ContextHost extends Context { currentContext = new React.State(undefined); get isOpen(): boolean { - return false; + return false; } get contextSelection(): T | undefined { - return undefined; + return undefined; } registerContext = (key: T, context: Context): void => { - this.contexts.set(key, context); + this.contexts.set(key, context); }; closeCurrentContext = (): void => { - if (this.currentContext.value) { - this.coreViewModel.closeContext( - this.currentContext.value.contextId, - ); - } - this.currentContext.value = undefined; + if (this.currentContext.value) { + this.coreViewModel.closeContext( + this.currentContext.value.contextId, + ); + } + this.currentContext.value = undefined; }; updateContexts = (): void => { - if (this.isOpen == false) return; + if (this.isOpen == false) return; - const selection = this.contextSelection; - if (!selection) return; - const selectedContext: Context | undefined = - this.contexts.get(selection); - if (!selectedContext) return; - if (selectedContext != this.currentContext.value) { - this.closeCurrentContext(); - } + const selection = this.contextSelection; + if (!selection) return; + const selectedContext: Context | undefined = + this.contexts.get(selection); + if (!selectedContext) return; + if (selectedContext != this.currentContext.value) { + this.closeCurrentContext(); + } - this.coreViewModel.context = selectedContext; - this.currentContext.value = selectedContext; + this.coreViewModel.context = selectedContext; + this.currentContext.value = selectedContext; }; constructor( - contextDebugDescription: string, - public coreViewModel: CoreViewModel, + contextDebugDescription: string, + public coreViewModel: CoreViewModel, ) { - super(contextDebugDescription); + super(contextDebugDescription); } } diff --git a/src/ViewModel/Global/fileTransferViewModel.ts b/src/ViewModel/Global/fileTransferViewModel.ts index 8d883412..59a4d422 100644 --- a/src/ViewModel/Global/fileTransferViewModel.ts +++ b/src/ViewModel/Global/fileTransferViewModel.ts @@ -1,13 +1,13 @@ import CoreViewModel, { Context } from "./coreViewModel"; import * as React from "../../react"; import { CommonKeys } from "../../View/keystrokes"; +import { formatISO } from "../../Model/Utility/utility"; import StorageModel, { StorageModelSubPaths, filePaths, } from "../../Model/Global/storageModel"; import { TransferData } from "../../Model/Global/fileTransferModel"; import ChatModel from "../../Model/Chat/chatModel"; -import {formatISO} from "../../Model/Utility/utility"; export default class FileTransferViewModel extends Context { // state @@ -143,7 +143,7 @@ export default class FileTransferViewModel extends Context { downloadFile = async (): Promise => { if (this.cannotExport.value == true) return; - const date = formatISO(new Date()); + const date = formatISO(new Date()); const backup: Blob = await this.coreViewModel.fileTransferModel.generateBackup( diff --git a/src/ViewModel/Global/notificationViewModel.ts b/src/ViewModel/Global/notificationViewModel.ts index b08f3a2d..6adec03e 100644 --- a/src/ViewModel/Global/notificationViewModel.ts +++ b/src/ViewModel/Global/notificationViewModel.ts @@ -16,11 +16,9 @@ export default class NotificationViewModel { if (this.seenMessageIds.has(message.id)) return; if (this.chatListViewModel.selectedChat.value == undefined) return; - const notification: Notification = - this.createNotification(message); + const notification: Notification = this.createNotification(message); const currentChat = - this.chatListViewModel.selectedChat.value.chatModel - .id; + this.chatListViewModel.selectedChat.value.chatModel.id; const currentPage = this.chatListViewModel.selectedChat.value.selectedPage.value; if ( @@ -39,10 +37,7 @@ export default class NotificationViewModel { const chat = [ ...this.chatListViewModel.chatViewModels.value.values(), - ].find( - (chat) => - chat.chatModel.id == notification.fullChannel, - ); + ].find((chat) => chat.chatModel.id == notification.fullChannel); if (!chat) return; chat.open(); chat.openPage(ChatPageTypes.Messages); @@ -86,12 +81,12 @@ export default class NotificationViewModel { // util createNotification(message: ChatMessage): Notification { - const fullChannel = ChatModel.splitChannel(message.channel)[0]; - const chat = this.chatListViewModel.getDisplayName(fullChannel); + const fullChannel = ChatModel.splitChannel(message.channel)[0]; + const chat = this.chatListViewModel.getDisplayName(fullChannel); return { messageId: message.id, chat, - fullChannel, + fullChannel, sender: message.sender, body: message.body, }; diff --git a/src/ViewModel/Global/settingsViewModel.ts b/src/ViewModel/Global/settingsViewModel.ts index 6bfd98e0..4f8f6579 100644 --- a/src/ViewModel/Global/settingsViewModel.ts +++ b/src/ViewModel/Global/settingsViewModel.ts @@ -53,129 +53,129 @@ export default class SettingsViewModel extends Context { // view applyTheme = (): void => { - let theme: string = this.theme.value; - - if (theme == ThemeSettings.System) - theme = SettingsViewModel.getSystemTheme(); + let theme: string = this.theme.value; - switch (theme) { - case ThemeSettings.Dynamic: - const scene = this.selectDynamicScene(); - this.setScene(scene); - break; - case ThemeSettings.Dark: - this.setScene(DynamicSceneNight); - break; - case ThemeSettings.Black: - this.setScene(DynamicSceneBlack); - break; - default: - this.setScene(DynamicSceneDay); - } + if (theme == ThemeSettings.System) + theme = SettingsViewModel.getSystemTheme(); + + switch (theme) { + case ThemeSettings.Dynamic: + const scene = this.selectDynamicScene(); + this.setScene(scene); + break; + case ThemeSettings.Dark: + this.setScene(DynamicSceneNight); + break; + case ThemeSettings.Black: + this.setScene(DynamicSceneBlack); + break; + default: + this.setScene(DynamicSceneDay); + } }; selectDynamicScene = (): DynamicScene => { - let hour = new Date().getHours(); + let hour = new Date().getHours(); - if (hour >= 21 || hour <= 6) { - return DynamicSceneNight; - } else if (hour > 6 && hour < 10) { - return DynamicSceneSunrise; - } else if (hour < 14) { - return DynamicSceneDay; - } else if (hour < 17) { - return DynamicSceneAfternoon; - } else { - return DynamicSceneSunset; - } + if (hour >= 21 || hour <= 6) { + return DynamicSceneNight; + } else if (hour > 6 && hour < 10) { + return DynamicSceneSunrise; + } else if (hour < 14) { + return DynamicSceneDay; + } else if (hour < 17) { + return DynamicSceneAfternoon; + } else { + return DynamicSceneSunset; + } }; setScene = (scene: DynamicScene): void => { - document.body.style.setProperty( - "--backdrop-grass-filter", - `brightness(${scene.brightness})`, - ); + document.body.style.setProperty( + "--backdrop-grass-filter", + `brightness(${scene.brightness})`, + ); - function setSkyColor( - tone: 1 | 2, - hue: number, - saturation: number, - luma: number, - ) { - document.body.style.setProperty( - `--sky-${tone}`, - `hsl(${hue}, ${saturation}%, ${luma}%)`, - ); - } - setSkyColor(1, scene.hue1, scene.saturation, scene.luma); - setSkyColor(2, scene.hue2, scene.saturation - 10, scene.luma - 10); + function setSkyColor( + tone: 1 | 2, + hue: number, + saturation: number, + luma: number, + ) { + document.body.style.setProperty( + `--sky-${tone}`, + `hsl(${hue}, ${saturation}%, ${luma}%)`, + ); + } + setSkyColor(1, scene.hue1, scene.saturation, scene.luma); + setSkyColor(2, scene.hue2, scene.saturation - 10, scene.luma - 10); - document.body.setAttribute("theme", scene.baseTheme); + document.body.setAttribute("theme", scene.baseTheme); }; // exit close = (): void => { - this.coreViewModel.closeContext(this.contextId); + this.coreViewModel.closeContext(this.contextId); }; handleContextClose = (): void => { - this.isShowingSettingsModal.value = false; - if (this.requiresReload.value == true) { - window.location.reload(); - } + this.isShowingSettingsModal.value = false; + if (this.requiresReload.value == true) { + window.location.reload(); + } }; // init constructor(public readonly coreViewModel: CoreViewModel) { - super("settings"); + super("settings"); - this.username.value = coreViewModel.settingsModel.username; - this.usernameInput.value = coreViewModel.settingsModel.username; - this.firstDayOfWeek.value = coreViewModel.settingsModel.firstDayOfWeek; - this.language.value = coreViewModel.settingsModel.language; - this.theme.value = coreViewModel.settingsModel.theme; + this.username.value = coreViewModel.settingsModel.username; + this.usernameInput.value = coreViewModel.settingsModel.username; + this.firstDayOfWeek.value = coreViewModel.settingsModel.firstDayOfWeek; + this.language.value = coreViewModel.settingsModel.language; + this.theme.value = coreViewModel.settingsModel.theme; - // subscriptions - this.firstDayOfWeek.subscribe(this.setFirstDayofWeek); - this.language.subscribeSilent((newValue) => { - this.coreViewModel.settingsModel.setLanguage(newValue); - this.requiresReload.value = true; - }); - this.theme.subscribeSilent((newValue) => { - this.coreViewModel.settingsModel.setTheme(newValue); - }); + // subscriptions + this.firstDayOfWeek.subscribe(this.setFirstDayofWeek); + this.language.subscribeSilent((newValue) => { + this.coreViewModel.settingsModel.setLanguage(newValue); + this.requiresReload.value = true; + }); + this.theme.subscribeSilent((newValue) => { + this.coreViewModel.settingsModel.setTheme(newValue); + }); - // set theme - this.theme.subscribe(() => { - this.applyTheme(); - }); - SettingsViewModel.generateThemeMedia().addEventListener("change", () => - this.applyTheme(), - ); - const seconds = new Date().getSeconds(); - const secondsUntilNewMinute = 60 - seconds; - setTimeout(() => { - setInterval(this.applyTheme, 1000 * 60); - }, secondsUntilNewMinute); + // set theme + this.theme.subscribe(() => { + this.applyTheme(); + }); + SettingsViewModel.generateThemeMedia().addEventListener("change", () => + this.applyTheme(), + ); + const seconds = new Date().getSeconds(); + const secondsUntilNewMinute = 60 - seconds; + setTimeout(() => { + setInterval(this.applyTheme, 1000 * 60); + }, secondsUntilNewMinute); - // keystrokes - this.registerKeyStroke(CommonKeys.CloseOrCancel, this.close); + // keystrokes + this.registerKeyStroke(CommonKeys.CloseOrCancel, this.close); } static generateThemeMedia(): MediaQueryList { - return window.matchMedia("(prefers-color-scheme: dark)"); + return window.matchMedia("(prefers-color-scheme: dark)"); } static getSystemTheme(): string { - const media = SettingsViewModel.generateThemeMedia(); - return media.matches == true ? ThemeSettings.Dark : ThemeSettings.Light; + const media = SettingsViewModel.generateThemeMedia(); + return media.matches == true ? ThemeSettings.Dark : ThemeSettings.Light; } } export enum SettingsModalPages { Appearance, - Regional, - Info, + Regional, + Info, } export interface DynamicScene { diff --git a/src/ViewModel/Global/storageViewModel.ts b/src/ViewModel/Global/storageViewModel.ts index b5f10db4..452e4d51 100644 --- a/src/ViewModel/Global/storageViewModel.ts +++ b/src/ViewModel/Global/storageViewModel.ts @@ -50,15 +50,17 @@ export default class StorageViewModel extends Context { }; calculateUsage = (): void => { - this.occupiedSpaceMB.value = this.coreViewModel.storageModel.calculateUsage(); - this.maximumSpaceMB.value = this.coreViewModel.storageModel.determineCapacity(); - } + this.occupiedSpaceMB.value = + this.coreViewModel.storageModel.calculateUsage(); + this.maximumSpaceMB.value = + this.coreViewModel.storageModel.determineCapacity(); + }; // view showStorageModal = (): void => { this.coreViewModel.context = this; this.isShowingStorageModal.value = true; - this.calculateUsage(); + this.calculateUsage(); }; // exit diff --git a/src/ViewModel/Pages/boardViewModel.ts b/src/ViewModel/Pages/boardViewModel.ts index cb49edd6..0eb1f3e9 100644 --- a/src/ViewModel/Pages/boardViewModel.ts +++ b/src/ViewModel/Pages/boardViewModel.ts @@ -7,11 +7,11 @@ import ChatViewModel, { ChatPageTypes } from "../Chat/chatViewModel"; import * as React from "../../react"; import { Colors } from "../../colors"; import { CommonKeys } from "../../View/keystrokes"; +import { PinchToZoomData } from "../../Model/Utility/utility"; import BoardsAndTasksModel, { BoardInfoFileContent, TaskFileContent, } from "../../Model/Files/boardsAndTasksModel"; -import {PinchToZoomData} from "../../Model/Utility/utility"; export default class BoardViewModel extends TaskContainingPageViewModel { // state @@ -34,7 +34,11 @@ export default class BoardViewModel extends TaskContainingPageViewModel { new React.ListState(); isFilterActive: React.State; - pinchToZoomData: React.State = new React.State({zoom: 1, x: 0, y: 0}); + pinchToZoomData: React.State = new React.State({ + zoom: 1, + x: 0, + y: 0, + }); // paths getBasePath = (): string[] => { diff --git a/src/ViewModel/Pages/calendarPageViewModel.ts b/src/ViewModel/Pages/calendarPageViewModel.ts index eb2e71c0..73d24324 100644 --- a/src/ViewModel/Pages/calendarPageViewModel.ts +++ b/src/ViewModel/Pages/calendarPageViewModel.ts @@ -4,11 +4,19 @@ import CoreViewModel from "../Global/coreViewModel"; import ChatViewModel, { ChatPageTypes } from "../Chat/chatViewModel"; import * as React from "../../react"; import { CommonKeys } from "../../View/keystrokes"; +import { + formatISO, + formatISOFromParts, + formatMonthStringFromParts, + formatTime, + isoToDateString, + isoToMonthString, + padZero, +} from "../../Model/Utility/utility"; import CalendarModel, { MonthGrid } from "../../Model/Files/calendarModel"; import BoardsAndTasksModel, { TaskFileContent, } from "../../Model/Files/boardsAndTasksModel"; -import {formatISO, formatISOFromParts, formatMonthStringFromParts, formatTime, isoToDateString, isoToMonthString, padZero} from "../../Model/Utility/utility"; export const CALENDAR_EVENT_BOARD_ID = "events"; @@ -22,7 +30,11 @@ export default class CalendarPageViewModel extends TaskContainingPageViewModel { } get selectedDateString(): string { - return formatISOFromParts(this.selectedYear.value, this.selectedMonth.value, this.selectedDate.value); + return formatISOFromParts( + this.selectedYear.value, + this.selectedMonth.value, + this.selectedDate.value, + ); } // paths @@ -39,8 +51,8 @@ export default class CalendarPageViewModel extends TaskContainingPageViewModel { monthGrid: React.State< MonthGrid> | undefined > = new React.State(undefined); - - nextTask = new React.State(undefined); + + nextTask = new React.State(undefined); // methods createEvent = (): void => { @@ -65,9 +77,7 @@ export default class CalendarPageViewModel extends TaskContainingPageViewModel { }; getEventsForDate = (): React.MapState | undefined => { - const paddedDate: string = padZero( - this.selectedDate.toString(), 2 - ); + const paddedDate: string = padZero(this.selectedDate.toString(), 2); if (this.monthGrid.value == undefined) { return undefined; @@ -82,9 +92,7 @@ export default class CalendarPageViewModel extends TaskContainingPageViewModel { ): React.MapState | null => { if (this.monthGrid.value == null) return null; - const date: string = isoToDateString( - taskFileContent.date ?? "", - ); + const date: string = isoToDateString(taskFileContent.date ?? ""); return this.monthGrid.value.days[date]; }; @@ -152,11 +160,7 @@ export default class CalendarPageViewModel extends TaskContainingPageViewModel { }; handleDrop = (year: string, month: string, date: string): void => { - const ISOString: string = formatISOFromParts( - year, - month, - date, - ); + const ISOString: string = formatISOFromParts(year, month, date); const draggedObject: any = this.coreViewModel.draggedObject.value; if (draggedObject instanceof TaskViewModel == false) return; @@ -165,37 +169,34 @@ export default class CalendarPageViewModel extends TaskContainingPageViewModel { }; handleChron = (): void => { - this.updateMonthGrid(); - this.updateNextTask(); - } + this.updateMonthGrid(); + this.updateNextTask(); + }; updateMonthGrid = (): void => { - const today = formatISO(this.coreViewModel.todayDate.value) - if ( - this.currentTodayDate == today - ) - return; + const today = formatISO(this.coreViewModel.todayDate.value); + if (this.currentTodayDate == today) return; this.loadMonthTasks(); this.currentTodayDate = today; - this.selectedDate.callSubscriptions(); + this.selectedDate.callSubscriptions(); }; updateNextTask = (): void => { - if (this.selectedDateString != this.currentTodayDate) { - this.nextTask.value = undefined; - return; - } + if (this.selectedDateString != this.currentTodayDate) { + this.nextTask.value = undefined; + return; + } - const tasks = this.getEventsForDate(); - if (tasks == undefined) return; - const taskArray =[...tasks.value.values()]; - const sorted = taskArray.sort((a, b) => a.index.value - b.index.value); - for (const task of sorted) { - if (task.time.value <= this.coreViewModel.time.value) continue; - this.nextTask.value = task; - break; - }; - } + const tasks = this.getEventsForDate(); + if (tasks == undefined) return; + const taskArray = [...tasks.value.values()]; + const sorted = taskArray.sort((a, b) => a.index.value - b.index.value); + for (const task of sorted) { + if (task.time.value <= this.coreViewModel.time.value) continue; + this.nextTask.value = task; + break; + } + }; // load loadMonthTasks = (): void => { @@ -217,8 +218,7 @@ export default class CalendarPageViewModel extends TaskContainingPageViewModel { } }; - loadData = (): void => { - }; + loadData = (): void => {}; // init constructor( @@ -237,9 +237,9 @@ export default class CalendarPageViewModel extends TaskContainingPageViewModel { React.bulkSubscribe([this.selectedYear, this.selectedMonth], () => { this.loadMonthTasks(); }); - this.selectedDate.subscribeSilent(()=>{ - this.updateNextTask(); - }) + this.selectedDate.subscribeSilent(() => { + this.updateNextTask(); + }); // handlers boardsAndTasksModel.taskHandlerManager.setHandler( diff --git a/src/ViewModel/Pages/messagePageViewModel.ts b/src/ViewModel/Pages/messagePageViewModel.ts index ed8a7f12..29eb2913 100644 --- a/src/ViewModel/Pages/messagePageViewModel.ts +++ b/src/ViewModel/Pages/messagePageViewModel.ts @@ -16,9 +16,17 @@ export default class MessagePageViewModel extends Context { new React.MapState(); filteredMessageViewModels: React.ListState = new React.ListState(); - replyViewSelectedMessage = new React.State(undefined); - isReplyViewActive: React.State = React.createProxyState([this.replyViewSelectedMessage], ()=>this.replyViewSelectedMessage.value != undefined); - isReplyViewInactive = React.createProxyState([this.isReplyViewActive], ()=>!this.isReplyViewActive.value); + replyViewSelectedMessage = new React.State< + ChatMessageViewModel | undefined + >(undefined); + isReplyViewActive: React.State = React.createProxyState( + [this.replyViewSelectedMessage], + () => this.replyViewSelectedMessage.value != undefined, + ); + isReplyViewInactive = React.createProxyState( + [this.isReplyViewActive], + () => !this.isReplyViewActive.value, + ); searchViewModel: SearchViewModel; isFilterModalOpen = new React.State(false); reactionFilter = new React.State(undefined); @@ -39,193 +47,194 @@ export default class MessagePageViewModel extends Context { if (this.cannotSendMessage.value == true) return; const idPromise = this.sendMessageFromBody(this.composingMessage.value); - this.composingMessage.value = ""; + this.composingMessage.value = ""; - const id = await idPromise; - if (id && this.reactionFilter.value != undefined) { - this.sendReaction(id, this.reactionFilter.value, false); - } + const id = await idPromise; + if (id && this.reactionFilter.value != undefined) { + this.sendReaction(id, this.reactionFilter.value, false); + } }; - sendMessageFromBody = (body: string): Promise=> { - let replyId: string | undefined = undefined; - if (this.replyingMessage.value) { - replyId = this.replyingMessage.value.chatMessage.id; - } - const id = this.chatViewModel.chatModel.sendMessage(body, replyId); + sendMessageFromBody = (body: string): Promise => { + let replyId: string | undefined = undefined; + if (this.replyingMessage.value) { + replyId = this.replyingMessage.value.chatMessage.id; + } + const id = this.chatViewModel.chatModel.sendMessage(body, replyId); - if (this.replyViewSelectedMessage.value == undefined) - this.replyingMessage.value = undefined; + if (this.replyViewSelectedMessage.value == undefined) + this.replyingMessage.value = undefined; - return id; + return id; }; decryptMessage = async ( - messageViewModel: ChatMessageViewModel, + messageViewModel: ChatMessageViewModel, ): Promise => { - const chatMessage: ChatMessage = messageViewModel.chatMessage; - await this.chatViewModel.chatModel.decryptMessage(chatMessage); - this.chatViewModel.chatModel.addMessage(chatMessage); - messageViewModel.loadData(); + const chatMessage: ChatMessage = messageViewModel.chatMessage; + await this.chatViewModel.chatModel.decryptMessage(chatMessage); + this.chatViewModel.chatModel.addMessage(chatMessage); + messageViewModel.loadData(); }; sendReaction = ( - messageId: string, - content: ReactionSymbols, - isDeleting: boolean, + messageId: string, + content: ReactionSymbols, + isDeleting: boolean, ): void => { - this.chatViewModel.chatModel.sendReaction( - messageId, - content, - isDeleting, - ); + this.chatViewModel.chatModel.sendReaction( + messageId, + content, + isDeleting, + ); }; setReply = ( - chatMessageViewModel: ChatMessageViewModel | undefined, - setFocus: boolean = true, + chatMessageViewModel: ChatMessageViewModel | undefined, + setFocus: boolean = true, ): void => { - this.replyingMessage.value = chatMessageViewModel; - if (setFocus == false || chatMessageViewModel == undefined) return; - this.setFocus(); + this.replyingMessage.value = chatMessageViewModel; + if (setFocus == false || chatMessageViewModel == undefined) return; + this.setFocus(); }; resetReply = (setFocus: boolean = true): void => { - this.replyingMessage.value = undefined; - if (setFocus == false) return; - this.setFocus(); + this.replyingMessage.value = undefined; + if (setFocus == false) return; + this.setFocus(); }; // view showChatMessage = (chatMessage: ChatMessage): void => { - const chatMessageViewModel = new ChatMessageViewModel( - this.coreViewModel, - this, - chatMessage, - chatMessage.sender == - this.chatViewModel.settingsViewModel.username.value, - ); + const chatMessageViewModel = new ChatMessageViewModel( + this.coreViewModel, + this, + chatMessage, + chatMessage.sender == + this.chatViewModel.settingsViewModel.username.value, + ); - const existingChatMessageViewModel: ChatMessageViewModel | undefined = - this.chatMessageViewModels.value.get(chatMessage.id); - if (existingChatMessageViewModel != undefined) { - existingChatMessageViewModel.body.value = chatMessage.body; - existingChatMessageViewModel.status.value = chatMessage.status; - } else { - this.chatMessageViewModels.set( - chatMessage.id, - chatMessageViewModel, - ); - } + const existingChatMessageViewModel: ChatMessageViewModel | undefined = + this.chatMessageViewModels.value.get(chatMessage.id); + if (existingChatMessageViewModel != undefined) { + existingChatMessageViewModel.body.value = chatMessage.body; + existingChatMessageViewModel.status.value = chatMessage.status; + } else { + this.chatMessageViewModels.set( + chatMessage.id, + chatMessageViewModel, + ); + } }; handleReaction = (reaction: ChatMessageReaction): void => { - const messageViewModel: ChatMessageViewModel | undefined = - this.chatMessageViewModels.value.get(reaction.messageId); - if (messageViewModel == undefined) return; - messageViewModel.handleReaction(reaction); + const messageViewModel: ChatMessageViewModel | undefined = + this.chatMessageViewModels.value.get(reaction.messageId); + if (messageViewModel == undefined) return; + messageViewModel.handleReaction(reaction); }; showFilterModal = (): void => { - this.isFilterModalOpen.value = true; + this.isFilterModalOpen.value = true; }; hideFilterModal = (): void => { - this.isFilterModalOpen.value = false; + this.isFilterModalOpen.value = false; }; revokeReactionFilter = (persist: boolean = true): void => { - this.reactionFilter.value = undefined; - if (persist) this.chatViewModel.chatModel.storeFilter(""); + this.reactionFilter.value = undefined; + if (persist) this.chatViewModel.chatModel.storeFilter(""); }; setReactionFilter = (content: ReactionSymbols): void => { - this.reactionFilter.value = content; - this.chatViewModel.chatModel.storeFilter(content); + this.reactionFilter.value = content; + this.chatViewModel.chatModel.storeFilter(content); }; resetFilter = (): void => { - this.revokeReactionFilter(); - this.searchViewModel.search(""); + this.revokeReactionFilter(); + this.searchViewModel.search(""); }; setReplyView = (message: ChatMessageViewModel): void => { - this.replyViewSelectedMessage.value = message; - this.revokeReactionFilter(false); - this.setReply(message, false); - } + this.replyViewSelectedMessage.value = message; + this.revokeReactionFilter(false); + this.setReply(message, false); + }; resetReplyView = (): void => { - this.replyViewSelectedMessage.value = undefined; - this.resetReply(false); - this.restoreFilter(); - } + this.replyViewSelectedMessage.value = undefined; + this.resetReply(false); + this.restoreFilter(); + }; setFocus = (): void => { - this.focusSetter.callSubscriptions(); + this.focusSetter.callSubscriptions(); }; // load loadData = (): void => { - this.chatMessageViewModels.clear(); - for (const chatMessage of this.chatViewModel.chatModel.messages) { - this.showChatMessage(chatMessage); - } - for (const reaction of this.chatViewModel.chatModel.reactions) { - this.handleReaction(reaction); - } + this.chatMessageViewModels.clear(); + for (const chatMessage of this.chatViewModel.chatModel.messages) { + this.showChatMessage(chatMessage); + } + for (const reaction of this.chatViewModel.chatModel.reactions) { + this.handleReaction(reaction); + } }; restoreFilter = (): void => { - const previousFilter = this.chatViewModel.chatModel.getFilter() as any; - if (Object.values(ReactionSymbols).includes(previousFilter)) this.setReactionFilter(previousFilter); - } + const previousFilter = this.chatViewModel.chatModel.getFilter() as any; + if (Object.values(ReactionSymbols).includes(previousFilter)) + this.setReactionFilter(previousFilter); + }; // init constructor( - public readonly coreViewModel: CoreViewModel, - public readonly chatViewModel: ChatViewModel, + public readonly coreViewModel: CoreViewModel, + public readonly chatViewModel: ChatViewModel, ) { - super("message-page"); - this.restoreFilter(); + super("message-page"); + this.restoreFilter(); - // states - this.cannotSendMessage = React.createProxyState( - [ - this.chatViewModel.settingsViewModel.username, - this.composingMessage, - ], - () => - this.chatViewModel.settingsViewModel.username.value == "" || - this.composingMessage.value == "", - ); + // states + this.cannotSendMessage = React.createProxyState( + [ + this.chatViewModel.settingsViewModel.username, + this.composingMessage, + ], + () => + this.chatViewModel.settingsViewModel.username.value == "" || + this.composingMessage.value == "", + ); - this.searchViewModel = new SearchViewModel( - this.chatMessageViewModels, - this.filteredMessageViewModels, - (chatMessageViewModel) => [chatMessageViewModel.body.value], - new React.ListState(), - ); + this.searchViewModel = new SearchViewModel( + this.chatMessageViewModels, + this.filteredMessageViewModels, + (chatMessageViewModel) => [chatMessageViewModel.body.value], + new React.ListState(), + ); - this.isFilterActive = React.createProxyState( - [this.searchViewModel.appliedQuery, this.reactionFilter], - () => - this.searchViewModel.appliedQuery.value != "" || - this.reactionFilter.value != undefined, - ); + this.isFilterActive = React.createProxyState( + [this.searchViewModel.appliedQuery, this.reactionFilter], + () => + this.searchViewModel.appliedQuery.value != "" || + this.reactionFilter.value != undefined, + ); - // keystrokes - this.registerKeyStroke(CommonKeys.Filter, this.showFilterModal); - this.registerKeyStroke(CommonKeys.CloseOrCancel, () => { - if (this.isFilterModalOpen.value == true) { - this.hideFilterModal(); - } else { - this.replyingMessage.value = undefined; - } - }); - this.registerKeyStroke(CommonKeys.Reset, this.resetFilter); - this.registerKeyStroke(CommonKeys.Create, this.setFocus); + // keystrokes + this.registerKeyStroke(CommonKeys.Filter, this.showFilterModal); + this.registerKeyStroke(CommonKeys.CloseOrCancel, () => { + if (this.isFilterModalOpen.value == true) { + this.hideFilterModal(); + } else { + this.replyingMessage.value = undefined; + } + }); + this.registerKeyStroke(CommonKeys.Reset, this.resetFilter); + this.registerKeyStroke(CommonKeys.Create, this.setFocus); - this.chatViewModel.registerContext(ChatPageTypes.Messages, this); + this.chatViewModel.registerContext(ChatPageTypes.Messages, this); } } diff --git a/src/ViewModel/Pages/settingsPageViewModel.ts b/src/ViewModel/Pages/settingsPageViewModel.ts index c93d2d32..12eccd14 100644 --- a/src/ViewModel/Pages/settingsPageViewModel.ts +++ b/src/ViewModel/Pages/settingsPageViewModel.ts @@ -30,8 +30,7 @@ export default class SettingsPageViewModel extends Context { ); cannotSetColor: React.State = React.createProxyState( [this.color, this.appliedColor], - () => - this.color.value == this.appliedColor.value, + () => this.color.value == this.appliedColor.value, ); cannotAddSecondaryChannel: React.State = React.createProxyState( [this.newSecondaryChannelInput], @@ -41,11 +40,8 @@ export default class SettingsPageViewModel extends Context { // methods setName = (): void => { - this.chatViewModel.chatModel.setName( - this.nameInput.value, - ); - this.name.value = - this.chatViewModel.chatModel.info.name; + this.chatViewModel.chatModel.setName(this.nameInput.value); + this.name.value = this.chatViewModel.chatModel.info.name; this.chatViewModel.chatListViewModel.updateIndices(); }; @@ -79,7 +75,7 @@ export default class SettingsPageViewModel extends Context { applyColor = (): void => { this.chatViewModel.setColor(this.color.value); - this.appliedColor.value = this.color.value; + this.appliedColor.value = this.color.value; }; remove = (): void => { @@ -90,18 +86,17 @@ export default class SettingsPageViewModel extends Context { // load preloadData = (): void => { - this.name.value = - this.chatViewModel.chatModel.info.name; - + this.name.value = this.chatViewModel.chatModel.info.name; + this.color.value = this.chatViewModel.chatModel.color; - this.appliedColor.value = this.color.value; + this.appliedColor.value = this.color.value; }; updateData = (): void => { - this.preloadData(); - this.nameInput.value = this.name.value; - this.chatViewModel.resetColor(); - } + this.preloadData(); + this.nameInput.value = this.name.value; + this.chatViewModel.resetColor(); + }; loadData = (): void => { this.nameInput.value = this.name.value; diff --git a/src/ViewModel/Pages/taskPageViewModel.ts b/src/ViewModel/Pages/taskPageViewModel.ts index d45d7df8..337323cd 100644 --- a/src/ViewModel/Pages/taskPageViewModel.ts +++ b/src/ViewModel/Pages/taskPageViewModel.ts @@ -178,8 +178,13 @@ export default class TaskPageViewModel extends ContextHost { this.chatViewModel = chatViewModel; - // filter - implementFilter(this.boardViewModels, this.boardMatches, this.boardQuery, (board) => board.name.value); + // filter + implementFilter( + this.boardViewModels, + this.boardMatches, + this.boardQuery, + (board) => board.name.value, + ); // context this.chatViewModel.registerContext(ChatPageTypes.Tasks, this); diff --git a/src/ViewModel/Pages/taskViewModel.ts b/src/ViewModel/Pages/taskViewModel.ts index f7d80af4..8b8782ee 100644 --- a/src/ViewModel/Pages/taskViewModel.ts +++ b/src/ViewModel/Pages/taskViewModel.ts @@ -1,4 +1,5 @@ import TaskContainingPageViewModel from "./taskContainingPageViewModel"; +import CalendarPageViewModel from "./calendarPageViewModel"; import CoreViewModel, { Context } from "../Global/coreViewModel"; import ChatViewModel from "../Chat/chatViewModel"; import * as React from "../../react"; @@ -8,7 +9,6 @@ import { localeCompare, padZero } from "../../Model/Utility/utility"; import BoardsAndTasksModel, { TaskFileContent, } from "../../Model/Files/boardsAndTasksModel"; -import CalendarPageViewModel from "./calendarPageViewModel"; export default class TaskViewModel extends Context { // util @@ -200,11 +200,11 @@ export default class TaskViewModel extends Context { this.loadTaskData(); this.loadVersionIds(); - if (this.containingViewModel instanceof CalendarPageViewModel) { - this.containingViewModel.nextTask.subscribe((nextTask)=>{ - this.isNotNext.value = nextTask != this; - }) - } + if (this.containingViewModel instanceof CalendarPageViewModel) { + this.containingViewModel.nextTask.subscribe((nextTask) => { + this.isNotNext.value = nextTask != this; + }); + } }; loadTaskData = (): void => { diff --git a/src/base.css b/src/base.css index c85fe579..d8c289bb 100644 --- a/src/base.css +++ b/src/base.css @@ -10,7 +10,7 @@ #background-wrapper { position: fixed; inset: 0px; - + transform: scale(1.2); filter: blur(40px); @@ -41,7 +41,7 @@ main { bottom: -50%; background-image: radial-gradient(var(--sky-1), var(--sky-2)); - + opacity: 0.4; } @@ -113,4 +113,3 @@ body[theme="dark"] #background-wrapper #grass-2 { padding: var(--content-padding); } - diff --git a/src/colors.css b/src/colors.css index 58f3a1b3..6c6fef3a 100644 --- a/src/colors.css +++ b/src/colors.css @@ -80,7 +80,8 @@ body:is([theme="dark"], [theme="black"]) [color]:not([color="standard"]).tile { background: hsl(var(--hue), var(--sat), var(--luma), 40%); } - body:is([theme="dark"], [theme="black"]) [color]:not([color="standard"]).background { + body:is([theme="dark"], [theme="black"]) + [color]:not([color="standard"]).background { --luma: var(--background-luma-dark); } @@ -100,7 +101,8 @@ body [color]:not([color="standard"]).subtle-background { background: hsl(var(--hue), 100%, var(--luma), 40%); } -body:is([theme="dark"], [theme="black"]) [color]:not([color="standard"]).subtle-background { +body:is([theme="dark"], [theme="black"]) + [color]:not([color="standard"]).subtle-background { --luma: var(--subtle-luma-dark); }