From 839e887d859201fd4dc82bacaf0dd42cd76fae3c Mon Sep 17 00:00:00 2001 From: marlon-erler Date: Wed, 9 Sep 2026 00:04:27 +0200 Subject: [PATCH] correct type issues --- dist/index.js | 74 +- src/.index.tsx.swp | Bin 12288 -> 0 bytes src/Model/Chat/chatModel.ts | 10 +- src/Model/Global/fileTransferModel.ts | 5 +- src/Model/Global/settingsModel.ts | 10 +- src/Model/Utility/.crypto.ts.swp | Bin 12288 -> 0 bytes src/Model/Utility/utility.ts | 30 +- src/View/Modals/settingsModal.tsx | 2 +- src/View/Modals/splitModal.tsx | 1 + src/View/translations.ts | 750 +++++++++--------- src/View/viewController.ts | 6 +- src/ViewModel/Chat/chatMessageViewModel.ts | 6 +- src/ViewModel/Chat/chatViewModel.ts | 4 +- src/ViewModel/Global/.coreViewModel.ts.swp | Bin 16384 -> 16384 bytes src/ViewModel/Global/coreViewModel.ts | 17 +- src/ViewModel/Global/fileTransferViewModel.ts | 4 +- src/ViewModel/Global/notificationViewModel.ts | 6 +- src/ViewModel/Global/settingsViewModel.ts | 6 +- src/ViewModel/Global/storageViewModel.ts | 2 +- src/ViewModel/Pages/messagePageViewModel.ts | 2 +- src/ViewModel/Pages/taskPageViewModel.ts | 4 +- src/index.tsx | 1 - src/types/styles.d.ts | 2 + tsconfig.json | 6 +- 24 files changed, 511 insertions(+), 437 deletions(-) delete mode 100644 src/.index.tsx.swp delete mode 100644 src/Model/Utility/.crypto.ts.swp create mode 100644 src/types/styles.d.ts diff --git a/dist/index.js b/dist/index.js index 8645709e..450bf304 100644 --- a/dist/index.js +++ b/dist/index.js @@ -605,9 +605,9 @@ exportHeadline: "Daten exportieren", importHeadline: "Daten importieren", selectionDescription: "W\xE4hle die Daten aus, die du \xFCbertragen m\xF6chtest.", + exportSelectionDescription: "W\xE4hle die Daten aus, die du exportieren m\xF6chtest.", dataEntryDescription: "Gib diese Informationen auf dem anderen Ger\xE4t ein.", dataEntryInputDescription: "Gib die auf dem anderen Ger\xE4t angezeigten Informationen ein.", - notConnectedError: "Du bist mit keinem Server verbunden.", fromThisDeviceButton: "An anderes Ger\xE4t senden", toThisDeviceButton: "An dieses Ger\xE4t senden", exportButton: "Als Datei exportieren", @@ -622,7 +622,13 @@ sendAgainButton: "Erneut senden", filesSentCount: (count) => `Dateien gesendet: ${count}.`, allFilesSent: "Fertig.", - filesReceivedCount: (count) => `Dateien empfangen: ${count}.` + filesReceivedCount: (count) => `Dateien empfangen: ${count}.`, + exportKey: "Schl\xFCssel", + exportKeyConfirmation: "Schl\xFCssel best\xE4tigen", + downloadFileButton: "Herunterladen", + importFileButton: "Importieren", + decryptImportButton: "Entschl\xFCsseln", + incorrectPassphraseError: "Der Schl\xFCssel ist nicht korrekt" }, storage: { noItemSelected: "Kein Element ausgew\xE4hlt", @@ -814,9 +820,9 @@ 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.", - notConnectedError: "No est\xE1s conectado a ning\xFAn servidor.", fromThisDeviceButton: "Enviar a otro dispositivo", toThisDeviceButton: "Enviar a este dispositivo", exportButton: "Exportar archivo", @@ -826,12 +832,18 @@ settingsData: "Datos de Configuraci\xF3n", chatsHeadline: "Chats", transferChannelHeadline: "Canal de Transferencia", - transferKeyHeadline: "Clave de Encriptaci\xF3n de Transferencia", + transferKeyHeadline: "Clave de encriptaci\xF3n de transferencia", sendButton: "Enviar", sendAgainButton: "Enviar otra vez", filesSentCount: (count) => `Archivos enviados: ${count}.`, allFilesSent: "Hecho.", - filesReceivedCount: (count) => `Archivos recibidos: ${count}.` + filesReceivedCount: (count) => `Archivos recibidos: ${count}.`, + exportKey: "Clave de encriptaci\xF3n", + exportKeyConfirmation: "Confirmar clave", + downloadFileButton: "Descargar", + importFileButton: "Importar", + decryptImportButton: "Descifrar", + incorrectPassphraseError: "La clave no es correcta" }, storage: { noItemSelected: "Ning\xFAn elemento seleccionado", @@ -1162,6 +1174,8 @@ const point = (e, direction, i) => e.touches[i][direction == "x" ? "clientX" : "clientY"]; const midpoint = (e, direction) => (point(e, direction, 0) + point(e, direction, 1)) / 2; function apply(factor, _offset) { + const el = element(); + if (!el) return; if (factor < MIN) return apply(MIN, _offset); if (factor > MAX) return apply(5, _offset); let x, y; @@ -1170,7 +1184,7 @@ x = currentX; y = currentY; } - element().style.transform = `scale(${factor.toString()}) translate(${x}px, ${y}px)`; + el.style.transform = `scale(${factor.toString()}) translate(${x}px, ${y}px)`; currentX = x; currentY = y; currentZoom = factor; @@ -1194,8 +1208,10 @@ }); canvas.addEventListener("touchstart", (event) => { document.activeElement.blur(); - if (lastElement != void 0 && lastElement != element()) reset(); - lastElement = element(); + const el = element(); + if (!el) return; + if (lastElement != void 0 && lastElement != el) reset(); + lastElement = el; initialZoom = currentZoom; initialX = currentX; initialY = currentY; @@ -1241,7 +1257,7 @@ this.connectionModel = connectionModel2; this.chatListModel = chatListModel2; this.fileTransferModel = fileTransferModel2; - this.BUILD = "Build 26.09.06.A"; + this.BUILD = "Build 26.09.09.A"; // CONTEXT this.contextStack = /* @__PURE__ */ new Map(); this.closeContext = (contextId, fromHistoryEvent = false) => { @@ -1249,6 +1265,7 @@ return; while (this.contexts.length > 0) { const currentContext = this.context; + if (!currentContext) return; currentContext.handleContextClose(fromHistoryEvent); this.contextStack.delete(currentContext.contextId); if (currentContext.contextId == contextId) break; @@ -1260,7 +1277,7 @@ const contexts = this.contexts; while (contexts.length > 0) { const currentContext = contexts.pop(); - if (!currentContext) contexts; + if (!currentContext) return; const isHandled = currentContext.handleKeystroke(e); if (isHandled == true) break; } @@ -1287,6 +1304,7 @@ this.translations = allTranslations[settingsModel2.language] || allTranslations.en; document.body.addEventListener("keydown", this.handleKeyDown); window.onpopstate = () => { + if (!this.context) return; this.closeContext(this.context.contextId, true); }; this.startChron(); @@ -1337,8 +1355,9 @@ } }; var ContextHost = class extends Context { - constructor() { - super(...arguments); + constructor(contextDebugDescription, coreViewModel2) { + super(contextDebugDescription); + this.coreViewModel = coreViewModel2; this.contexts = /* @__PURE__ */ new Map(); this.currentContext = new State(void 0); this.registerContext = (key, context) => { @@ -1354,8 +1373,10 @@ }; this.updateContexts = () => { if (this.isOpen == false) return; + const selection = this.contextSelection; + if (!selection) return; const selectedContext = this.contexts.get( - this.contextSelection + selection ); if (!selectedContext) return; if (selectedContext != this.currentContext.value) { @@ -1657,6 +1678,11 @@ var SettingsModel = class _SettingsModel { // init constructor(storageModel2) { + // data + this.username = ""; + this.firstDayOfWeek = ""; + this.language = ""; + this.theme = ""; // storage this.storeSetting = (pathName, value) => { const path = StorageModel.getPath( @@ -1943,6 +1969,7 @@ const input = document.getElementById("file-transfer-input"); if (!input) return; if (!(input instanceof HTMLInputElement)) return; + if (!input.files) return; const file = input.files[0]; this.importedFile.value = file; }; @@ -1953,6 +1980,7 @@ reader.readAsText(file, "utf8"); reader.onload = () => { const result = reader.result; + if (!result) return; this.importedFileString.value = result.toString(); this.showImportDecryptDataModal(); }; @@ -3183,7 +3211,7 @@ var TaskPageViewModel = class extends ContextHost { // init constructor(coreViewModel2, chatViewModel, boardsAndTasksModel) { - super("task-page"); + super("task-page", coreViewModel2); this.coreViewModel = coreViewModel2; this.chatViewModel = chatViewModel; this.boardsAndTasksModel = boardsAndTasksModel; @@ -3508,6 +3536,8 @@ var ChatModel = class _ChatModel { // init constructor(storageModel2, connectionModel2, settingsModel2, chatListModel2, chatId) { + /* load function called in constructor */ + this.color = "standard" /* Standard */; // handler managers this.chatMessageHandlerManager = new HandlerManager(); this.reactionHandlerManager = new HandlerManager(); @@ -3622,7 +3652,7 @@ }; this.sendMessage = async (body, inlineReplyId, fileContent) => { const nameAndChannel = this.getNameAndChannel(); - if (nameAndChannel == false) return; + if (nameAndChannel == false) return false; const [senderName, combinedChannel] = nameAndChannel; const chatMessage = await _ChatModel.createChatMessage( combinedChannel, @@ -3648,10 +3678,10 @@ chatMessage.body = decryptedBody; chatMessage.stringifiedFile = decryptedFile; }; - this.sendReaction = async (messageId, content, isDeleting) => { + this.sendReaction = async (messageId, content, isDeleting = false) => { const nameAndChannel = this.getNameAndChannel(); if (nameAndChannel == false) return; - const [senderName, combinedChannel] = nameAndChannel; + const [senderName] = nameAndChannel; const reaction = _ChatModel.createMessageReaction( messageId, senderName, @@ -3860,6 +3890,9 @@ constructor(coreViewModel2, messagePageViewModel, chatMessage, sentByUser) { this.coreViewModel = coreViewModel2; this.messagePageViewModel = messagePageViewModel; + this.channel = ""; + this.sender = ""; + this.dateSent = ""; this.body = new State(""); this.inlineReply = void 0; this.status = new State( @@ -4314,7 +4347,7 @@ var ChatViewModel6 = class extends ContextHost { // init constructor(coreViewModel2, chatModel, settingsViewModel2, notificationViewModel, connectionViewModel2, chatListViewModel2) { - super("chat"); + super("chat", coreViewModel2); this.coreViewModel = coreViewModel2; this.chatModel = chatModel; this.settingsViewModel = settingsViewModel2; @@ -4498,6 +4531,7 @@ ].find( (chat2) => chat2.chatModel.unwrappedPrimaryChannel == notification.chat ); + if (!chat) return; chat.open(); chat.openPage("messages" /* Messages */); }; @@ -4508,6 +4542,7 @@ return this.stopLoop(); } const notification = this.messagesInMarquee.shift(); + if (!notification) return; this.seenMessageIds.delete(notification.messageId); this.marquee.value = notification; }; @@ -6573,6 +6608,7 @@ // src/View/Modals/splitModal.tsx function SplitModal(coreViewModel2, leftView, rightView, extendedStyle = false, navigationState) { function closePage() { + if (!navigationState) return; navigationState.value = void 0; } const hasPageOpen = new State(false); @@ -7531,6 +7567,7 @@ return transferData; }; this.prepareToSend = () => { + if (!this.transferData) return; this.direction = 0 /* Send */; this.connectionModel.addChannel(this.transferData.channel); }; @@ -7627,6 +7664,7 @@ return stringify(fileData); }; this.sendFile = async (stringifiedFileData) => { + if (!this.transferData) return; const encryptedFileData = await encryptString( stringifiedFileData, this.transferData.key diff --git a/src/.index.tsx.swp b/src/.index.tsx.swp deleted file mode 100644 index 91f0b2a241e862e081933efc54a3c85190646766..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12288 zcmeI2%ZnUE9LIl&@fEWw@t_2R-U-T#W~Z}>kjOrQ?qUpNA#tH}*)~1hYgf;1 z)?^hCeBkS#2OkRx;z{(9gPtOakBguuFM_%U528f!ANZ|)R98P{*MJ~_YWVDAs_OTv zUwwbSs;S*f=iuUrIpe|hLBex8(eEE^Jo(;TchdVdQO}J;>$Z;<*p{~x@a;xF1BWJ$ zg3#(Qb8&WV_JlbT^!wc8p>4Xp!_KuMes0_8^Z>1ZR^VzC7)0H%qa$?q(0IJn_cun3 zJN7PItrtCBE1(t73TOqi0$KsBfL1^&pcS}=6^NF1(6fktXS#-N`nsd^n!eR9S^=$q zRzNGD70?Q31+)TM0j+>mKr5gX&)>F)@OcX z;Au^ecoEM$iz3(W@wvdUyrvz5Y|&+_c*nd022VR>Q|kc5R>Cm(N=Ut3(pP7uco3et zuE)-Vme0E^l*98$#1K31eP%~);13<322H|7JhN70Wv=5W9}lhNWfnFm?#7Q9>A7|l zH4`h*&n#KdDSRg;^IDS5M)ygVM>1x`RQaa}r82a*{{KRvN+OF>q+jomu@-xaD?M~pV$)(VG z8mF>fD#>c|c$v%*1<_uyya6*trwsUKUDsz$zPbiq3Rbb##)OYX(w-@jOdJKhp2r@F zqR{OOA}G7fY<$q+Hpa4Mvt>+88|TS1jTP))9KFdFuc_f=;`)?tQENj=s8k%7k4MH5 zN<$WtF=hB{H7*y~)+C(fgijvY#8I7{j9J@nXv_YTO^L_az*5hT)SV&4qYP?nD@ggQ zOLVGTUnMPRB%%Zgn;sdA1*u6xW+Km^T%5w3h&%C7NkHmhz8rXE>8X9`P|nOt%@u1B z*;^T3SjMJwaD0}dL&*)2K3R2YwvvyMcn4>)sZDbEN@KQCwJC`*ZOKGc&V4DT($>tj zLu|&Wrk3KK)K;ydxV@Qfl4MpRPh#9qS5wKzc(MO>5oyW9mf0fIwrU9#h8FcJL|myH z)iA4?xNV4;qIt1c5+nFW?)&1Z0Bv!>2*Sw7wm>phHw^klqix3TOwnf+il8we?TQOA zik8Q{pksMvDFeB6C3W@omAcG56!fUKE@V`(RAs6STP>s9?molfMtVIfO_;WtgXHoC z8*v;S2EQuDW!CnKa$Kfa$hWKXob6w8Wjv4JeEAM!tV;uN9*M+R9xn=Sd8&h9*Q_C) zobs(q^`#`i@`gB2vQP|UUglxAtujQNR}`jlmn+XKN>=GsEwf8d*+hH-3X^=Sn4|F7 zP!PIigUHVV#fRJ^va`lZWwXe^swd@~+{%YCEVov-n{+, ): Promise => { const nameAndChannel = this.getNameAndChannel(); - if (nameAndChannel == false) return; + if (nameAndChannel == false) return false; const [senderName, combinedChannel] = nameAndChannel; const chatMessage: ChatMessage = await ChatModel.createChatMessage( @@ -231,11 +231,11 @@ export default class ChatModel { readonly sendReaction = async ( messageId: string, content: ReactionSymbols, - isDeleting?: boolean, + isDeleting: boolean = false, ): Promise => { const nameAndChannel = this.getNameAndChannel(); if (nameAndChannel == false) return; - const [senderName, combinedChannel] = nameAndChannel; + const [senderName] = nameAndChannel; const reaction = ChatModel.createMessageReaction( messageId, diff --git a/src/Model/Global/fileTransferModel.ts b/src/Model/Global/fileTransferModel.ts index 605b3b8c..16868af3 100644 --- a/src/Model/Global/fileTransferModel.ts +++ b/src/Model/Global/fileTransferModel.ts @@ -37,6 +37,7 @@ export default class FileTransferModel { }; readonly prepareToSend = (): void => { + if (!this.transferData) return; this.direction = TransferDirections.Send; this.connectionModel.addChannel(this.transferData.channel); }; @@ -156,7 +157,7 @@ export default class FileTransferModel { }; readonly prepareFileForSending = (filePath: string[]): string => { - const fileContent: string | undefined = + const fileContent: string | null = this.storageModel.read(filePath); if (fileContent == null) return ""; @@ -168,6 +169,8 @@ export default class FileTransferModel { }; readonly sendFile = async (stringifiedFileData: string): Promise => { + if (!this.transferData) return; + const encryptedFileData: string = await encryptString( stringifiedFileData, this.transferData.key, diff --git a/src/Model/Global/settingsModel.ts b/src/Model/Global/settingsModel.ts index 4e20f02e..a2b9128f 100644 --- a/src/Model/Global/settingsModel.ts +++ b/src/Model/Global/settingsModel.ts @@ -6,10 +6,10 @@ export default class SettingsModel { readonly storageModel: StorageModel; // data - username: string; - firstDayOfWeek: string; - language: string; - theme: string; + username: string = ""; + firstDayOfWeek: string = ""; + language: string = ""; + theme: string = ""; // storage private readonly storeSetting = ( @@ -46,7 +46,7 @@ export default class SettingsModel { // load private readonly readSetting = ( pathName: keyof typeof filePaths.settingsModel, - ): string => { + ): string|null=> { const path = StorageModel.getPath( StorageModelSubPaths.SettingsModel, filePaths.settingsModel[pathName], diff --git a/src/Model/Utility/.crypto.ts.swp b/src/Model/Utility/.crypto.ts.swp deleted file mode 100644 index 504b41878991713ee8275ebbd5b86ade0b8b5586..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12288 zcmeI2-)|IE6vr<=1Vj<64-g*A?O@_;Ty~+21h$~5ZGlx=2>p?0(~#NSyW4@?na#{> z%Lc27e*o}Af-f4Q5JKXU`bffqQ8ZEG4_Nffcy0-Fqcu_zf)j^P+S3vT7gGBwoGSTFWNsE1Wwy__|MD;skXdw z_Rny+Cqm(K_SHh2t*CNwI=n zY}Nb~R>oUM>ACsF%DxvyG@g$h>bc36TGc8GlJrKX9do(B|j<$%aQ68t*}*!>MZ9r zntl+y!rC^0!pGqvH)IFL#A{q=eF2-|mMXgo)WVwlrbXYN7IYVX%T;1Cv?5vJgl(@( zJ0X-<4N{$EZLN{AaQ@}#V^g`N6NJommoizZR$~?EgoP0z%#n`mx(V+#SWwe_b79>r zGrKrDiWK~QoKtEI}@+7#s z4kbzDvTpkWZM+(YE0r_KO*IysaJ-7&m~-ka7TR4&s?EjrI`-C>#{wr}#W@>B#WuqB!Dc!G2V3l}wmu_9bkuZFBuH6g*Xk65iz_!GT zcUC5+ii;2vGIr7|*`9P(Mq9Wlto0HT;@A%COinpL#!7PX)D1l$W{zc%+1w2LGCZi` zK%O8xbk%_x$DPcX6< zxJF=iBt2L;f>p%ad>+1re!!4-QAWp|$l*fqN~8K>uJlymK>vr~s3qM)QuAZ+MCEZJ zzhuYCWz^UxXhXM5e1@e{Jl?hTmkiN(qPU%%;Z>LR&T3iex^ue}`Hn4&l*_u+Hn0C& z6(y3kb0ywtTDF3G6w=RG>6?iYfFC}oCo*1&h2p8YtCod!IKR0+Qg;(>6%Qw9_iblvKi4XowQKS4 m({Mev;nWF{`|f()J4CI~iRs-(#wM*1)kBqf$h~)Hg!~QhCldbv diff --git a/src/Model/Utility/utility.ts b/src/Model/Utility/utility.ts index baf50031..cf71678e 100644 --- a/src/Model/Utility/utility.ts +++ b/src/Model/Utility/utility.ts @@ -313,20 +313,22 @@ export function implementPinchZoom(canvas: HTMLElement) { const MIN = 0.25; const MAX = 5; - const element = (): HTMLElement => canvas.querySelector(".zoom"); + const element = (): HTMLElement|null=> 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(factor: number, _offset?: [number, number]) { - if (factor < MIN) return apply(MIN, _offset); - if (factor > MAX) return apply(5, _offset); + const el = element(); + if (!el) return; + if (factor < MIN) return apply(MIN, _offset); + if (factor > MAX) return apply(5, _offset); let x: number, y: number; if (_offset) [x, y] = _offset; @@ -334,7 +336,7 @@ export function implementPinchZoom(canvas: HTMLElement) { x = currentX y = currentY } - element().style.transform = `scale(${factor.toString()}) translate(${x}px, ${y}px)`; + el.style.transform = `scale(${factor.toString()}) translate(${x}px, ${y}px)`; currentX = x; currentY = y; currentZoom = factor; @@ -356,15 +358,17 @@ export function implementPinchZoom(canvas: HTMLElement) { } apply(currentZoom - event.deltaY * 0.01); }); - canvas.addEventListener("scroll", (event: MouseEvent) => { + canvas.addEventListener("scroll", (event: Event) => { event.preventDefault(); }); canvas.addEventListener("touchstart", (event: TouchEvent) => { (document.activeElement as HTMLElement).blur(); - if (lastElement != undefined && lastElement != element()) reset(); - lastElement = element(); + const el = element(); + if (!el) return; + if (lastElement != undefined && lastElement != el) reset(); + lastElement = el; initialZoom = currentZoom; initialX = currentX; diff --git a/src/View/Modals/settingsModal.tsx b/src/View/Modals/settingsModal.tsx index a37455d6..a5cd8613 100644 --- a/src/View/Modals/settingsModal.tsx +++ b/src/View/Modals/settingsModal.tsx @@ -169,7 +169,7 @@ function SettingsAppearancePane(

{coreViewModel.translations.settings.pages.appearance}


{OptionButtonList( - new React.ListState<[string, ThemeSettings]>([ + new React.ListState<[string, string]>([ [ coreViewModel.translations.settings.themes.dark, ThemeSettings.Dark, diff --git a/src/View/Modals/splitModal.tsx b/src/View/Modals/splitModal.tsx index 925fb957..46dec7cc 100644 --- a/src/View/Modals/splitModal.tsx +++ b/src/View/Modals/splitModal.tsx @@ -10,6 +10,7 @@ export function SplitModal( navigationState?: React.State, ) { function closePage() { + if (!navigationState) return; navigationState.value = undefined; } diff --git a/src/View/translations.ts b/src/View/translations.ts index 13fe9493..ffae625e 100644 --- a/src/View/translations.ts +++ b/src/View/translations.ts @@ -435,13 +435,13 @@ export const allTranslations: { 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.", - notConnectedError: "Du bist mit keinem Server verbunden.", - fromThisDeviceButton: "An anderes Gerät senden", toThisDeviceButton: "An dieses Gerät senden", exportButton: "Als Datei exportieren", @@ -463,448 +463,462 @@ export const allTranslations: { filesSentCount: (count) => `Dateien gesendet: ${count}.`, allFilesSent: "Fertig.", - filesReceivedCount: (count) => `Dateien empfangen: ${count}.`, - }, + filesReceivedCount: (count) => `Dateien empfangen: ${count}.`, - storage: { - noItemSelected: "Kein Element ausgewählt", - notAFile: "(keine Datei)", - contentEmpty: "(leer)", + exportKey: "Schlüssel", + exportKeyConfirmation: "Schlüssel bestätigen", + downloadFileButton: "Herunterladen", + importFileButton: "Importieren", + decryptImportButton: "Entschlüsseln", + incorrectPassphraseError: "Der Schlüssel ist nicht korrekt" + }, - path: "Pfad", - content: "Inhalt", + storage: { + noItemSelected: "Kein Element ausgewählt", + notAFile: "(keine Datei)", + contentEmpty: "(leer)", - deleteItem: "Element löschen", + path: "Pfad", + content: "Inhalt", - removeJunkButton: "Datenmüll löschen", - }, + deleteItem: "Element löschen", - chatPage: { - closeChatAudioLabe: "Chat schließen", - chatSettingsAudioLabel: "Chateinstellungen", + removeJunkButton: "Datenmüll löschen", + }, - pages: { - settings: "Einstellungen", - messages: "Nachrichten", - tasks: "Aufgaben", - calendar: "Kalender", - }, + chatPage: { + closeChatAudioLabe: "Chat schließen", + chatSettingsAudioLabel: "Chateinstellungen", - settings: { - settingsHeadline: "Einstellungen", + pages: { + settings: "Einstellungen", + messages: "Nachrichten", + tasks: "Aufgaben", + calendar: "Kalender", + }, - primaryChannelLabel: "Hauptkanal", - setPrimaryChannelButtonAudioLabel: "Hauptkanal festlegen", + settings: { + settingsHeadline: "Einstellungen", - namespaceLabel: "Namensraum", - namespacePlaceholder: "Ohne Namensraum", - setNamespaceButtonAudioLabel: "Namensraum festlegen", + primaryChannelLabel: "Hauptkanal", + setPrimaryChannelButtonAudioLabel: "Hauptkanal festlegen", - newSecondaryChannelPlaceholder: "Sekundären Kanal hinzufügen", - newSecondaryChannelAudioLabel: - "Name des neuen sekundären Kanals", - addSecondaryChannelButtonAudioLabel: - "Sekundären Kanal hinzufügen", + namespaceLabel: "Namensraum", + namespacePlaceholder: "Ohne Namensraum", + setNamespaceButtonAudioLabel: "Namensraum festlegen", - encryptionKeyLabel: "Schlüssel", - setEncryptionKeyButtonAudioLabel: "Schlüssel festlegen", - showEncryptionKey: "Schlüssel anzeigen", + newSecondaryChannelPlaceholder: "Sekundären Kanal hinzufügen", + newSecondaryChannelAudioLabel: + "Name des neuen sekundären Kanals", + addSecondaryChannelButtonAudioLabel: + "Sekundären Kanal hinzufügen", - deleteChatButton: "Gesamten Chat löschen", - }, + encryptionKeyLabel: "Schlüssel", + setEncryptionKeyButtonAudioLabel: "Schlüssel festlegen", + showEncryptionKey: "Schlüssel anzeigen", - message: { - messagesHeadline: "Nachrichten", + deleteChatButton: "Gesamten Chat löschen", + }, - messageFilterHeadline: "Nachrichten filtern", - messageFilterReactionsHadline: "Reaktionen", - messageFilterAllReactionsButton: "Alle anzeigen", + message: { + messagesHeadline: "Nachrichten", - composerInputPlaceholder: "Schreib eine Nachricht...", - sendMessageButtonAudioLabel: "nachricht senden", - filterMessagesButtonAudioLabel: "nachrichten filtern", + messageFilterHeadline: "Nachrichten filtern", + messageFilterReactionsHadline: "Reaktionen", + messageFilterAllReactionsButton: "Alle anzeigen", - showMessageInfoButtonAudioLabel: "nachrichteninfo anzeigen", - messageInfoHeadline: "Nachrichteninfo", - cancelReplyAudioLabel: "antwort abbrechen", + composerInputPlaceholder: "Schreib eine Nachricht...", + sendMessageButtonAudioLabel: "nachricht senden", + filterMessagesButtonAudioLabel: "nachrichten filtern", - sentBy: "Gesendet von", - timeSent: "Sendezeit", - channel: "Kanal", - messageContent: "Nachrichteninhalt", + showMessageInfoButtonAudioLabel: "nachrichteninfo anzeigen", + messageInfoHeadline: "Nachrichteninfo", + cancelReplyAudioLabel: "antwort abbrechen", - copyMessageButton: "Nachricht kopieren", - resendMessageButton: "Nachricht erneut senden", - decryptMessageButton: "Nachricht entschlüsseln", - replyToMessageButton: "Auf Nachricht antworten", - deleteMessageButton: "Nachricht löschen", + sentBy: "Gesendet von", + timeSent: "Sendezeit", + channel: "Kanal", + messageContent: "Nachrichteninhalt", - // + copyMessageButton: "Nachricht kopieren", + resendMessageButton: "Nachricht erneut senden", + decryptMessageButton: "Nachricht entschlüsseln", + replyToMessageButton: "Auf Nachricht antworten", + deleteMessageButton: "Nachricht löschen", - thumbsUpReaction: "Reaktion: Daumen hoch", - checkReaction: "Reaktion: Haken", - stopReaction: "Reaktion: Stopp", - attentionReaction: "Reaktion: Ausrufezeichen", - doubleAttentionReaction: "Reaktion: doppeltes Ausrufezeichen", - questionReaction: "Reaktion: Fragezeichen", - }, + // - task: { - newBoardNamePlaceholder: "Board erstellen", - createBoardButtonAudioLabel: "board erstellen", + thumbsUpReaction: "Reaktion: Daumen hoch", + checkReaction: "Reaktion: Haken", + stopReaction: "Reaktion: Stopp", + attentionReaction: "Reaktion: Ausrufezeichen", + doubleAttentionReaction: "Reaktion: doppeltes Ausrufezeichen", + questionReaction: "Reaktion: Fragezeichen", + }, - noBoardSelected: "Kein Board ausgewählt", - boardNotFound: "Board nicht gefunden", + task: { + newBoardNamePlaceholder: "Board erstellen", + createBoardButtonAudioLabel: "board erstellen", - closeBoardButtonAudioLabel: "board schließen", - toggleBoardButtonAudioLabel: "board-liste ein/ausblenden", - showBoardSettingsButtonAudioLabel: - "Board-Einstellungen anzeigen", + noBoardSelected: "Kein Board ausgewählt", + boardNotFound: "Board nicht gefunden", - listViewButtonAudioLabel: "Listenansicht", - kanbanViewButtonAudioLabel: "Kanban-Ansicht", - statusViewButtonAudioLabel: "Statusrasteransicht", + closeBoardButtonAudioLabel: "board schließen", + toggleBoardButtonAudioLabel: "board-liste ein/ausblenden", + showBoardSettingsButtonAudioLabel: + "Board-Einstellungen anzeigen", - filterTasksButtonAudioLabel: "Aufgaben filtern", - createTaskButtonAudioLabel: "Neue Aufgabe erstellen", + listViewButtonAudioLabel: "Listenansicht", + kanbanViewButtonAudioLabel: "Kanban-Ansicht", + statusViewButtonAudioLabel: "Statusrasteransicht", - boardSettingsHeadline: "Board-Einstellungen", - boardNameInputLabel: "Boardname", - deleteBoardButton: "Board und alle Aufgaben löschen", + filterTasksButtonAudioLabel: "Aufgaben filtern", + createTaskButtonAudioLabel: "Neue Aufgabe erstellen", - taskSettingsHeadline: "Aufgabe bearbeiten", + boardSettingsHeadline: "Board-Einstellungen", + boardNameInputLabel: "Boardname", + deleteBoardButton: "Board und alle Aufgaben löschen", - taskNameLabel: "Titel", - taskBoardLabel: "Board", + taskSettingsHeadline: "Aufgabe bearbeiten", - taskCategoryLabel: "Kategorie", - taskStatusLabel: "Status", - taskPriorityLabel: "Priorität", + taskNameLabel: "Titel", + taskBoardLabel: "Board", - taskDescriptionLabel: "Beschreibung", + taskCategoryLabel: "Kategorie", + taskStatusLabel: "Status", + taskPriorityLabel: "Priorität", - taskDateLabel: "Datum", - taskTimeLabel: "Uhrzeit", + taskDescriptionLabel: "Beschreibung", - deleteTaskButton: "Aufgabe löschen", + taskDateLabel: "Datum", + taskTimeLabel: "Uhrzeit", - filterTasksHeadline: "Aufgaben filtern", + deleteTaskButton: "Aufgabe löschen", - renameCategoryInputPlaceholder: "Kategorie umbenennen", - renameStatusInputPlaceholder: "Status umbenennen", - }, + filterTasksHeadline: "Aufgaben filtern", - calendar: { - eventsBoard: "Ereignisse", + renameCategoryInputPlaceholder: "Kategorie umbenennen", + renameStatusInputPlaceholder: "Status umbenennen", + }, - /// + calendar: { + eventsBoard: "Ereignisse", - todayButtonAudioLabel: "gehe zu heute", + /// - previousMonthButtonAudioLabel: "vorheriger monat", - nextMonthButtonAudioLabel: "nächster monat", + todayButtonAudioLabel: "gehe zu heute", - yearInputAudioLabel: "Jahr", - monthInputAudioLabel: "Monat", + previousMonthButtonAudioLabel: "vorheriger monat", + nextMonthButtonAudioLabel: "nächster monat", - yearInputPlaceholder: "2000", - monthInputPlaceholder: "01", + yearInputAudioLabel: "Jahr", + monthInputAudioLabel: "Monat", - searchEventsHeadline: "Ereignisse suchen", + yearInputPlaceholder: "2000", + monthInputPlaceholder: "01", - events: "Ereignisse", - noEvents: "Keine Ereignisse", - }, - }, + searchEventsHeadline: "Ereignisse suchen", + + events: "Ereignisse", + noEvents: "Keine Ereignisse", + }, + }, }, es: { - updater: { - migrated: "Migrado", - }, - - general: { - deleteItemButtonAudioLabel: "eliminar elemento", - searchButtonAudioLabel: "buscar", - - abortButton: "Abortar", - cancelButton: "Cancelar", - closeButton: "Cerrar", - backButton: "Atrás", - - continueButton: "Continuar", - confirmButton: "Confirmar", - saveButton: "Guardar", - setButton: "OK", - - reloadAppButton: "Recargar app", - - fileVersionLabel: "Versión", - searchLabel: "Buscar", - 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: "Comms", - - 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", - - 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 Comms", - }, - themes: { - dark: "Oscuro", - light: "Claro", - system: "Según dispositivo", - }, - - version: "Versión", - language: "Idioma", - - firstDayOfWeekLabel: "Primer día de la semana", - }, - 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.", - dataEntryDescription: - "Introduce estos datos en el otro dispositivo.", - dataEntryInputDescription: - "Introduce los datos mostrados en el otro dispositivo.", - - notConnectedError: "No estás conectado a ningún servidor.", - - 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}.`, - }, - - storage: { - noItemSelected: "Ningún elemento seleccionado", - notAFile: "(no es un archivo)", - contentEmpty: "(vacío)", - - 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", - }, + updater: { + migrated: "Migrado", + }, + + general: { + deleteItemButtonAudioLabel: "eliminar elemento", + searchButtonAudioLabel: "buscar", + + abortButton: "Abortar", + cancelButton: "Cancelar", + closeButton: "Cerrar", + backButton: "Atrás", + + continueButton: "Continuar", + confirmButton: "Confirmar", + saveButton: "Guardar", + setButton: "OK", + + reloadAppButton: "Recargar app", + + fileVersionLabel: "Versión", + searchLabel: "Buscar", + 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: "Comms", + + 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", + + 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 Comms", + }, + themes: { + dark: "Oscuro", + light: "Claro", + system: "Según dispositivo", + }, + + version: "Versión", + language: "Idioma", + + firstDayOfWeekLabel: "Primer día de la semana", + }, + 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)", + + 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", + + primaryChannelLabel: "Canal principal", + setPrimaryChannelButtonAudioLabel: "establecer canal principal", + + namespaceLabel: "Espacio de nombres", + namespacePlaceholder: "Sin espacio de nombres", + setNamespaceButtonAudioLabel: "establecer espacio de nombres", + + newSecondaryChannelPlaceholder: "Añadir canal secundario", + newSecondaryChannelAudioLabel: + "nombre del nuevo canal secundario", + addSecondaryChannelButtonAudioLabel: "añadir canal secundario", - settings: { - settingsHeadline: "Configuración", + encryptionKeyLabel: "Clave de encriptación", + setEncryptionKeyButtonAudioLabel: + "establecer clave de encriptación", + showEncryptionKey: "Mostrar clave de encriptación", - primaryChannelLabel: "Canal principal", - setPrimaryChannelButtonAudioLabel: "establecer canal principal", + deleteChatButton: "Eliminar todo el chat", + }, - namespaceLabel: "Espacio de nombres", - namespacePlaceholder: "Sin espacio de nombres", - setNamespaceButtonAudioLabel: "establecer espacio de nombres", + message: { + messagesHeadline: "Mensajes", - newSecondaryChannelPlaceholder: "Añadir canal secundario", - newSecondaryChannelAudioLabel: - "nombre del nuevo canal secundario", - addSecondaryChannelButtonAudioLabel: "añadir canal secundario", + messageFilterHeadline: "Filtrar mensajes", + messageFilterReactionsHadline: "Reacciones", + messageFilterAllReactionsButton: "Mostrar todas", - encryptionKeyLabel: "Clave de encriptación", - setEncryptionKeyButtonAudioLabel: - "establecer clave de encriptación", - showEncryptionKey: "Mostrar clave de encriptación", + composerInputPlaceholder: "Escribe un mensaje...", + sendMessageButtonAudioLabel: "enviar mensaje", + filterMessagesButtonAudioLabel: "filtrar mensajes", - deleteChatButton: "Eliminar todo el chat", - }, + showMessageInfoButtonAudioLabel: + "mostrar información del mensaje", + messageInfoHeadline: "Información del Mensaje", + cancelReplyAudioLabel: "abortar la respuesta", - message: { - messagesHeadline: "Mensajes", + sentBy: "Enviado por", + timeSent: "Hora de envío", + channel: "Canal", + messageContent: "Contenido del mensaje", - messageFilterHeadline: "Filtrar mensajes", - messageFilterReactionsHadline: "Reacciones", - messageFilterAllReactionsButton: "Mostrar todas", + copyMessageButton: "Copiar mensaje", + resendMessageButton: "Reenviar mensaje", + decryptMessageButton: "Desencriptar mensaje", + replyToMessageButton: "Responder al mensaje", + deleteMessageButton: "Eliminar mensaje", - composerInputPlaceholder: "Escribe un mensaje...", - sendMessageButtonAudioLabel: "enviar mensaje", - filterMessagesButtonAudioLabel: "filtrar mensajes", + // - showMessageInfoButtonAudioLabel: - "mostrar información del mensaje", - messageInfoHeadline: "Información del Mensaje", - cancelReplyAudioLabel: "abortar la respuesta", + 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", + }, - sentBy: "Enviado por", - timeSent: "Hora de envío", - channel: "Canal", - messageContent: "Contenido del mensaje", + task: { + newBoardNamePlaceholder: "Crear un tablero", + createBoardButtonAudioLabel: "crear tablero", - copyMessageButton: "Copiar mensaje", - resendMessageButton: "Reenviar mensaje", - decryptMessageButton: "Desencriptar mensaje", - replyToMessageButton: "Responder al mensaje", - deleteMessageButton: "Eliminar mensaje", + noBoardSelected: "Ningún tablero seleccionado", + boardNotFound: "Tablero no encontrado", - // + closeBoardButtonAudioLabel: "cerrar tablero", + toggleBoardButtonAudioLabel: + "mostrar o ocultar lista de tableros", + showBoardSettingsButtonAudioLabel: + "mostrar configuración del tablero", - 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", - }, + listViewButtonAudioLabel: "vista de lista", + kanbanViewButtonAudioLabel: "vista kanban", + statusViewButtonAudioLabel: "vista de cuadrícula de estado", - task: { - newBoardNamePlaceholder: "Crear un tablero", - createBoardButtonAudioLabel: "crear tablero", + filterTasksButtonAudioLabel: "filtrar tareas", + createTaskButtonAudioLabel: "crear nueva tarea", - noBoardSelected: "Ningún tablero seleccionado", - boardNotFound: "Tablero no encontrado", + boardSettingsHeadline: "Configuración del Tablero", + boardNameInputLabel: "Nombre del tablero", + deleteBoardButton: "Eliminar tablero y todas las tareas", - closeBoardButtonAudioLabel: "cerrar tablero", - toggleBoardButtonAudioLabel: - "mostrar o ocultar lista de tableros", - showBoardSettingsButtonAudioLabel: - "mostrar configuración del tablero", + taskSettingsHeadline: "Editar Tarea", - listViewButtonAudioLabel: "vista de lista", - kanbanViewButtonAudioLabel: "vista kanban", - statusViewButtonAudioLabel: "vista de cuadrícula de estado", + taskNameLabel: "Título", + taskBoardLabel: "Tablero", - filterTasksButtonAudioLabel: "filtrar tareas", - createTaskButtonAudioLabel: "crear nueva tarea", + taskCategoryLabel: "Categoría", + taskStatusLabel: "Estado", + taskPriorityLabel: "Prioridad", - boardSettingsHeadline: "Configuración del Tablero", - boardNameInputLabel: "Nombre del tablero", - deleteBoardButton: "Eliminar tablero y todas las tareas", + taskDescriptionLabel: "Descripción", - taskSettingsHeadline: "Editar Tarea", + taskDateLabel: "Fecha", + taskTimeLabel: "Hora", - taskNameLabel: "Título", - taskBoardLabel: "Tablero", + deleteTaskButton: "Eliminar tarea", - taskCategoryLabel: "Categoría", - taskStatusLabel: "Estado", - taskPriorityLabel: "Prioridad", + filterTasksHeadline: "Filtrar Tareas", - taskDescriptionLabel: "Descripción", + renameCategoryInputPlaceholder: "Renombrar categoría", + renameStatusInputPlaceholder: "Renombrar estado", + }, - taskDateLabel: "Fecha", - taskTimeLabel: "Hora", + calendar: { + eventsBoard: "Eventos", - deleteTaskButton: "Eliminar tarea", + /// - filterTasksHeadline: "Filtrar Tareas", + todayButtonAudioLabel: "ir a hoy", - renameCategoryInputPlaceholder: "Renombrar categoría", - renameStatusInputPlaceholder: "Renombrar estado", - }, + previousMonthButtonAudioLabel: "mes anterior", + nextMonthButtonAudioLabel: "mes siguiente", - calendar: { - eventsBoard: "Eventos", + yearInputAudioLabel: "año", + monthInputAudioLabel: "mes", - /// + yearInputPlaceholder: "2000", + monthInputPlaceholder: "01", - todayButtonAudioLabel: "ir a hoy", + searchEventsHeadline: "Buscar Eventos", - previousMonthButtonAudioLabel: "mes anterior", - nextMonthButtonAudioLabel: "mes siguiente", - - yearInputAudioLabel: "año", - monthInputAudioLabel: "mes", - - yearInputPlaceholder: "2000", - monthInputPlaceholder: "01", - - searchEventsHeadline: "Buscar Eventos", - - events: "Eventos", - noEvents: "No hay eventos", - }, - }, + events: "Eventos", + noEvents: "No hay eventos", + }, + }, }, }; diff --git a/src/View/viewController.ts b/src/View/viewController.ts index c6795e7a..9a6fb706 100644 --- a/src/View/viewController.ts +++ b/src/View/viewController.ts @@ -7,9 +7,9 @@ class Tracker { class TrackerMap { trackers = new Map>(); - private register = (key: string): Tracker => { + private register = (key: string): Tracker=> { if (this.trackers.has(key)) { - return this.trackers.get(key); + return this.trackers.get(key)!; } const tracker = new Tracker(); this.trackers.set(key, tracker); @@ -19,7 +19,7 @@ class TrackerMap { setState = ( key: string, stateBuilder: () => React.State, - ): React.State | undefined => { + ): React.State | undefined => { const tracker: Tracker = this.register(key); if (tracker.state != undefined) { diff --git a/src/ViewModel/Chat/chatMessageViewModel.ts b/src/ViewModel/Chat/chatMessageViewModel.ts index 3bf940da..a34598f1 100644 --- a/src/ViewModel/Chat/chatMessageViewModel.ts +++ b/src/ViewModel/Chat/chatMessageViewModel.ts @@ -11,9 +11,9 @@ import { export default class ChatMessageViewModel { // data chatMessage: ChatMessage; - channel: string; - sender: string; - dateSent: string; + channel: string = ""; + sender: string = ""; + dateSent: string = ""; body: React.State = new React.State(""); inlineReply: ChatMessageViewModel | undefined = undefined; status: React.State = new React.State( diff --git a/src/ViewModel/Chat/chatViewModel.ts b/src/ViewModel/Chat/chatViewModel.ts index eb37c335..0725672c 100644 --- a/src/ViewModel/Chat/chatViewModel.ts +++ b/src/ViewModel/Chat/chatViewModel.ts @@ -143,14 +143,14 @@ export default class ChatViewModel extends ContextHost { // init constructor( - public readonly coreViewModel: CoreViewModel, + 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"); + super("chat", coreViewModel); // page viewModels this.calendarViewModel = new CalendarPageViewModel( diff --git a/src/ViewModel/Global/.coreViewModel.ts.swp b/src/ViewModel/Global/.coreViewModel.ts.swp index f1deea6778f035714c0edb82127541cb42923c03..dda9cc0b9913eb6f1165eea2283c865bc17b668a 100644 GIT binary patch delta 1042 zcmZ|OO-K}B9LMqhtgmCfA(CX}jzP5cVrvk!t`_J<7)eGLfe^XttZr_*%j_)n;^syr z-9i>JZ-$U%bg(&es9Q&&OQ3{WK|}_15EO!x`p%l>r3XInFwcLU=b7jEO)90NQi{{> zKHt)+d1~E4D-{V0j$ZD}u8>3YyF=#C#4!4C25yug4+;cJ#T+#Tk-|+R5kwm_ zII&P9@)&n<9UW*b;y91ese>Ekm?#u^iXJqxPmb3AURQmCBid{G?FlI8l_kuI3F+%J6s0rPz6zp zADrx0*e6_=XDQizIhT@RUsqDpcp|17uE5$|`E-Ax+o#6^Mkr>6qLCVJri{_JX(R$> z^uLw$8Wo{P_kJyw@P|WzbYa8J{2J{>=6!4Sh*MGHdRPzGv!+WuElp}BDjUz%Q{ojh zvzoRsqBUw}PbgmdcZ=uNXYpDWJd=*}n`7nH@rE*GtCI{7)J(H~RH7tRIaYV$2u0P6 MoASANx_|5b0lQV!^#A|> delta 821 zcmYk)Pe{{Y7{Kx8-9It!M#ax|5>I@2_>=c`*q&34a%+g`(rCg42ue!ix#F^jal3P; zx!Bm@a3=JjjCMM6!UzXijK@K@xv%+^GPVacD!-`*4p`Mz^UbD^B|A#?OZ>7@>1gE% z;+LC5@E()MLq`(*ID}q!QC=hR0n1oI2~!xsFe0$xQ;oLgAuGCPqJd0zff&(vC zi%j4KuHzu$h@k~8lvjz|LIF7pAc-J+@S+~ejKf3RM-k@`Lo0qW4qse7A|F{y;~wtf zJmQF<7T=hWGM?ZpV%Uo)yeLz>6;!IIoTjo}a;OnQ57(KwZ7yX@cRD=(da++iYl%!s zA8IwO1-ndN=z+ywiG+S!>q}{;y7i=%4*PfizcuGOnpNEorl8X7N~{CDlJ8ctddE%6 EUkme;DgXcg diff --git a/src/ViewModel/Global/coreViewModel.ts b/src/ViewModel/Global/coreViewModel.ts index 6cce6625..46e94a4c 100644 --- a/src/ViewModel/Global/coreViewModel.ts +++ b/src/ViewModel/Global/coreViewModel.ts @@ -9,7 +9,7 @@ import ConnectionModel from "../../Model/Global/connectionModel"; import ChatListModel from "../../Model/Chat/chatListModel"; export default class CoreViewModel { - readonly BUILD = "Build 26.09.06.A"; + readonly BUILD = "Build 26.09.09.A"; translations: Translations; @@ -40,7 +40,8 @@ export default class CoreViewModel { return; while (this.contexts.length > 0) { - const currentContext: Context = this.context; + const currentContext: Context|undefined= this.context; + if (!currentContext) return; currentContext.handleContextClose(fromHistoryEvent); this.contextStack.delete(currentContext.contextId); if (currentContext.contextId == contextId) break; @@ -53,7 +54,7 @@ export default class CoreViewModel { const contexts: Context[] = this.contexts; while (contexts.length > 0) { const currentContext: Context | undefined = contexts.pop(); - if (!currentContext) contexts; + if (!currentContext) return; const isHandled: boolean = currentContext.handleKeystroke(e); if (isHandled == true) break; } @@ -102,6 +103,7 @@ export default class CoreViewModel { document.body.addEventListener("keydown", this.handleKeyDown); window.onpopstate = () => { + if (!this.context) return; this.closeContext(this.context.contextId, true); }; @@ -142,7 +144,6 @@ export class Context { } export class ContextHost extends Context { - coreViewModel: CoreViewModel; contexts = new Map(); currentContext = new React.State(undefined); @@ -169,8 +170,10 @@ export class ContextHost extends Context { updateContexts = (): void => { if (this.isOpen == false) return; + const selection = this.contextSelection; + if (!selection) return; const selectedContext: Context | undefined = this.contexts.get( - this.contextSelection, + selection ); if (!selectedContext) return; if (selectedContext != this.currentContext.value) { @@ -180,4 +183,8 @@ export class ContextHost extends Context { this.coreViewModel.context = selectedContext; this.currentContext.value = selectedContext; }; + + constructor(contextDebugDescription: string, public coreViewModel: CoreViewModel) { + super(contextDebugDescription); + } } diff --git a/src/ViewModel/Global/fileTransferViewModel.ts b/src/ViewModel/Global/fileTransferViewModel.ts index 578f118d..77256a6c 100644 --- a/src/ViewModel/Global/fileTransferViewModel.ts +++ b/src/ViewModel/Global/fileTransferViewModel.ts @@ -54,7 +54,7 @@ export default class FileTransferViewModel extends Context { exportKey: React.State = new React.State(""); exportKeyConfirmation: React.State = new React.State(""); - importedFile: React.State = new React.State(undefined); + importedFile: React.State = new React.State(undefined); importedFileString: React.State = new React.State(""); importKey: React.State = new React.State(""); isImportKeyCorrect: React.State = new React.State(true); @@ -158,6 +158,7 @@ export default class FileTransferViewModel extends Context { if (!input) return; if (!(input instanceof HTMLInputElement)) return; + if (!input.files) return; const file = input.files[0]; this.importedFile.value = file; }; @@ -170,6 +171,7 @@ export default class FileTransferViewModel extends Context { reader.readAsText(file, "utf8"); reader.onload = () => { const result = reader.result; + if (!result) return; this.importedFileString.value = result.toString(); this.showImportDecryptDataModal(); }; diff --git a/src/ViewModel/Global/notificationViewModel.ts b/src/ViewModel/Global/notificationViewModel.ts index 9be7e21c..78a8cfc0 100644 --- a/src/ViewModel/Global/notificationViewModel.ts +++ b/src/ViewModel/Global/notificationViewModel.ts @@ -35,7 +35,7 @@ export default class NotificationViewModel { }; openNotification = () => { - const notification: Notification = this.marquee.value; + const notification: Notification|undefined = this.marquee.value; if (notification == undefined) return; const chat = [ @@ -44,6 +44,7 @@ export default class NotificationViewModel { (chat) => chat.chatModel.unwrappedPrimaryChannel == notification.chat, ); + if (!chat) return; chat.open(); chat.openPage(ChatPageTypes.Messages); }; @@ -55,7 +56,8 @@ export default class NotificationViewModel { return this.stopLoop(); } - const notification: Notification = this.messagesInMarquee.shift(); + const notification: Notification|undefined = this.messagesInMarquee.shift(); + if (!notification) return; this.seenMessageIds.delete(notification.messageId); this.marquee.value = notification; }; diff --git a/src/ViewModel/Global/settingsViewModel.ts b/src/ViewModel/Global/settingsViewModel.ts index 335d579c..f603d20a 100644 --- a/src/ViewModel/Global/settingsViewModel.ts +++ b/src/ViewModel/Global/settingsViewModel.ts @@ -9,14 +9,14 @@ export default class SettingsViewModel extends Context { usernameInput: React.State = new React.State(""); isShowingSettingsModal: React.State = new React.State(false); selectedModalPage: React.State = - new React.State(undefined); + new React.State(undefined); requiresReload = new React.State(false); firstDayOfWeek: React.State = new React.State("0"); - language: React.State = new React.State( + language: React.State = new React.State( Languages.English, ); - theme: React.State = new React.State( + theme: React.State = new React.State( ThemeSettings.System, ); diff --git a/src/ViewModel/Global/storageViewModel.ts b/src/ViewModel/Global/storageViewModel.ts index 4fb362e9..98b2375b 100644 --- a/src/ViewModel/Global/storageViewModel.ts +++ b/src/ViewModel/Global/storageViewModel.ts @@ -23,7 +23,7 @@ export default class StorageViewModel extends Context { const path: string[] = StorageModel.stringToPathComponents( this.selectedPath.value, ); - const content: string | undefined = + const content: string | null = this.coreViewModel.storageModel.read(path); return ( (content ?? this.coreViewModel.translations.storage.notAFile) || diff --git a/src/ViewModel/Pages/messagePageViewModel.ts b/src/ViewModel/Pages/messagePageViewModel.ts index 53727277..8599b24a 100644 --- a/src/ViewModel/Pages/messagePageViewModel.ts +++ b/src/ViewModel/Pages/messagePageViewModel.ts @@ -68,7 +68,7 @@ export default class MessagePageViewModel extends Context { ); }; - setReply = (chatMessageViewModel: ChatMessageViewModel): void => { + setReply = (chatMessageViewModel: ChatMessageViewModel|undefined): void => { this.replyingMessage.value = chatMessageViewModel; this.setFocus(); }; diff --git a/src/ViewModel/Pages/taskPageViewModel.ts b/src/ViewModel/Pages/taskPageViewModel.ts index 73d708f8..9362a0c4 100644 --- a/src/ViewModel/Pages/taskPageViewModel.ts +++ b/src/ViewModel/Pages/taskPageViewModel.ts @@ -167,11 +167,11 @@ export default class TaskPageViewModel extends ContextHost { // init constructor( - public readonly coreViewModel: CoreViewModel, + readonly coreViewModel: CoreViewModel, public readonly chatViewModel: ChatViewModel, public readonly boardsAndTasksModel: BoardsAndTasksModel, ) { - super("task-page"); + super("task-page", coreViewModel); this.loadData(); // needed for board options in calendar diff --git a/src/index.tsx b/src/index.tsx index 34daa9fe..7efc731f 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -16,7 +16,6 @@ import { SettingsModal } from "./View/Modals/settingsModal"; import { DataTransferModalWrapper } from "./View/Modals/dataTransferModal"; import { ConnectionModal } from "./View/Modals/connectionModal"; import v1Upgrader from "./Upgrader/v1"; -import * as Utility from "./Model/Utility/utility"; import StorageModel from "./Model/Global/storageModel"; import SettingsModel from "./Model/Global/settingsModel"; import FileTransferModel from "./Model/Global/fileTransferModel"; diff --git a/src/types/styles.d.ts b/src/types/styles.d.ts new file mode 100644 index 00000000..acdbccea --- /dev/null +++ b/src/types/styles.d.ts @@ -0,0 +1,2 @@ +declare module "*.css" { +} diff --git a/tsconfig.json b/tsconfig.json index 0c9158f3..c2f13cd4 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -3,8 +3,10 @@ "noImplicitAny": false, "jsx": "react", "jsxFactory": "React.createElement", - "moduleResolution": "node", + "module": "nodenext", + "moduleResolution": "nodenext", "esModuleInterop": true, "target": "es2020" - } + }, + "include":["./**/*"] }