From 26c99085d2e48ca96ce80ab34dff241240c2c922 Mon Sep 17 00:00:00 2001 From: marlon-erler Date: Wed, 23 Sep 2026 00:09:09 +0200 Subject: [PATCH] add method for filtering --- NERDTreeRenameTempBuffer | 0 src/Model/Files/fileModel.ts | 172 +-- src/Model/Global/fileTransferModel.ts | 7 +- src/Model/Global/settingsModel.ts | 2 +- src/Model/Utility/.utility.ts.swp | Bin 0 -> 24576 bytes src/Model/Utility/utility.ts | 320 ++--- .../.taskPage.tsx.swp} | Bin 12288 -> 16384 bytes src/View/ChatPages/boardKanbanPage.tsx | 2 +- src/View/ChatPages/boardPage.tsx | 2 +- src/View/ChatPages/boardStatusGridPage.tsx | 2 +- src/View/ChatPages/calendarPage.tsx | 2 +- src/View/ChatPages/messagePage.tsx | 2 +- src/View/ChatPages/settingsPage.tsx | 2 +- src/View/ChatPages/taskPage.tsx | 6 +- src/View/Components/boardEntry.tsx | 2 +- src/View/Components/boardViewToggleButton.tsx | 2 +- src/View/Components/chatMessage.tsx | 2 +- src/View/Components/chatViewToggleButton.tsx | 2 +- src/View/Components/inlineReply.tsx | 2 +- .../Components/messageReactionButtonRow.tsx | 2 +- src/View/Components/monthGrid.tsx | 2 +- src/View/Components/optionButtonList.tsx | 2 +- src/View/Modals/boardSettingsModal.tsx | 2 +- src/View/Modals/chatMessageInfoModal.tsx | 2 +- src/View/Modals/connectionModal.tsx | 2 +- src/View/Modals/dataTransferModal.tsx | 290 ++--- src/View/Modals/messageFilterModal.tsx | 2 +- src/View/Modals/searchModal.tsx | 106 +- src/View/Modals/settingsModal.tsx | 2 +- src/View/Modals/splitModal.tsx | 4 +- src/View/Modals/storageModal.tsx | 2 +- src/View/Modals/taskSettingsModal.tsx | 489 ++++---- src/View/chatPage.css | 93 +- src/View/chatPage.tsx | 87 +- src/View/chatPageWrapper.tsx | 2 +- src/View/homePage.tsx | 2 +- src/View/translations.ts | 1072 ++++++++--------- src/View/viewController.ts | 2 +- src/ViewModel/Chat/chatListViewModel.ts | 2 +- src/ViewModel/Chat/chatMessageViewModel.ts | 2 +- src/ViewModel/Chat/chatViewModel.ts | 2 +- .../Global/.connectionViewModel.ts.swp | Bin 12288 -> 0 bytes src/ViewModel/Global/connectionViewModel.ts | 8 +- src/ViewModel/Global/coreViewModel.ts | 27 +- src/ViewModel/Global/fileTransferViewModel.ts | 12 +- src/ViewModel/Global/notificationViewModel.ts | 11 +- src/ViewModel/Global/settingsViewModel.ts | 195 +-- src/ViewModel/Global/storageViewModel.ts | 2 +- src/ViewModel/Pages/.taskPageViewModel.ts.swp | Bin 0 -> 20480 bytes src/ViewModel/Pages/boardViewModel.ts | 18 +- src/ViewModel/Pages/calendarPageViewModel.ts | 2 +- src/ViewModel/Pages/messagePageViewModel.ts | 6 +- src/ViewModel/Pages/settingsPageViewModel.ts | 2 +- .../Pages/taskContainingPageViewModel.ts | 3 +- src/ViewModel/Pages/taskPageViewModel.ts | 18 +- src/ViewModel/Pages/taskViewModel.ts | 22 +- src/ViewModel/Utility/searchViewModel.ts | 13 +- .../taskPropertyBulkChangeViewModel.ts | 2 +- src/base.css | 10 +- src/react.ts | 272 ++--- src/types/styles.d.ts | 3 +- 61 files changed, 1703 insertions(+), 1623 deletions(-) create mode 100644 NERDTreeRenameTempBuffer create mode 100644 src/Model/Utility/.utility.ts.swp rename src/View/{Modals/.connectionModal.tsx.swp => ChatPages/.taskPage.tsx.swp} (56%) delete mode 100644 src/ViewModel/Global/.connectionViewModel.ts.swp create mode 100644 src/ViewModel/Pages/.taskPageViewModel.ts.swp diff --git a/NERDTreeRenameTempBuffer b/NERDTreeRenameTempBuffer new file mode 100644 index 00000000..e69de29b diff --git a/src/Model/Files/fileModel.ts b/src/Model/Files/fileModel.ts index 4c52f54d..5ee7db4e 100644 --- a/src/Model/Files/fileModel.ts +++ b/src/Model/Files/fileModel.ts @@ -70,150 +70,150 @@ export default class FileModel { 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", - ModelView = "view", - ModelTask = "tasks", - ModelCalendar = "calendar", + Model = "model", + 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 16868af3..c9d98bda 100644 --- a/src/Model/Global/fileTransferModel.ts +++ b/src/Model/Global/fileTransferModel.ts @@ -37,7 +37,7 @@ export default class FileTransferModel { }; readonly prepareToSend = (): void => { - if (!this.transferData) return; + if (!this.transferData) return; this.direction = TransferDirections.Send; this.connectionModel.addChannel(this.transferData.channel); }; @@ -157,8 +157,7 @@ export default class FileTransferModel { }; readonly prepareFileForSending = (filePath: string[]): string => { - const fileContent: string | null = - this.storageModel.read(filePath); + const fileContent: string | null = this.storageModel.read(filePath); if (fileContent == null) return ""; const fileData: FileData = { @@ -169,7 +168,7 @@ export default class FileTransferModel { }; readonly sendFile = async (stringifiedFileData: string): Promise => { - if (!this.transferData) return; + if (!this.transferData) return; const encryptedFileData: string = await encryptString( stringifiedFileData, diff --git a/src/Model/Global/settingsModel.ts b/src/Model/Global/settingsModel.ts index a2935ceb..c7e8e134 100644 --- a/src/Model/Global/settingsModel.ts +++ b/src/Model/Global/settingsModel.ts @@ -46,7 +46,7 @@ export default class SettingsModel { // load private readonly readSetting = ( pathName: keyof typeof filePaths.settingsModel, - ): string|null=> { + ): string | null => { const path = StorageModel.getPath( StorageModelSubPaths.SettingsModel, filePaths.settingsModel[pathName], diff --git a/src/Model/Utility/.utility.ts.swp b/src/Model/Utility/.utility.ts.swp new file mode 100644 index 0000000000000000000000000000000000000000..26ecc9d25bcc4d061d4131cff1f9f20381210a3c GIT binary patch literal 24576 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 @@ -28,7 +28,7 @@ export function filterObjectsByStringEntries( ): Set { const matches: Set = new Set(); - object_loop: for (const object of objects) { + for (const object of objects) { const doesMatch: boolean = checkDoesObjectMatchReference( reference, converter(object), @@ -39,79 +39,6 @@ export function filterObjectsByStringEntries( return matches; } -export function checkDoesObjectMatchReference( - reference: StringEntryObject, - stringEntryObject: StringEntryObject, - explicitEmptyValue: boolean = false, -): boolean { - reference_entry_loop: for (const referenceEntry of Object.entries( - reference, - )) { - const [referenceKey, referenceValue] = referenceEntry; - const stringEntryObjectValue: Stringifiable | undefined = - stringEntryObject[referenceKey]; - - 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; - } - - // 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; - } - } - } - return true; -} - -export function collectObjectValuesForKey( - key: string, - converter: (object: T) => StringEntryObject, - objects: T[], -): string[] { - 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; - - values.add(stringEntryObjectValue.toString()); - } - - return [...values.values()]; -} - export function filterObjectsByWords( query: string, getStringsOfObject: (object: T) => string[], @@ -119,7 +46,7 @@ export function filterObjectsByWords( ): Set { const matches: Set = new Set(); - object_loop: for (const object of objects) { + for (const object of objects) { const doesMatch: boolean = checkDoesObjectMatchSearch( query, getStringsOfObject, @@ -170,6 +97,26 @@ export function checkDoesObjectMatchSearch( return true; } +export default function implementFilter( + 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).includes(query.value)) return; + matches.add(item); + allItems.handleRemoval(item, () => { + matches.remove(item); + }); + }); + } + query.subscribe(update); + allItems.handleAddition(update); +} + // handlers export type Handler = (item: T) => void; @@ -313,99 +260,174 @@ export function implementPinchZoom(canvas: HTMLElement) { const MIN = 0.25; const MAX = 5; - const element = (): HTMLElement|null=> 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]) { - const el = element(); - if (!el) return; - 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; - else { - x = currentX - y = currentY - } - el.style.transform = `scale(${factor.toString()}) translate(${x}px, ${y}px)`; - currentX = x; - currentY = y; - currentZoom = factor; + let x: number, y: number; + if (_offset) [x, y] = _offset; + else { + x = currentX; + y = currentY; + } + el.style.transform = `scale(${factor.toString()}) translate(${x}px, ${y}px)`; + currentX = x; + currentY = y; + currentZoom = factor; } canvas.addEventListener("wheel", (event: WheelEvent) => { - event.preventDefault(); + event.preventDefault(); - initialZoom = currentZoom; - initialX = currentX; - initialY = currentY; + initialZoom = currentZoom; + initialX = currentX; + initialY = currentY; - if (!event.shiftKey) { - apply(currentZoom, [ - currentX - event.deltaX, - currentY - event.deltaY, - ]); - return; - } - apply(currentZoom - event.deltaY * 0.01); + if (!event.shiftKey) { + apply(currentZoom, [ + currentX - event.deltaX, + currentY - event.deltaY, + ]); + return; + } + apply(currentZoom - event.deltaY * 0.01); }); canvas.addEventListener("scroll", (event: Event) => { - event.preventDefault(); + event.preventDefault(); }); 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 = currentZoom; - initialX = currentX; - initialY = currentY; + initialZoom = currentZoom; + initialX = currentX; + initialY = currentY; - 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(currentZoom, [ - 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, - initialY + (midY - difference - initialTouchY) / initialZoom, - ]); + if (!pinching) { + apply(currentZoom, [ + 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, + initialY + (midY - difference - initialTouchY) / initialZoom, + ]); }); } + +// objecs +export function collectObjectValuesForKey( + key: string, + converter: (object: T) => StringEntryObject, + objects: T[], +): string[] { + 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; + + values.add(stringEntryObjectValue.toString()); + } + + return [...values.values()]; +} + +// type safety +export function checkDoesObjectMatchReference( + reference: StringEntryObject, + stringEntryObject: StringEntryObject, + explicitEmptyValue: boolean = false, +): boolean { + reference_entry_loop: for (const referenceEntry of Object.entries( + reference, + )) { + const [referenceKey, referenceValue] = referenceEntry; + const stringEntryObjectValue: Stringifiable | undefined = + stringEntryObject[referenceKey]; + + 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; + } + + // 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; + } + } + } + return true; +} diff --git a/src/View/Modals/.connectionModal.tsx.swp b/src/View/ChatPages/.taskPage.tsx.swp similarity index 56% rename from src/View/Modals/.connectionModal.tsx.swp rename to src/View/ChatPages/.taskPage.tsx.swp index 388ae278ae8fa70ef64d43f372484c94df4a993b..e7479c10aed06a4845d7ab93f49b82a84bdc8871 100644 GIT binary patch literal 16384 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 vSmdW#7VlF5pPs8dTUH0g6 diff --git a/src/View/ChatPages/boardKanbanPage.tsx b/src/View/ChatPages/boardKanbanPage.tsx index a1b3c5e3..147196e3 100644 --- a/src/View/ChatPages/boardKanbanPage.tsx +++ b/src/View/ChatPages/boardKanbanPage.tsx @@ -1,4 +1,3 @@ -import * as React from "../../react"; import { ViewController } from "../viewController"; import { TaskViewModelToEntry } from "../Components/taskEntry"; import { @@ -6,6 +5,7 @@ import { createPropertyValueIndexState, } from "../Components/propertyValueList"; import { FilteredList } from "../Components/filteredList"; +import * as React from "../../react"; import { TaskCategoryBulkChangeViewModel } from "../../ViewModel/Utility/taskPropertyBulkChangeViewModel"; import TaskViewModel from "../../ViewModel/Pages/taskViewModel"; import BoardViewModel from "../../ViewModel/Pages/boardViewModel"; diff --git a/src/View/ChatPages/boardPage.tsx b/src/View/ChatPages/boardPage.tsx index ee4668ab..5c68529f 100644 --- a/src/View/ChatPages/boardPage.tsx +++ b/src/View/ChatPages/boardPage.tsx @@ -1,4 +1,3 @@ -import * as React from "../../react"; import { BoardStatusGridPage } from "./boardStatusGridPage"; import { BoardKanbanPage } from "./boardKanbanPage"; import { ViewController } from "../viewController"; @@ -7,6 +6,7 @@ import { SearchModal } from "../Modals/searchModal"; import { BoardSettingsModal } from "../Modals/boardSettingsModal"; import { TaskViewModelToEntry } from "../Components/taskEntry"; import { BoardViewToggleButton } from "../Components/boardViewToggleButton"; +import * as React from "../../react"; import BoardViewModel, { BoardPageTypes, } from "../../ViewModel/Pages/boardViewModel"; diff --git a/src/View/ChatPages/boardStatusGridPage.tsx b/src/View/ChatPages/boardStatusGridPage.tsx index 54f69925..b50d3876 100644 --- a/src/View/ChatPages/boardStatusGridPage.tsx +++ b/src/View/ChatPages/boardStatusGridPage.tsx @@ -1,4 +1,3 @@ -import * as React from "../../react"; import { ViewController } from "../viewController"; import { TaskViewModelToEntry } from "../Components/taskEntry"; import { @@ -8,6 +7,7 @@ import { createSortedPropertyValueState, } from "../Components/propertyValueList"; import { FilteredList } from "../Components/filteredList"; +import * as React from "../../react"; import { TaskCategoryBulkChangeViewModel, TaskStatusBulkChangeViewModel, diff --git a/src/View/ChatPages/calendarPage.tsx b/src/View/ChatPages/calendarPage.tsx index 28eb900a..ddbc82f3 100644 --- a/src/View/ChatPages/calendarPage.tsx +++ b/src/View/ChatPages/calendarPage.tsx @@ -1,10 +1,10 @@ -import * as React from "../../react"; import "./calendarPage.css"; import { ViewController } from "../viewController"; import { TaskSettingsModal } from "../Modals/taskSettingsModal"; import { TaskViewModelToEntry } from "../Components/taskEntry"; import { PlaceholderView } from "../Components/placeholderView"; import { MonthGrid } from "../Components/monthGrid"; +import * as React from "../../react"; import CalendarPageViewModel from "../../ViewModel/Pages/calendarPageViewModel"; import CoreViewModel from "../../ViewModel/Global/coreViewModel"; diff --git a/src/View/ChatPages/messagePage.tsx b/src/View/ChatPages/messagePage.tsx index b84904bb..24259c0d 100644 --- a/src/View/ChatPages/messagePage.tsx +++ b/src/View/ChatPages/messagePage.tsx @@ -1,9 +1,9 @@ -import * as React from "../../react"; import "./messagePage.css"; import { ViewController } from "../viewController"; import { MessageFilterModal } from "../Modals/messageFilterModal"; import { ReplyPreview } from "../Components/replyPreview"; import { ChatMessage } from "../Components/chatMessage"; +import * as React from "../../react"; import MessagePageViewModel from "../../ViewModel/Pages/messagePageViewModel"; import CoreViewModel from "../../ViewModel/Global/coreViewModel"; import ChatMessageViewModel from "../../ViewModel/Chat/chatMessageViewModel"; diff --git a/src/View/ChatPages/settingsPage.tsx b/src/View/ChatPages/settingsPage.tsx index d47ec888..25955203 100644 --- a/src/View/ChatPages/settingsPage.tsx +++ b/src/View/ChatPages/settingsPage.tsx @@ -1,7 +1,7 @@ -import * as React from "../../react"; import { DeletableListItem } from "../Components/deletableListItem"; import { DangerousActionButton } from "../Components/dangerousActionButton"; import { ColorPicker } from "../Components/colorPicker"; +import * as React from "../../react"; import SettingsPageViewModel from "../../ViewModel/Pages/settingsPageViewModel"; import CoreViewModel from "../../ViewModel/Global/coreViewModel"; diff --git a/src/View/ChatPages/taskPage.tsx b/src/View/ChatPages/taskPage.tsx index 690b89ba..2e149231 100644 --- a/src/View/ChatPages/taskPage.tsx +++ b/src/View/ChatPages/taskPage.tsx @@ -1,9 +1,9 @@ -import * as React from "../../react"; import "./taskPage.css"; import { BoardPage } from "./boardPage"; import { ViewController } from "../viewController"; import { PlaceholderView } from "../Components/placeholderView"; import { BoardViewModelToEntry } from "../Components/boardEntry"; +import * as React from "../../react"; import TaskPageViewModel from "../../ViewModel/Pages/taskPageViewModel"; import CoreViewModel from "../../ViewModel/Global/coreViewModel"; @@ -62,7 +62,7 @@ export function TaskPage(
diff --git a/src/View/Components/boardEntry.tsx b/src/View/Components/boardEntry.tsx index 0d5835f4..80bef85f 100644 --- a/src/View/Components/boardEntry.tsx +++ b/src/View/Components/boardEntry.tsx @@ -1,5 +1,5 @@ -import * as React from "../../react"; import { ViewController } from "../viewController"; +import * as React from "../../react"; import BoardViewModel from "../../ViewModel/Pages/boardViewModel"; export function BoardEntry(boardViewModel: BoardViewModel) { diff --git a/src/View/Components/boardViewToggleButton.tsx b/src/View/Components/boardViewToggleButton.tsx index 67a4d9b1..063d0b27 100644 --- a/src/View/Components/boardViewToggleButton.tsx +++ b/src/View/Components/boardViewToggleButton.tsx @@ -1,5 +1,5 @@ -import * as React from "../../react"; import { RibbonButton } from "./ribbonButton"; +import * as React from "../../react"; import BoardViewModel, { BoardPageTypes, } from "../../ViewModel/Pages/boardViewModel"; diff --git a/src/View/Components/chatMessage.tsx b/src/View/Components/chatMessage.tsx index 43d21d6c..42f50888 100644 --- a/src/View/Components/chatMessage.tsx +++ b/src/View/Components/chatMessage.tsx @@ -1,7 +1,7 @@ -import * as React from "../../react"; import { MessageReactionButtonRow } from "./messageReactionButtonRow"; import { InlineReply } from "./inlineReply"; import { ChatMessageInfoModal } from "../Modals/chatMessageInfoModal"; +import * as React from "../../react"; import CoreViewModel from "../../ViewModel/Global/coreViewModel"; import ChatMessageViewModel from "../../ViewModel/Chat/chatMessageViewModel"; import { ChatMessageStatuses } from "../../Model/Chat/chatModel"; diff --git a/src/View/Components/chatViewToggleButton.tsx b/src/View/Components/chatViewToggleButton.tsx index e7869f9e..c03979e5 100644 --- a/src/View/Components/chatViewToggleButton.tsx +++ b/src/View/Components/chatViewToggleButton.tsx @@ -1,5 +1,5 @@ -import * as React from "../../react"; import { RibbonButton } from "./ribbonButton"; +import * as React from "../../react"; import ChatViewModel, { ChatPageTypes, } from "../../ViewModel/Chat/chatViewModel"; diff --git a/src/View/Components/inlineReply.tsx b/src/View/Components/inlineReply.tsx index 925e9c53..9c632092 100644 --- a/src/View/Components/inlineReply.tsx +++ b/src/View/Components/inlineReply.tsx @@ -1,5 +1,5 @@ -import * as React from "../../react"; import { ViewController } from "../viewController"; +import * as React from "../../react"; import ChatMessageViewModel from "../../ViewModel/Chat/chatMessageViewModel"; export function InlineReply(chatMessageViewModel: ChatMessageViewModel) { diff --git a/src/View/Components/messageReactionButtonRow.tsx b/src/View/Components/messageReactionButtonRow.tsx index e4aaa06f..ba8b7d14 100644 --- a/src/View/Components/messageReactionButtonRow.tsx +++ b/src/View/Components/messageReactionButtonRow.tsx @@ -1,5 +1,5 @@ -import * as React from "../../react"; import { MessageReactionButton } from "./messageReactionButton"; +import * as React from "../../react"; import CoreViewModel from "../../ViewModel/Global/coreViewModel"; import ChatMessageViewModel from "../../ViewModel/Chat/chatMessageViewModel"; import { ReactionSymbols } from "../../Model/Chat/chatModel"; diff --git a/src/View/Components/monthGrid.tsx b/src/View/Components/monthGrid.tsx index 06f59f61..15e70da9 100644 --- a/src/View/Components/monthGrid.tsx +++ b/src/View/Components/monthGrid.tsx @@ -1,6 +1,6 @@ -import * as React from "../../react"; import "./monthGrid.css"; import { ViewController } from "../viewController"; +import * as React from "../../react"; import TaskViewModel from "../../ViewModel/Pages/taskViewModel"; import CoreViewModel from "../../ViewModel/Global/coreViewModel"; import { localeCompare } from "../../Model/Utility/utility"; diff --git a/src/View/Components/optionButtonList.tsx b/src/View/Components/optionButtonList.tsx index 3b84f228..82c612db 100644 --- a/src/View/Components/optionButtonList.tsx +++ b/src/View/Components/optionButtonList.tsx @@ -1,5 +1,5 @@ -import * as React from "../../react"; import { OptionButton } from "./optionButton"; +import * as React from "../../react"; export function OptionButtonList( options: React.ListState<[string, T]>, diff --git a/src/View/Modals/boardSettingsModal.tsx b/src/View/Modals/boardSettingsModal.tsx index e7e32262..771e048c 100644 --- a/src/View/Modals/boardSettingsModal.tsx +++ b/src/View/Modals/boardSettingsModal.tsx @@ -1,7 +1,7 @@ -import * as React from "../../react"; import { ViewController } from "../viewController"; import { DangerousActionButton } from "../Components/dangerousActionButton"; import { ColorPicker } from "../Components/colorPicker"; +import * as React from "../../react"; import BoardViewModel from "../../ViewModel/Pages/boardViewModel"; import CoreViewModel from "../../ViewModel/Global/coreViewModel"; diff --git a/src/View/Modals/chatMessageInfoModal.tsx b/src/View/Modals/chatMessageInfoModal.tsx index b592c119..e8017bcb 100644 --- a/src/View/Modals/chatMessageInfoModal.tsx +++ b/src/View/Modals/chatMessageInfoModal.tsx @@ -1,7 +1,7 @@ -import * as React from "../../react"; import { MessageReactionEntry } from "../Components/messageReactionEntry"; import { MessageReactionButtonRow } from "../Components/messageReactionButtonRow"; import { InfoTile } from "../Components/infoTile"; +import * as React from "../../react"; import CoreViewModel from "../../ViewModel/Global/coreViewModel"; import ChatMessageViewModel from "../../ViewModel/Chat/chatMessageViewModel"; diff --git a/src/View/Modals/connectionModal.tsx b/src/View/Modals/connectionModal.tsx index fc220fb1..7e8913c7 100644 --- a/src/View/Modals/connectionModal.tsx +++ b/src/View/Modals/connectionModal.tsx @@ -1,5 +1,5 @@ -import * as React from "../../react"; import { DeletableListItem } from "../Components/deletableListItem"; +import * as React from "../../react"; import CoreViewModel from "../../ViewModel/Global/coreViewModel"; import ConnectionViewModel from "../../ViewModel/Global/connectionViewModel"; diff --git a/src/View/Modals/dataTransferModal.tsx b/src/View/Modals/dataTransferModal.tsx index cc3d8eec..72ff8eac 100644 --- a/src/View/Modals/dataTransferModal.tsx +++ b/src/View/Modals/dataTransferModal.tsx @@ -1,6 +1,6 @@ -import * as React from "../../react"; import { ViewController } from "../viewController"; import { StringToTextSpan } from "../Components/textSpan"; +import * as React from "../../react"; import FileTransferViewModel, { FileTransferModals, FileTransferOption, @@ -758,7 +758,9 @@ function ExportModal( @@ -777,36 +779,38 @@ function ExportModal( bind:value={ fileTransferViewModel.exportKeyConfirmation } - on:enter={fileTransferViewModel.downloadFile} - type="password" - > - - - - -
- - -
- - + on:enter={ + fileTransferViewModel.downloadFile + } + type="password" + > + + + + +
+ + +
+ + ); } @@ -815,57 +819,57 @@ function ImportModal( fileTransferViewModel: FileTransferViewModel, ) { const isPresented = React.createProxyState( - [fileTransferViewModel.presentedModal], - () => - fileTransferViewModel.presentedModal.value == - FileTransferModals.ImportSelection, + [fileTransferViewModel.presentedModal], + () => + fileTransferViewModel.presentedModal.value == + FileTransferModals.ImportSelection, ); return ( - +
+ + +
+ + ); } @@ -874,74 +878,76 @@ function ImportDecryptionDataModal( fileTransferViewModel: FileTransferViewModel, ) { const isPresented = React.createProxyState( - [fileTransferViewModel.presentedModal], - () => - fileTransferViewModel.presentedModal.value == - FileTransferModals.ImportDecryptData, + [fileTransferViewModel.presentedModal], + () => + fileTransferViewModel.presentedModal.value == + FileTransferModals.ImportDecryptData, ); return ( - ); } diff --git a/src/View/Modals/messageFilterModal.tsx b/src/View/Modals/messageFilterModal.tsx index 81d5fc37..e288755a 100644 --- a/src/View/Modals/messageFilterModal.tsx +++ b/src/View/Modals/messageFilterModal.tsx @@ -1,6 +1,6 @@ -import * as React from "../../react"; import { ViewController } from "../viewController"; import { MessageReactionFilterButton } from "../Components/messageReactionFilterButton"; +import * as React from "../../react"; import MessagePageViewModel from "../../ViewModel/Pages/messagePageViewModel"; import CoreViewModel from "../../ViewModel/Global/coreViewModel"; import { ReactionSymbols } from "../../Model/Chat/chatModel"; diff --git a/src/View/Modals/searchModal.tsx b/src/View/Modals/searchModal.tsx index 94da4ec8..936534da 100644 --- a/src/View/Modals/searchModal.tsx +++ b/src/View/Modals/searchModal.tsx @@ -1,7 +1,7 @@ import { v4 } from "uuid"; -import * as React from "../../react"; import { ViewController } from "../viewController"; import { StringToOption } from "../Components/option"; +import * as React from "../../react"; import SearchViewModel from "../../ViewModel/Utility/searchViewModel"; import CoreViewModel from "../../ViewModel/Global/coreViewModel"; @@ -29,8 +29,8 @@ export function SearchModal(

{headline}

(
-
-
-

{coreViewModel.translations.general.searchSuggestionsLabel}

-
SuggestionView(suggestion, searchViewModel, coreViewModel), - ]} - >
-
- - - - +
+
+

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

+
+ SuggestionView( + suggestion, + searchViewModel, + coreViewModel, + ), + ]} + >
+
+ + + + ); } -function SuggestionView(suggestion: string, searchViewModel: SearchViewModel, coreViewModel: CoreViewModel) { - const isApplied = React.createProxyState([searchViewModel.appliedQuery], ()=>searchViewModel.appliedQuery.value == suggestion); +function SuggestionView( + suggestion: string, + searchViewModel: SearchViewModel, + coreViewModel: CoreViewModel, +) { + const isApplied = React.createProxyState( + [searchViewModel.appliedQuery], + () => searchViewModel.appliedQuery.value == suggestion, + ); function deleteSuggestion() { - searchViewModel.deleteSuggestion(suggestion); + searchViewModel.deleteSuggestion(suggestion); } function applySuggestion() { - searchViewModel.search(suggestion); + searchViewModel.search(suggestion); } - return
- {suggestion} - - -
+ return ( +
+ {suggestion} + + +
+ ); } diff --git a/src/View/Modals/settingsModal.tsx b/src/View/Modals/settingsModal.tsx index 871dc700..5095df8e 100644 --- a/src/View/Modals/settingsModal.tsx +++ b/src/View/Modals/settingsModal.tsx @@ -1,10 +1,10 @@ -import * as React from "../../react"; import { SplitModal } from "./splitModal"; import { languageNames } from "../translations"; import { PlaceholderView } from "../Components/placeholderView"; import { OptionButtonList } from "../Components/optionButtonList"; import { NavigationButton } from "../Components/navigationButton"; import { InfoTile } from "../Components/infoTile"; +import * as React from "../../react"; import SettingsViewModel, { SettingsModalPages, } from "../../ViewModel/Global/settingsViewModel"; diff --git a/src/View/Modals/splitModal.tsx b/src/View/Modals/splitModal.tsx index 16e36993..9151a984 100644 --- a/src/View/Modals/splitModal.tsx +++ b/src/View/Modals/splitModal.tsx @@ -1,5 +1,5 @@ -import * as React from "../../react"; import "./splitModal.css"; +import * as React from "../../react"; import CoreViewModel from "../../ViewModel/Global/coreViewModel"; export function SplitModal( @@ -10,7 +10,7 @@ export function SplitModal( navigationState?: React.State, ) { function closePage() { - if (!navigationState) return; + if (!navigationState) return; navigationState.value = undefined; } diff --git a/src/View/Modals/storageModal.tsx b/src/View/Modals/storageModal.tsx index abd430be..d1169e12 100644 --- a/src/View/Modals/storageModal.tsx +++ b/src/View/Modals/storageModal.tsx @@ -1,7 +1,7 @@ -import * as React from "../../react"; import { SplitModal } from "./splitModal"; 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"; diff --git a/src/View/Modals/taskSettingsModal.tsx b/src/View/Modals/taskSettingsModal.tsx index a59dde04..b50a1007 100644 --- a/src/View/Modals/taskSettingsModal.tsx +++ b/src/View/Modals/taskSettingsModal.tsx @@ -1,5 +1,4 @@ import { v4 } from "uuid"; -import * as React from "../../react"; import { Entry, Option, @@ -7,6 +6,7 @@ import { VersionIdToOption, } from "../Components/option"; import { DangerousActionButton } from "../Components/dangerousActionButton"; +import * as React from "../../react"; import TaskViewModel from "../../ViewModel/Pages/taskViewModel"; import CoreViewModel from "../../ViewModel/Global/coreViewModel"; @@ -18,264 +18,269 @@ export function TaskSettingsModal( const statusSuggestionId = v4(); const BoardOptionConverter: React.StateItemConverter = ( - entry: Entry, + entry: Entry, ) => { - const isSelected = entry[0] == taskViewModel.task.boardId; - return Option(entry[1], entry[0], isSelected); + const isSelected = entry[0] == taskViewModel.task.boardId; + return Option(entry[1], entry[0], isSelected); }; return ( - -); +
+ {DangerousActionButton( + coreViewModel, + coreViewModel.translations.chatPage.task + .deleteTaskButton, + "delete_forever", + taskViewModel.deleteTask, + )} +
+ +
+ +
+
+ +
+
+ + +
+ + + ); } diff --git a/src/View/chatPage.css b/src/View/chatPage.css index e3179cd6..f79cbb27 100644 --- a/src/View/chatPage.css +++ b/src/View/chatPage.css @@ -65,9 +65,9 @@ body[showing-chat] #chat-page-wrapper { overflow: hidden; } -@media (pointer: coarse) and (max-width: 480px){ +@media (pointer: coarse) and (max-width: 480px) { #chat-page > div > #main > div > .pane-wrapper > .pane { - flex-direction: column-reverse; + flex-direction: column-reverse; } } @@ -78,13 +78,13 @@ body[showing-chat] #chat-page-wrapper { @media (min-width: 1024px) { #chat-page > div > #main > div > .pane-wrapper { - min-width: unset; + min-width: unset; } #chat-page > div > #main > div > .pane-wrapper.side { - width: 18rem; - min-width: 18rem; - max-width: 18rem; + width: 18rem; + min-width: 18rem; + max-width: 18rem; } } @@ -114,21 +114,21 @@ body[showing-chat] #chat-page-wrapper { #chat-page > div > #ribbon > span, #chat-page -> div -> #main -> div -> .pane-wrapper -> .pane -> .toolbar -> span.ribbon { + > div + > #main + > div + > .pane-wrapper + > .pane + > .toolbar + > span.ribbon { gap: var(--gap-between-tiles); padding: var(--gap-between-tiles); } -@media (pointer: coarse) and (max-width: 480px){ -#chat-page > div > #ribbon #close-button { - order: 1; -} +@media (pointer: coarse) and (max-width: 480px) { + #chat-page > div > #ribbon #close-button { + order: 1; + } } #chat-page > div > #main > div > .pane-wrapper > .pane > .toolbar { @@ -192,13 +192,13 @@ body[showing-chat] #chat-page-wrapper { #chat-page > div > #ribbon button.ribbon-button, #chat-page -> div -> #main -> div -> .pane-wrapper -> .pane -> .toolbar -button.ribbon-button { + > div + > #main + > div + > .pane-wrapper + > .pane + > .toolbar + button.ribbon-button { min-width: calc(var(--control-height) - 2 * var(--gap-between-tiles)); width: calc(var(--control-height) - 2 * var(--gap-between-tiles)); max-width: calc(var(--control-height) - 2 * var(--gap-between-tiles)); @@ -211,14 +211,14 @@ button.ribbon-button { #chat-page > div > #ribbon button > .icon, #chat-page -> div -> #main -> div -> .pane-wrapper -> .pane -> .toolbar -button -> .icon { + > div + > #main + > div + > .pane-wrapper + > .pane + > .toolbar + button + > .icon { font-size: 1.1rem; } @@ -244,13 +244,13 @@ button } #chat-page -> div -> #main -> div -> .pane-wrapper -> .pane -> .toolbar -:is(input, select, button) { + > div + > #main + > div + > .pane-wrapper + > .pane + > .toolbar + :is(input, select, button) { height: 100%; flex: 1; } @@ -262,18 +262,19 @@ button @media (min-width: 640px) { .modal.task-settings .column-wrapper { - display: flex; - flex-direction: row; - gap: var(--content-padding); + display: flex; + flex-direction: row; + gap: var(--content-padding); } - .modal.task-settings .column-wrapper > .flex-column{ - width: 100%; - flex: 1; + .modal.task-settings .column-wrapper > .flex-column { + width: 100%; + flex: 1; } } -.modal.task-settings:not([full-description]) :is(#fullscreen-exit, #fullscreen-main) { +.modal.task-settings:not([full-description]) + :is(#fullscreen-exit, #fullscreen-main) { display: none; } diff --git a/src/View/chatPage.tsx b/src/View/chatPage.tsx index e612759e..dbf830cd 100644 --- a/src/View/chatPage.tsx +++ b/src/View/chatPage.tsx @@ -1,4 +1,3 @@ -import * as React from "../react"; import { ViewController } from "./viewController"; import "./homePage.css"; import { ChatViewToggleButton } from "./Components/chatViewToggleButton"; @@ -6,6 +5,7 @@ import { TaskPage } from "./ChatPages/taskPage"; import { SettingsPage } from "./ChatPages/settingsPage"; import { MessagePage } from "./ChatPages/messagePage"; import { CalendarPage } from "./ChatPages/calendarPage"; +import * as React from "../react"; import CoreViewModel from "../ViewModel/Global/coreViewModel"; import ChatViewModel, { ChatPageTypes } from "../ViewModel/Chat/chatViewModel"; @@ -73,8 +73,8 @@ export function ChatPage(
+ toggle:disabled={ + chatViewModel.connectionViewModel + .hasNoPreviousConnections + } + > + signal_disconnected + - + - - {ChatViewToggleButton( - coreViewModel.translations.chatPage.pages.calendar, - "calendar_month", - ChatPageTypes.Calendar, - chatViewModel, - )} - {ChatViewToggleButton( - coreViewModel.translations.chatPage.pages.tasks, - "task_alt", - ChatPageTypes.Tasks, - chatViewModel, - )} - {ChatViewToggleButton( - coreViewModel.translations.chatPage.pages.messages, - "forum", - ChatPageTypes.Messages, - chatViewModel, - )} - {ChatViewToggleButton( - coreViewModel.translations.chatPage.pages.settings, - "settings", - ChatPageTypes.Settings, - chatViewModel, - )} - -
-
-
- + + {ChatViewToggleButton( + coreViewModel.translations.chatPage.pages.calendar, + "calendar_month", + ChatPageTypes.Calendar, + chatViewModel, + )} + {ChatViewToggleButton( + coreViewModel.translations.chatPage.pages.tasks, + "task_alt", + ChatPageTypes.Tasks, + chatViewModel, + )} + {ChatViewToggleButton( + coreViewModel.translations.chatPage.pages.messages, + "forum", + ChatPageTypes.Messages, + chatViewModel, + )} + {ChatViewToggleButton( + coreViewModel.translations.chatPage.pages.settings, + "settings", + ChatPageTypes.Settings, + chatViewModel, + )} + + +
+ + ); } diff --git a/src/View/chatPageWrapper.tsx b/src/View/chatPageWrapper.tsx index b2189ff2..057d520f 100644 --- a/src/View/chatPageWrapper.tsx +++ b/src/View/chatPageWrapper.tsx @@ -1,6 +1,6 @@ -import * as React from "../react"; import "./chatPage.css"; import { ChatPage } from "./chatPage"; +import * as React from "../react"; import CoreViewModel from "../ViewModel/Global/coreViewModel"; import ChatListViewModel from "../ViewModel/Chat/chatListViewModel"; diff --git a/src/View/homePage.tsx b/src/View/homePage.tsx index a45143eb..7c27676a 100644 --- a/src/View/homePage.tsx +++ b/src/View/homePage.tsx @@ -1,8 +1,8 @@ -import * as React from "../react"; import "./homePage.css"; import { StringToOption } from "./Components/option"; import { HomePageButton } from "./Components/homePageButton"; import { ChatViewModelToChatEntry } from "./Components/chatEntry"; +import * as React from "../react"; import StorageViewModel from "../ViewModel/Global/storageViewModel"; import SettingsViewModel from "../ViewModel/Global/settingsViewModel"; import FileTransferViewModel from "../ViewModel/Global/fileTransferViewModel"; diff --git a/src/View/translations.ts b/src/View/translations.ts index e9476b98..c659972a 100644 --- a/src/View/translations.ts +++ b/src/View/translations.ts @@ -9,13 +9,13 @@ const englishTranslations = { searchButtonClearAudioLabel: "clear search query", abortButton: "Abort", - applyButton: "Apply", + applyButton: "Apply", backButton: "Back", cancelButton: "Cancel", closeButton: "Close", - deleteButton: "Delete", - exitButton: "Exit", - fullscreenButton: "Fullscreen", + deleteButton: "Delete", + exitButton: "Exit", + fullscreenButton: "Fullscreen", continueButton: "Continue", confirmButton: "Confirm", @@ -26,7 +26,7 @@ const englishTranslations = { fileVersionLabel: "Version", searchLabel: "Search", - searchSuggestionsLabel: "Recent searches", + searchSuggestionsLabel: "Recent searches", waitingLabel: "Waiting...", restoreConnection: "Restore connection", @@ -89,7 +89,7 @@ const englishTranslations = { info: "About Comms", }, themes: { - dynamic: "Dynamic", + dynamic: "Dynamic", dark: "Dark", light: "Light", system: "Device theme", @@ -342,604 +342,604 @@ export const allTranslations: { }, general: { - deleteItemButtonAudioLabel: "element löschen", - searchButtonAudioLabel: "suchen", - searchButtonClearAudioLabel: "suche zurücksetzen", - - abortButton: "Abbrechen", - applyButton: "Anwenden", - backButton: "Zurück", - cancelButton: "Abbrechen", - closeButton: "Schließen", - deleteButton: "Löschen", - exitButton: "Schließen", - fullscreenButton: "Vollbild", - - continueButton: "Weiter", - confirmButton: "Bestätigen", - saveButton: "Speichern", - setButton: "OK", - - 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: "Comms", - - 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", - - 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 Comms", - }, - themes: { - dynamic: "Dynamisch", - dark: "Dunkel", - light: "Hell", - system: "Geräteeinstellung", - }, - - version: "Version", - language: "Sprache", - - firstDayOfWeekLabel: "Erster Wochentag", - }, - - 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)", - - 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", - }, + deleteItemButtonAudioLabel: "element löschen", + searchButtonAudioLabel: "suchen", + searchButtonClearAudioLabel: "suche zurücksetzen", + + abortButton: "Abbrechen", + applyButton: "Anwenden", + backButton: "Zurück", + cancelButton: "Abbrechen", + closeButton: "Schließen", + deleteButton: "Löschen", + exitButton: "Schließen", + fullscreenButton: "Vollbild", + + continueButton: "Weiter", + confirmButton: "Bestätigen", + saveButton: "Speichern", + setButton: "OK", + + 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: "Comms", + + 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", + + 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 Comms", + }, + themes: { + dynamic: "Dynamisch", + dark: "Dunkel", + light: "Hell", + system: "Geräteeinstellung", + }, + + version: "Version", + language: "Sprache", + + firstDayOfWeekLabel: "Erster Wochentag", + }, + + 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)", + + 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", - - primaryChannelLabel: "Hauptkanal", - setPrimaryChannelButtonAudioLabel: "Hauptkanal festlegen", - - namespaceLabel: "Namensraum", - namespacePlaceholder: "Ohne Namensraum", - setNamespaceButtonAudioLabel: "Namensraum festlegen", + settings: { + settingsHeadline: "Einstellungen", + + primaryChannelLabel: "Hauptkanal", + setPrimaryChannelButtonAudioLabel: "Hauptkanal festlegen", + + namespaceLabel: "Namensraum", + namespacePlaceholder: "Ohne Namensraum", + setNamespaceButtonAudioLabel: "Namensraum festlegen", - newSecondaryChannelPlaceholder: "Sekundären Kanal hinzufügen", - newSecondaryChannelAudioLabel: - "Name des neuen sekundären Kanals", - addSecondaryChannelButtonAudioLabel: - "Sekundären Kanal hinzufügen", + newSecondaryChannelPlaceholder: "Sekundären Kanal hinzufügen", + newSecondaryChannelAudioLabel: + "Name des neuen sekundären Kanals", + addSecondaryChannelButtonAudioLabel: + "Sekundären Kanal hinzufügen", - encryptionKeyLabel: "Schlüssel", - setEncryptionKeyButtonAudioLabel: "Schlüssel festlegen", - showEncryptionKey: "Schlüssel anzeigen", + encryptionKeyLabel: "Schlüssel", + setEncryptionKeyButtonAudioLabel: "Schlüssel festlegen", + showEncryptionKey: "Schlüssel anzeigen", - deleteChatButton: "Gesamten Chat löschen", - }, + deleteChatButton: "Gesamten Chat löschen", + }, - message: { - messagesHeadline: "Nachrichten", + message: { + messagesHeadline: "Nachrichten", - messageFilterHeadline: "Nachrichten filtern", - messageFilterReactionsHadline: "Reaktionen", - messageFilterAllReactionsButton: "Alle anzeigen", + messageFilterHeadline: "Nachrichten filtern", + messageFilterReactionsHadline: "Reaktionen", + messageFilterAllReactionsButton: "Alle anzeigen", - composerInputPlaceholder: "Schreib eine Nachricht...", - sendMessageButtonAudioLabel: "nachricht senden", - filterMessagesButtonAudioLabel: "nachrichten filtern", + composerInputPlaceholder: "Schreib eine Nachricht...", + sendMessageButtonAudioLabel: "nachricht senden", + filterMessagesButtonAudioLabel: "nachrichten filtern", - showMessageInfoButtonAudioLabel: "nachrichteninfo anzeigen", - messageInfoHeadline: "Nachrichteninfo", - cancelReplyAudioLabel: "antwort abbrechen", + showMessageInfoButtonAudioLabel: "nachrichteninfo anzeigen", + messageInfoHeadline: "Nachrichteninfo", + cancelReplyAudioLabel: "antwort abbrechen", - sentBy: "Gesendet von", - timeSent: "Sendezeit", - channel: "Kanal", - messageContent: "Nachrichteninhalt", + 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", + 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", - }, + 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", + task: { + newBoardNamePlaceholder: "Board erstellen", + createBoardButtonAudioLabel: "board erstellen", - noBoardSelected: "Kein Board ausgewählt", - boardNotFound: "Board nicht gefunden", + noBoardSelected: "Kein Board ausgewählt", + boardNotFound: "Board nicht gefunden", - closeBoardButtonAudioLabel: "board schließen", - toggleBoardButtonAudioLabel: "board-liste ein/ausblenden", - showBoardSettingsButtonAudioLabel: - "Board-Einstellungen anzeigen", + closeBoardButtonAudioLabel: "board schließen", + toggleBoardButtonAudioLabel: "board-liste ein/ausblenden", + showBoardSettingsButtonAudioLabel: + "Board-Einstellungen anzeigen", - listViewButtonAudioLabel: "Listenansicht", - kanbanViewButtonAudioLabel: "Kanban-Ansicht", - statusViewButtonAudioLabel: "Statusrasteransicht", + listViewButtonAudioLabel: "Listenansicht", + kanbanViewButtonAudioLabel: "Kanban-Ansicht", + statusViewButtonAudioLabel: "Statusrasteransicht", - filterTasksButtonAudioLabel: "Aufgaben filtern", - createTaskButtonAudioLabel: "Neue Aufgabe erstellen", + filterTasksButtonAudioLabel: "Aufgaben filtern", + createTaskButtonAudioLabel: "Neue Aufgabe erstellen", - boardSettingsHeadline: "Board-Einstellungen", - boardNameInputLabel: "Boardname", - deleteBoardButton: "Board und alle Aufgaben löschen", + boardSettingsHeadline: "Board-Einstellungen", + boardNameInputLabel: "Boardname", + deleteBoardButton: "Board und alle Aufgaben löschen", - taskSettingsHeadline: "Aufgabe bearbeiten", + taskSettingsHeadline: "Aufgabe bearbeiten", - taskNameLabel: "Titel", - taskBoardLabel: "Board", + taskNameLabel: "Titel", + taskBoardLabel: "Board", - taskCategoryLabel: "Kategorie", - taskStatusLabel: "Status", - taskPriorityLabel: "Priorität", + taskCategoryLabel: "Kategorie", + taskStatusLabel: "Status", + taskPriorityLabel: "Priorität", - taskDescriptionLabel: "Beschreibung", + taskDescriptionLabel: "Beschreibung", - taskDateLabel: "Datum", - taskTimeLabel: "Uhrzeit", + taskDateLabel: "Datum", + taskTimeLabel: "Uhrzeit", - deleteTaskButton: "Aufgabe löschen", + deleteTaskButton: "Aufgabe löschen", - filterTasksHeadline: "Aufgaben filtern", + filterTasksHeadline: "Aufgaben filtern", - renameCategoryInputPlaceholder: "Kategorie umbenennen", - renameStatusInputPlaceholder: "Status umbenennen", - }, + renameCategoryInputPlaceholder: "Kategorie umbenennen", + renameStatusInputPlaceholder: "Status umbenennen", + }, - calendar: { - eventsBoard: "Ereignisse", + calendar: { + eventsBoard: "Ereignisse", - /// + /// - todayButtonAudioLabel: "gehe zu heute", + todayButtonAudioLabel: "gehe zu heute", - previousMonthButtonAudioLabel: "vorheriger monat", - nextMonthButtonAudioLabel: "nächster monat", + previousMonthButtonAudioLabel: "vorheriger monat", + nextMonthButtonAudioLabel: "nächster monat", - yearInputAudioLabel: "Jahr", - monthInputAudioLabel: "Monat", + yearInputAudioLabel: "Jahr", + monthInputAudioLabel: "Monat", - yearInputPlaceholder: "2000", - monthInputPlaceholder: "01", + yearInputPlaceholder: "2000", + monthInputPlaceholder: "01", - searchEventsHeadline: "Ereignisse suchen", + searchEventsHeadline: "Ereignisse suchen", - events: "Ereignisse", - noEvents: "Keine Ereignisse", - }, - }, + events: "Ereignisse", + noEvents: "Keine Ereignisse", + }, + }, }, es: { - updater: { - migrated: "Migrado", - }, - - general: { - deleteItemButtonAudioLabel: "eliminar elemento", - searchButtonAudioLabel: "buscar", - searchButtonClearAudioLabel: "borrar büsqueda", - - abortButton: "Abortar", - applyButton: "Guardar", - backButton: "Atrás", - cancelButton: "Cancelar", - closeButton: "Cerrar", - deleteButton: "Borrar", - exitButton: "Salir", - fullscreenButton: "Pantalla completa", - - continueButton: "Continuar", - confirmButton: "Confirmar", - saveButton: "Guardar", - setButton: "OK", - - 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: "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: { - dynamic: "Dinámico", - 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", + updater: { + migrated: "Migrado", + }, + + general: { + deleteItemButtonAudioLabel: "eliminar elemento", + searchButtonAudioLabel: "buscar", + searchButtonClearAudioLabel: "borrar büsqueda", + + abortButton: "Abortar", + applyButton: "Guardar", + backButton: "Atrás", + cancelButton: "Cancelar", + closeButton: "Cerrar", + deleteButton: "Borrar", + exitButton: "Salir", + fullscreenButton: "Pantalla completa", + + continueButton: "Continuar", + confirmButton: "Confirmar", + saveButton: "Guardar", + setButton: "OK", + + 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: "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: { + dynamic: "Dinámico", + 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", - encryptionKeyLabel: "Clave de encriptación", - setEncryptionKeyButtonAudioLabel: - "establecer clave de encriptación", - showEncryptionKey: "Mostrar clave de encriptación", + encryptionKeyLabel: "Clave de encriptación", + setEncryptionKeyButtonAudioLabel: + "establecer clave de encriptación", + showEncryptionKey: "Mostrar clave de encriptación", - deleteChatButton: "Eliminar todo el chat", - }, + deleteChatButton: "Eliminar todo el chat", + }, - message: { - messagesHeadline: "Mensajes", + message: { + messagesHeadline: "Mensajes", - messageFilterHeadline: "Filtrar mensajes", - messageFilterReactionsHadline: "Reacciones", - messageFilterAllReactionsButton: "Mostrar todas", + messageFilterHeadline: "Filtrar mensajes", + messageFilterReactionsHadline: "Reacciones", + messageFilterAllReactionsButton: "Mostrar todas", - composerInputPlaceholder: "Escribe un mensaje...", - sendMessageButtonAudioLabel: "enviar mensaje", - filterMessagesButtonAudioLabel: "filtrar mensajes", + 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", + 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", + sentBy: "Enviado por", + timeSent: "Hora de envío", + channel: "Canal", + messageContent: "Contenido del mensaje", - copyMessageButton: "Copiar mensaje", - resendMessageButton: "Reenviar mensaje", - decryptMessageButton: "Desencriptar mensaje", - replyToMessageButton: "Responder al mensaje", - deleteMessageButton: "Eliminar mensaje", + copyMessageButton: "Copiar mensaje", + resendMessageButton: "Reenviar mensaje", + decryptMessageButton: "Desencriptar mensaje", + replyToMessageButton: "Responder al mensaje", + deleteMessageButton: "Eliminar 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", - }, + 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", + }, - task: { - newBoardNamePlaceholder: "Crear un tablero", - createBoardButtonAudioLabel: "crear tablero", + task: { + newBoardNamePlaceholder: "Crear un tablero", + createBoardButtonAudioLabel: "crear tablero", - noBoardSelected: "Ningún tablero seleccionado", - boardNotFound: "Tablero no encontrado", + 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", + closeBoardButtonAudioLabel: "cerrar tablero", + toggleBoardButtonAudioLabel: + "mostrar o ocultar lista de tableros", + showBoardSettingsButtonAudioLabel: + "mostrar configuración del tablero", - listViewButtonAudioLabel: "vista de lista", - kanbanViewButtonAudioLabel: "vista kanban", - statusViewButtonAudioLabel: "vista de cuadrícula de estado", + listViewButtonAudioLabel: "vista de lista", + kanbanViewButtonAudioLabel: "vista kanban", + statusViewButtonAudioLabel: "vista de cuadrícula de estado", - filterTasksButtonAudioLabel: "filtrar tareas", - createTaskButtonAudioLabel: "crear nueva tarea", + filterTasksButtonAudioLabel: "filtrar tareas", + createTaskButtonAudioLabel: "crear nueva tarea", - boardSettingsHeadline: "Configuración del Tablero", - boardNameInputLabel: "Nombre del tablero", - deleteBoardButton: "Eliminar tablero y todas las tareas", + boardSettingsHeadline: "Configuración del Tablero", + boardNameInputLabel: "Nombre del tablero", + deleteBoardButton: "Eliminar tablero y todas las tareas", - taskSettingsHeadline: "Editar Tarea", + taskSettingsHeadline: "Editar Tarea", - taskNameLabel: "Título", - taskBoardLabel: "Tablero", + taskNameLabel: "Título", + taskBoardLabel: "Tablero", - taskCategoryLabel: "Categoría", - taskStatusLabel: "Estado", - taskPriorityLabel: "Prioridad", + taskCategoryLabel: "Categoría", + taskStatusLabel: "Estado", + taskPriorityLabel: "Prioridad", - taskDescriptionLabel: "Descripción", + taskDescriptionLabel: "Descripción", - taskDateLabel: "Fecha", - taskTimeLabel: "Hora", + taskDateLabel: "Fecha", + taskTimeLabel: "Hora", - deleteTaskButton: "Eliminar tarea", + deleteTaskButton: "Eliminar tarea", - filterTasksHeadline: "Filtrar Tareas", + filterTasksHeadline: "Filtrar Tareas", - renameCategoryInputPlaceholder: "Renombrar categoría", - renameStatusInputPlaceholder: "Renombrar estado", - }, + renameCategoryInputPlaceholder: "Renombrar categoría", + renameStatusInputPlaceholder: "Renombrar estado", + }, - calendar: { - eventsBoard: "Eventos", + calendar: { + eventsBoard: "Eventos", - /// + /// - todayButtonAudioLabel: "ir a hoy", + todayButtonAudioLabel: "ir a hoy", - previousMonthButtonAudioLabel: "mes anterior", - nextMonthButtonAudioLabel: "mes siguiente", + previousMonthButtonAudioLabel: "mes anterior", + nextMonthButtonAudioLabel: "mes siguiente", - yearInputAudioLabel: "año", - monthInputAudioLabel: "mes", + yearInputAudioLabel: "año", + monthInputAudioLabel: "mes", - yearInputPlaceholder: "2000", - monthInputPlaceholder: "01", + yearInputPlaceholder: "2000", + monthInputPlaceholder: "01", - searchEventsHeadline: "Buscar Eventos", + 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 6c8f1f56..7eaa8ec3 100644 --- a/src/View/viewController.ts +++ b/src/View/viewController.ts @@ -7,7 +7,7 @@ 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)!; } diff --git a/src/ViewModel/Chat/chatListViewModel.ts b/src/ViewModel/Chat/chatListViewModel.ts index 358c05c9..cf62d219 100644 --- a/src/ViewModel/Chat/chatListViewModel.ts +++ b/src/ViewModel/Chat/chatListViewModel.ts @@ -1,9 +1,9 @@ -import * as React from "../../react"; import ChatViewModel from "./chatViewModel"; import SettingsViewModel from "../Global/settingsViewModel"; import NotificationViewModel from "../Global/notificationViewModel"; import CoreViewModel from "../Global/coreViewModel"; import ConnectionViewModel from "../Global/connectionViewModel"; +import * as React from "../../react"; import { IndexManager } from "../../Model/Utility/utility"; import ChatModel from "../../Model/Chat/chatModel"; diff --git a/src/ViewModel/Chat/chatMessageViewModel.ts b/src/ViewModel/Chat/chatMessageViewModel.ts index de499e5a..54542567 100644 --- a/src/ViewModel/Chat/chatMessageViewModel.ts +++ b/src/ViewModel/Chat/chatMessageViewModel.ts @@ -1,6 +1,6 @@ -import * as React from "../../react"; import MessagePageViewModel from "../Pages/messagePageViewModel"; import CoreViewModel from "../Global/coreViewModel"; +import * as React from "../../react"; import { ChatMessage, ChatMessageReaction, diff --git a/src/ViewModel/Chat/chatViewModel.ts b/src/ViewModel/Chat/chatViewModel.ts index a960fa49..97876f6b 100644 --- a/src/ViewModel/Chat/chatViewModel.ts +++ b/src/ViewModel/Chat/chatViewModel.ts @@ -1,4 +1,3 @@ -import * as React from "../../react"; import ChatListViewModel from "./chatListViewModel"; import TaskPageViewModel from "../Pages/taskPageViewModel"; import SettingsPageViewModel from "../Pages/settingsPageViewModel"; @@ -10,6 +9,7 @@ import SettingsViewModel from "../Global/settingsViewModel"; import NotificationViewModel from "../Global/notificationViewModel"; import CoreViewModel, { Context, ContextHost } from "../Global/coreViewModel"; import ConnectionViewModel from "../Global/connectionViewModel"; +import * as React from "../../react"; import { Colors } from "../../colors"; import { CommonKeys } from "../../View/keystrokes"; import { Entry } from "../../View/Components/option"; diff --git a/src/ViewModel/Global/.connectionViewModel.ts.swp b/src/ViewModel/Global/.connectionViewModel.ts.swp deleted file mode 100644 index 6335601759593a591d81fcf18ecdfa080fff4e7c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12288 zcmeI2O>7%Q6vwAPp#j=L%LS^!)RiI|HR}{41PP7=jzl8}AWDNMaMKi7o$`Xmmgc$3{PH6{U$p(Q!-If1k;jAdCo2*|gE0n10i!^# z0_~_aasPI5?>z_ARNr6NM|bZ!(rag)7zK<1MggOMQNSo*6fg=H1&jj!TLq%l7IGZf zU86H(`g6;=PyN+=7zK<1MggOMQNSo*6fg=H1&jhl0i%FXz$kDPDqy>W?7|=a=dMNY z`2YXp@Bg)(gnR-%1}8xT4uZ=&2>A`X58eYu!L#5|Fb2NcPRM!iHmHI9;P;yexdc80 zr@`~!2-pTL+(gLd;3IGroB=-A1MUFd+(^g?a2z}X?gDp$Tft9bgnR(bfH#2)ir{vz z6YKz&w-NFSxCqw3IdB53fMqZX#=*rK;1B!=z6NiAQ{W^x1h#@7t|#Psa2A{fuY=dX z5_kga0k?tO;L=t?z676vPr)g06x;{?x{i=v!O!3VSOf2X5WEB^_#5N#EjSOp0&0A& z!um2H4^?25P+al9@~$+!y4w4UZ16}o$~Ps_Lvlq8PgvPGnrg!i>g1sH04p8LT2RfkY(p^GHZ2Yr(YlQc7UTkp(R+Pdo7~6^`(Mqw_H17Pll}H z@wRx#bwefu6UEZBvO_;23fm6O3>91LMc;F1$ZVGf{tE4iXo^pMnB>_<23n!T(iH7* z&!v?aw#Wu+z~QvSQ@Dp%QY zrH8D^J4_d9QI~`+r}(#Z#VqC3W>XZ!jBy%1q=RE{J%NcK5630-lRX)2Gza@noOfp@ z1;Q_a`^@rrJxNOEuG>7#wKSVdTV<6xi3eP;u){*_cP?nPqqwrWd+teG#)}ebvZ%pb zoEwziF?9x3nKDv_>7D$hdy==wHA1Oq`LfkQw(V2Gu+3JCWc5n=Dv{(a`P^*p`}%Yr z&!C1avLNJq%Vv=5c=S%Qg;urcH-NN~b&yW)!KJA+rIiY82QI650dunnpU5+!Gf!0G zX~eL+>SZ!>MiOr-hn#J?u8tr`u30RKo+mif+O-?^t6uEba~$*cmO+ql6Cu?5Eeah@z+S{ei@rsz}5b|UL=guVK~MUEA~4rUN?{Mf;kEcbA} zyrL}P8rnG4oF0jcTKM%r<}7u1jvWL%n)O6HX#X}UIlM}a{^ePrh1@GpQV(gvkxI2h zj~yfVrfKs5{dP5oSHYYfnR0T|rQ_qNxvGlvTRhsm-5iMX&Ux%oSdaXs^u>Z(Z`)zA z-u9Gc;`A|3L~%LATcWI{fGz2YN`IC6n@XqOJ5J)Sr!+HXaZRdspv+r3@vqnc#nmfm zx0{V}io+-r^t^yjLQW^bmRmfGDAqE&?MKw{Z6WY7+jI6^zWsSkWn0a^>e5=so3voz dynOEEwJ@C+-%V{1%bHkPWy>mK&N>mS{sE)HMy>z= diff --git a/src/ViewModel/Global/connectionViewModel.ts b/src/ViewModel/Global/connectionViewModel.ts index fdc104cd..587aab05 100644 --- a/src/ViewModel/Global/connectionViewModel.ts +++ b/src/ViewModel/Global/connectionViewModel.ts @@ -1,5 +1,5 @@ -import * as React from "../../react"; import CoreViewModel from "./coreViewModel"; +import * as React from "../../react"; export default class ConnectionViewModel { // state @@ -48,7 +48,7 @@ export default class ConnectionViewModel { ); } - this.hideConnectionModal(); + this.hideConnectionModal(); }; // methods @@ -69,8 +69,8 @@ export default class ConnectionViewModel { this.coreViewModel.connectionModel.removeAddress(address); this.updatePreviousAddresses(); - if (this.previousAddresses.value.size > 0) return; - this.hideConnectionModal(); + if (this.previousAddresses.value.size > 0) return; + this.hideConnectionModal(); }; // view diff --git a/src/ViewModel/Global/coreViewModel.ts b/src/ViewModel/Global/coreViewModel.ts index 47eb68cf..04706dfd 100644 --- a/src/ViewModel/Global/coreViewModel.ts +++ b/src/ViewModel/Global/coreViewModel.ts @@ -40,8 +40,8 @@ export default class CoreViewModel { return; while (this.contexts.length > 0) { - const currentContext: Context|undefined= this.context; - if (!currentContext) return; + const currentContext: Context | undefined = this.context; + if (!currentContext) return; currentContext.handleContextClose(fromHistoryEvent); this.contextStack.delete(currentContext.contextId); if (currentContext.contextId == contextId) break; @@ -49,9 +49,10 @@ export default class CoreViewModel { }; handleKeyDown = (e: KeyboardEvent): void => { - if (!(e instanceof KeyboardEvent)) return console.trace("NOT A KEY EVENT"); + if (!(e instanceof KeyboardEvent)) + return console.trace("NOT A KEY EVENT"); if (CoreViewModel.checkIsKeystroke(e) == false) return; - console.log(e.key); + console.log(e.key); e.preventDefault(); const contexts: Context[] = this.contexts; while (contexts.length > 0) { @@ -97,7 +98,7 @@ export default class CoreViewModel { document.body.addEventListener("keydown", this.handleKeyDown); window.onpopstate = () => { - if (!this.context) return; + if (!this.context) return; this.closeContext(this.context.contextId, true); }; @@ -164,11 +165,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( - selection - ); + 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(); @@ -178,7 +178,10 @@ export class ContextHost extends Context { this.currentContext.value = selectedContext; }; - constructor(contextDebugDescription: string, public coreViewModel: CoreViewModel) { - super(contextDebugDescription); + constructor( + contextDebugDescription: string, + public coreViewModel: CoreViewModel, + ) { + super(contextDebugDescription); } } diff --git a/src/ViewModel/Global/fileTransferViewModel.ts b/src/ViewModel/Global/fileTransferViewModel.ts index 37cc3809..10919ce1 100644 --- a/src/ViewModel/Global/fileTransferViewModel.ts +++ b/src/ViewModel/Global/fileTransferViewModel.ts @@ -1,5 +1,5 @@ -import * as React from "../../react"; import CoreViewModel, { Context } from "./coreViewModel"; +import * as React from "../../react"; import { CommonKeys } from "../../View/keystrokes"; import StorageModel, { StorageModelSubPaths, @@ -54,7 +54,9 @@ 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< + File | undefined + >(undefined); importedFileString: React.State = new React.State(""); importKey: React.State = new React.State(""); isImportKeyCorrect: React.State = new React.State(true); @@ -139,7 +141,7 @@ export default class FileTransferViewModel extends Context { }; downloadFile = async (): Promise => { - if (this.cannotExport.value == true) return; + if (this.cannotExport.value == true) return; const date = new Date().toISOString().split("T")[0]; const backup: Blob = @@ -158,7 +160,7 @@ export default class FileTransferViewModel extends Context { if (!input) return; if (!(input instanceof HTMLInputElement)) return; - if (!input.files) return; + if (!input.files) return; const file = input.files[0]; this.importedFile.value = file; }; @@ -171,7 +173,7 @@ export default class FileTransferViewModel extends Context { reader.readAsText(file, "utf8"); reader.onload = () => { const result = reader.result; - if (!result) return; + 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 75ba0c33..0f90e922 100644 --- a/src/ViewModel/Global/notificationViewModel.ts +++ b/src/ViewModel/Global/notificationViewModel.ts @@ -1,6 +1,6 @@ -import * as React from "../../react"; import { ChatPageTypes } from "../Chat/chatViewModel"; import ChatListViewModel from "../Chat/chatListViewModel"; +import * as React from "../../react"; import ChatModel, { ChatMessage } from "../../Model/Chat/chatModel"; export default class NotificationViewModel { @@ -35,7 +35,7 @@ export default class NotificationViewModel { }; openNotification = () => { - const notification: Notification|undefined = this.marquee.value; + const notification: Notification | undefined = this.marquee.value; if (notification == undefined) return; const chat = [ @@ -44,7 +44,7 @@ export default class NotificationViewModel { (chat) => chat.chatModel.unwrappedPrimaryChannel == notification.chat, ); - if (!chat) return; + if (!chat) return; chat.open(); chat.openPage(ChatPageTypes.Messages); }; @@ -56,8 +56,9 @@ export default class NotificationViewModel { return this.stopLoop(); } - const notification: Notification|undefined = this.messagesInMarquee.shift(); - if (!notification) return; + 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 7836effa..01a6e7d7 100644 --- a/src/ViewModel/Global/settingsViewModel.ts +++ b/src/ViewModel/Global/settingsViewModel.ts @@ -1,5 +1,5 @@ -import * as React from "../../react"; import CoreViewModel, { Context } from "./coreViewModel"; +import * as React from "../../react"; import { CommonKeys } from "../../View/keystrokes"; import { Languages, ThemeSettings } from "../../Model/Global/settingsModel"; @@ -13,12 +13,12 @@ export default class SettingsViewModel extends Context { requiresReload = new React.State(false); firstDayOfWeek: React.State = new React.State("0"); - language: React.State = new React.State( - Languages.English, - ); - theme: React.State = new React.State( - ThemeSettings.System, - ); + language: React.State = new React.State< + Languages | string + >(Languages.English); + theme: React.State = new React.State< + ThemeSettings | string + >(ThemeSettings.System); // guards cannotSetName: React.State = React.createProxyState( @@ -48,121 +48,132 @@ export default class SettingsViewModel extends Context { }; showModalPage = (page: SettingsModalPages): void => { - this.selectedModalPage.value = page; + this.selectedModalPage.value = page; }; // view applyTheme = (): void => { - let theme: string = this.theme.value; + let theme: string = this.theme.value; - if (theme == ThemeSettings.Dynamic) { - const scene = this.selectDynamicScene(); - this.setScene(scene); - return; - } + if (theme == ThemeSettings.Dynamic) { + const scene = this.selectDynamicScene(); + this.setScene(scene); + return; + } - if (theme == ThemeSettings.System) { - theme = SettingsViewModel.getSystemTheme(); - } + if (theme == ThemeSettings.System) { + theme = SettingsViewModel.getSystemTheme(); + } - if (theme == ThemeSettings.Dark) { - this.setScene(DynamicSceneNight); - } else { - this.setScene(DynamicSceneDay); - } + if (theme == ThemeSettings.Dark) { + this.setScene(DynamicSceneNight); + } else { + 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 { @@ -176,40 +187,40 @@ export interface DynamicScene { export const DynamicSceneNight: DynamicScene = { hue1: 215, hue2: 220, - saturation : 50, + saturation: 50, luma: 25, brightness: 0.4, baseTheme: ThemeSettings.Dark, -} +}; export const DynamicSceneSunrise: DynamicScene = { hue1: 45, hue2: 190, - saturation : 100, + saturation: 100, luma: 50, brightness: 1.2, baseTheme: ThemeSettings.Light, -} +}; export const DynamicSceneDay: DynamicScene = { hue1: 190, hue2: 180, - saturation : 100, + saturation: 100, luma: 70, brightness: 1.4, baseTheme: ThemeSettings.Light, -} +}; export const DynamicSceneAfternoon: DynamicScene = { hue1: 195, hue2: 220, - saturation : 100, + saturation: 100, luma: 50, brightness: 0.8, baseTheme: ThemeSettings.Light, -} +}; export const DynamicSceneSunset: DynamicScene = { hue1: 20, hue2: 260, - saturation : 100, + saturation: 100, luma: 50, brightness: 0.4, baseTheme: ThemeSettings.Dark, -} +}; diff --git a/src/ViewModel/Global/storageViewModel.ts b/src/ViewModel/Global/storageViewModel.ts index 8600e1de..4e31623e 100644 --- a/src/ViewModel/Global/storageViewModel.ts +++ b/src/ViewModel/Global/storageViewModel.ts @@ -1,5 +1,5 @@ -import * as React from "../../react"; import CoreViewModel, { Context } from "./coreViewModel"; +import * as React from "../../react"; import { CommonKeys } from "../../View/keystrokes"; import StorageModel, { PATH_COMPONENT_SEPARATOR, diff --git a/src/ViewModel/Pages/.taskPageViewModel.ts.swp b/src/ViewModel/Pages/.taskPageViewModel.ts.swp new file mode 100644 index 0000000000000000000000000000000000000000..a32dc84f9cc4d5793773fb24870d2b08767712a1 GIT binary patch literal 20480 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 { @@ -154,7 +150,7 @@ export default class BoardViewModel extends TaskContainingPageViewModel { this, taskFileContent, ); - console.log("STILL HERE", taskFileContent.fileId); + console.log("STILL HERE", taskFileContent.fileId); this.taskViewModels.set(taskFileContent.fileId, taskViewModel); }; @@ -234,7 +230,7 @@ export default class BoardViewModel extends TaskContainingPageViewModel { const dirPath: string[] = this.getPreviousSearchesPath(); const searches: string[] = this.coreViewModel.storageModel.list(dirPath); - this.searchSuggestions.add(...searches.filter(x => x != "")); + this.searchSuggestions.add(...searches.filter((x) => x != "")); }; restoreSearch = (): void => { @@ -307,13 +303,13 @@ export default class BoardViewModel extends TaskContainingPageViewModel { this.taskViewModels, this.filteredTaskViewModels, TaskViewModel.getStringsForFilter, - this.searchSuggestions, + this.searchSuggestions, ); this.searchViewModel.appliedQuery.subscribeSilent((newQuery) => { this.handleNewSearch(newQuery); }); this.restoreSearch(); - this.searchSuggestions.handleRemovals(this.handleSearchRemoved); + this.searchSuggestions.handleRemovals(this.handleSearchRemoved); this.isFilterActive = React.createProxyState( [this.searchViewModel.appliedQuery], diff --git a/src/ViewModel/Pages/calendarPageViewModel.ts b/src/ViewModel/Pages/calendarPageViewModel.ts index d3d80a04..539cf1cf 100644 --- a/src/ViewModel/Pages/calendarPageViewModel.ts +++ b/src/ViewModel/Pages/calendarPageViewModel.ts @@ -1,8 +1,8 @@ -import * as React from "../../react"; import TaskViewModel from "./taskViewModel"; import TaskContainingPageViewModel from "./taskContainingPageViewModel"; import CoreViewModel from "../Global/coreViewModel"; import ChatViewModel, { ChatPageTypes } from "../Chat/chatViewModel"; +import * as React from "../../react"; import { CommonKeys } from "../../View/keystrokes"; import CalendarModel, { MonthGrid } from "../../Model/Files/calendarModel"; import BoardsAndTasksModel, { diff --git a/src/ViewModel/Pages/messagePageViewModel.ts b/src/ViewModel/Pages/messagePageViewModel.ts index e27a8f7c..32720a6a 100644 --- a/src/ViewModel/Pages/messagePageViewModel.ts +++ b/src/ViewModel/Pages/messagePageViewModel.ts @@ -1,8 +1,8 @@ -import * as React from "../../react"; import SearchViewModel from "../Utility/searchViewModel"; import CoreViewModel, { Context } from "../Global/coreViewModel"; import ChatViewModel, { ChatPageTypes } from "../Chat/chatViewModel"; import ChatMessageViewModel from "../Chat/chatMessageViewModel"; +import * as React from "../../react"; import { CommonKeys } from "../../View/keystrokes"; import { ChatMessage, @@ -68,7 +68,9 @@ export default class MessagePageViewModel extends Context { ); }; - setReply = (chatMessageViewModel: ChatMessageViewModel|undefined): void => { + setReply = ( + chatMessageViewModel: ChatMessageViewModel | undefined, + ): void => { this.replyingMessage.value = chatMessageViewModel; this.setFocus(); }; diff --git a/src/ViewModel/Pages/settingsPageViewModel.ts b/src/ViewModel/Pages/settingsPageViewModel.ts index 4d114f0a..4b7717c5 100644 --- a/src/ViewModel/Pages/settingsPageViewModel.ts +++ b/src/ViewModel/Pages/settingsPageViewModel.ts @@ -1,6 +1,6 @@ -import * as React from "../../react"; import CoreViewModel, { Context } from "../Global/coreViewModel"; import ChatViewModel, { ChatPageTypes } from "../Chat/chatViewModel"; +import * as React from "../../react"; import { Colors } from "../../colors"; export default class SettingsPageViewModel extends Context { diff --git a/src/ViewModel/Pages/taskContainingPageViewModel.ts b/src/ViewModel/Pages/taskContainingPageViewModel.ts index 70a61bec..73c1de15 100644 --- a/src/ViewModel/Pages/taskContainingPageViewModel.ts +++ b/src/ViewModel/Pages/taskContainingPageViewModel.ts @@ -1,7 +1,7 @@ -import * as React from "../../react"; import TaskViewModel from "./taskViewModel"; import CoreViewModel, { Context } from "../Global/coreViewModel"; import ChatViewModel from "../Chat/chatViewModel"; +import * as React from "../../react"; import { IndexManager } from "../../Model/Utility/utility"; import BoardsAndTasksModel, { TaskFileContent, @@ -21,7 +21,6 @@ export default class TaskContainingPageViewModel extends Context { taskCategorySuggestions: React.ListState = new React.ListState(); taskStatusSuggestions: React.ListState = new React.ListState(); - // methods createTaskFromBoardId = (boardId: string): void => { const taskFileContent: TaskFileContent = diff --git a/src/ViewModel/Pages/taskPageViewModel.ts b/src/ViewModel/Pages/taskPageViewModel.ts index fbdfa896..d45d7df8 100644 --- a/src/ViewModel/Pages/taskPageViewModel.ts +++ b/src/ViewModel/Pages/taskPageViewModel.ts @@ -1,9 +1,9 @@ -import * as React from "../../react"; import BoardViewModel from "./boardViewModel"; import CoreViewModel, { ContextHost } from "../Global/coreViewModel"; import ChatViewModel, { ChatPageTypes } from "../Chat/chatViewModel"; +import * as React from "../../react"; import { CommonKeys } from "../../View/keystrokes"; -import { IndexManager } from "../../Model/Utility/utility"; +import implementFilter, { IndexManager } from "../../Model/Utility/utility"; import BoardsAndTasksModel, { BoardInfoFileContent, } from "../../Model/Files/boardsAndTasksModel"; @@ -26,8 +26,9 @@ export default class TaskPageViewModel extends ContextHost { }; // state - newBoardNameInput: React.State = new React.State(""); + boardQuery: React.State = new React.State(""); boardViewModels: React.MapState = new React.MapState(); + boardMatches: React.ListState = new React.ListState(); isShowingBoadList: React.State = new React.State(true); selectedBoardId: React.State = new React.State( undefined, @@ -47,8 +48,8 @@ export default class TaskPageViewModel extends ContextHost { // guards cannotCreateBoard: React.State = React.createProxyState( - [this.newBoardNameInput], - () => this.newBoardNameInput.value == "", + [this.boardQuery], + () => this.boardQuery.value == "", ); // methods @@ -56,8 +57,8 @@ export default class TaskPageViewModel extends ContextHost { if (this.cannotCreateBoard.value == true) return; const boardInfoFileContent: BoardInfoFileContent = - this.boardsAndTasksModel.createBoard(this.newBoardNameInput.value); - this.newBoardNameInput.value = ""; + this.boardsAndTasksModel.createBoard(this.boardQuery.value); + this.boardQuery.value = ""; this.showBoardInList(boardInfoFileContent); this.boardsAndTasksModel.updateBoardAndSend(boardInfoFileContent); @@ -177,6 +178,9 @@ export default class TaskPageViewModel extends ContextHost { this.chatViewModel = chatViewModel; + // filter + implementFilter(this.boardViewModels, this.boardMatches, this.boardQuery, (board) => board.name.value); + // context this.chatViewModel.registerContext(ChatPageTypes.Tasks, this); this.selectedBoardId.subscribeSilent(this.updateContexts); diff --git a/src/ViewModel/Pages/taskViewModel.ts b/src/ViewModel/Pages/taskViewModel.ts index 1f9cf22f..7dd47052 100644 --- a/src/ViewModel/Pages/taskViewModel.ts +++ b/src/ViewModel/Pages/taskViewModel.ts @@ -1,7 +1,7 @@ -import * as React from "../../react"; import TaskContainingPageViewModel from "./taskContainingPageViewModel"; import CoreViewModel, { Context } from "../Global/coreViewModel"; import ChatViewModel from "../Chat/chatViewModel"; +import * as React from "../../react"; import { ViewController } from "../../View/viewController"; import { CommonKeys } from "../../View/keystrokes"; import { localeCompare, padZero } from "../../Model/Utility/utility"; @@ -58,7 +58,9 @@ export default class TaskViewModel extends Context { selectedVersionId: React.State = new React.State(""); versionIds: React.ListState = new React.ListState(); - isPresentingFullScreenDescription: React.State = new React.State(false); + isPresentingFullScreenDescription: React.State = new React.State( + false, + ); // methods dragStart = (event: DragEvent): void => { @@ -99,12 +101,12 @@ export default class TaskViewModel extends Context { }; openFullscreenDecription = (): void => { - this.isPresentingFullScreenDescription.value = true; - } + this.isPresentingFullScreenDescription.value = true; + }; closeFullscreenDecription = (): void => { - this.isPresentingFullScreenDescription.value = false; - } + this.isPresentingFullScreenDescription.value = false; + }; updateIndex = (): void => { const index: number = @@ -118,7 +120,9 @@ export default class TaskViewModel extends Context { this.category.value, ) == false ) { - this.containingViewModel.taskCategorySuggestions.add(this.category.value); + this.containingViewModel.taskCategorySuggestions.add( + this.category.value, + ); } if ( @@ -126,7 +130,9 @@ export default class TaskViewModel extends Context { this.status.value, ) == false ) { - this.containingViewModel.taskStatusSuggestions.add(this.status.value); + this.containingViewModel.taskStatusSuggestions.add( + this.status.value, + ); } }; diff --git a/src/ViewModel/Utility/searchViewModel.ts b/src/ViewModel/Utility/searchViewModel.ts index 9f67825f..a401f8f6 100644 --- a/src/ViewModel/Utility/searchViewModel.ts +++ b/src/ViewModel/Utility/searchViewModel.ts @@ -15,7 +15,10 @@ export default class SearchViewModel { [this.searchInput], () => this.searchInput.value == "", ); - hasNoSuggestions: React.State = React.createProxyState([this.suggestions], ()=>this.suggestions.value.size == 0); + hasNoSuggestions: React.State = React.createProxyState( + [this.suggestions], + () => this.suggestions.value.size == 0, + ); // methods search = (searchTerm: string): void => { @@ -36,12 +39,12 @@ export default class SearchViewModel { }; clear = (): void => { - this.searchInput.value = ""; - } + this.searchInput.value = ""; + }; deleteSuggestion = (suggestion: string): void => { - this.suggestions.remove(suggestion); - } + this.suggestions.remove(suggestion); + }; // init constructor( diff --git a/src/ViewModel/Utility/taskPropertyBulkChangeViewModel.ts b/src/ViewModel/Utility/taskPropertyBulkChangeViewModel.ts index 7a31faf9..5c771da4 100644 --- a/src/ViewModel/Utility/taskPropertyBulkChangeViewModel.ts +++ b/src/ViewModel/Utility/taskPropertyBulkChangeViewModel.ts @@ -1,5 +1,5 @@ -import * as React from "../../react"; import TaskViewModel from "../Pages/taskViewModel"; +import * as React from "../../react"; export default class TaskPropertyBulkChangeViewModel { taskViewModels: React.ListState; diff --git a/src/base.css b/src/base.css index 329bd33c..1b18faf1 100644 --- a/src/base.css +++ b/src/base.css @@ -44,7 +44,9 @@ main { } body { - transition: --sky-1 1s, --sky-2 5s; + transition: + --sky-1 1s, + --sky-2 5s; } #background-wrapper #grass-1 { @@ -52,7 +54,7 @@ body { --color-2: hsl(150, 60%, 25%); filter: var(--backdrop-grass-filter); - opacity: .7; + opacity: 0.7; background-image: linear-gradient( 350deg, @@ -65,9 +67,9 @@ body { #background-wrapper #grass-2 { --color-1: hsl(110, 60%, 40%); --color-2: hsl(110, 60%, 35%); - + filter: var(--backdrop-grass-filter); - opacity: .7; + opacity: 0.7; background-image: linear-gradient( 9deg, diff --git a/src/react.ts b/src/react.ts index 3530a499..2a687838 100755 --- a/src/react.ts +++ b/src/react.ts @@ -85,7 +85,7 @@ export class ListState extends State> { items.forEach((item) => { this.value.delete(item); - this.genericRemovalHandlers.forEach(handler => handler(item)); + this.genericRemovalHandlers.forEach((handler) => handler(item)); if (!this.removalHandlers.has(item)) return; this.removalHandlers.get(item)!.forEach((handler) => handler(item)); this.removalHandlers.delete(item); @@ -146,73 +146,73 @@ export class MapState extends State> { this.value.delete(key); this.callSubscriptions(); - this.genericRemovalHandlers.forEach(handler => handler(item)); - if (!this.removalHandlers.has(item)) return; - this.removalHandlers.get(item)!.forEach((handler) => handler(item)); - this.removalHandlers.delete(item); + this.genericRemovalHandlers.forEach((handler) => handler(item)); + if (!this.removalHandlers.has(item)) return; + this.removalHandlers.get(item)!.forEach((handler) => handler(item)); + this.removalHandlers.delete(item); } clear() { - [...this.value.keys()].forEach((key) => this.remove(key)); + [...this.value.keys()].forEach((key) => this.remove(key)); } // handlers handleAddition(handler: AdditionSubscription): void { - this.additionHandlers.add(handler); - [...this.value.values()].forEach(handler); + this.additionHandlers.add(handler); + [...this.value.values()].forEach(handler); } handleRemoval(item: T, handler: RemovalSubscription): void { - if (!this.removalHandlers.has(item)) - this.removalHandlers.set(item, new Set()); - this.removalHandlers.get(item)!.add(handler); + if (!this.removalHandlers.has(item)) + this.removalHandlers.set(item, new Set()); + this.removalHandlers.get(item)!.add(handler); } handleRemovals(handler: RemovalSubscription): void { - this.genericRemovalHandlers.add(handler); + this.genericRemovalHandlers.add(handler); } // stringification toString(): string { - const array = [...this.value.entries()]; - const json = JSON.stringify(array); - return json; + const array = [...this.value.entries()]; + const json = JSON.stringify(array); + return json; } } // UTILITY export function createProxyState( statesToSubscibe: State[], - fn: () => T + fn: () => T, ): State { const proxyState = new State(fn()); statesToSubscibe.forEach((state) => - state.subscribeSilent(() => (proxyState.value = fn())) + state.subscribeSilent(() => (proxyState.value = fn())), ); return proxyState; } export function bulkSubscribe( statesToSubscibe: State[], - fn: () => void + fn: () => void, ): void { statesToSubscibe.forEach((state) => state.subscribeSilent(fn)); } function persistState(localStorageKey: string, state: State) { state.subscribe(() => { - const stringifiedValue = state.toString(); - localStorage.setItem(localStorageKey, stringifiedValue); + const stringifiedValue = state.toString(); + localStorage.setItem(localStorageKey, stringifiedValue); }); } export function restoreState( localStorageKey: string, - initialStateValue: T + initialStateValue: T, ): State { const storedString = - localStorage.getItem(localStorageKey) ?? - JSON.stringify(initialStateValue); + localStorage.getItem(localStorageKey) ?? + JSON.stringify(initialStateValue); const convertedValue = JSON.parse(storedString); const state = new State(convertedValue); @@ -223,14 +223,14 @@ export function restoreState( export function restoreListState( localStorageKey: string, - initialItems: any[] = [] + initialItems: any[] = [], ): ListState { const storedString = localStorage.getItem(localStorageKey) ?? ""; try { - const array = JSON.parse(storedString); - if (!Array.isArray(array)) throw ""; - initialItems = array; + const array = JSON.parse(storedString); + if (!Array.isArray(array)) throw ""; + initialItems = array; } catch {} const state = new ListState(initialItems); @@ -241,14 +241,14 @@ export function restoreListState( export function restoreMapState( localStorageKey: string, - initialItems: [string, any][] = [] + initialItems: [string, any][] = [], ): MapState { const storedString = localStorage.getItem(localStorageKey) ?? ""; try { - const array = JSON.parse(storedString); - if (!Array.isArray(array)) throw ""; - initialItems = array; + const array = JSON.parse(storedString); + if (!Array.isArray(array)) throw ""; + initialItems = array; } catch {} const state = new MapState(initialItems); @@ -271,115 +271,115 @@ export function createElement( const element = document.createElement(tagName); if (attributes != null) - Object.entries(attributes).forEach((entry) => { - const [attributename, value] = entry; - const [directiveKey, directiveValue] = attributename.split(":"); + Object.entries(attributes).forEach((entry) => { + const [attributename, value] = entry; + const [directiveKey, directiveValue] = attributename.split(":"); - switch (directiveKey) { - case "on": { - switch (directiveValue) { - case "enter": { - element.addEventListener("keydown", (e: Event) => { - if (!(e instanceof KeyboardEvent)) return; - if (e.key != "Enter") return; - value(e); - }); - break; - } - default: { - element.addEventListener(directiveValue, value); - } - } - break; - } - case "keystroke": { - element.addEventListener("keydown", (e: Event) => { - if (!(e instanceof KeyboardEvent)) return; - if (e.metaKey == false && e.ctrlKey == false) return; - if (e.key != directiveValue) return; - value(e); - }) - break; - } - case "subscribe": { - const state = value as State; - state.subscribe( - (newValue) => (element[directiveValue] = newValue) - ); + switch (directiveKey) { + case "on": { + switch (directiveValue) { + case "enter": { + element.addEventListener("keydown", (e: Event) => { + if (!(e instanceof KeyboardEvent)) return; + if (e.key != "Enter") return; + value(e); + }); + break; + } + default: { + element.addEventListener(directiveValue, value); + } + } + break; + } + case "keystroke": { + element.addEventListener("keydown", (e: Event) => { + if (!(e instanceof KeyboardEvent)) return; + if (e.metaKey == false && e.ctrlKey == false) return; + if (e.key != directiveValue) return; + value(e); + }); + break; + } + case "subscribe": { + const state = value as State; + state.subscribe( + (newValue) => (element[directiveValue] = newValue), + ); - break; - } - case "bind": { - const state = value as State; - state.subscribe( - (newValue) => (element[directiveValue] = newValue) - ); - element.addEventListener( - "input", - () => (state.value = (element as any)[directiveValue]) - ); - break; - } - case "toggle": { - if (value.subscribe) { - const state = value as State; - state.subscribe((newValue) => - element.toggleAttribute(directiveValue, newValue) - ); - } else { - element.toggleAttribute(directiveValue, value); - } - break; - } - case "set": { - const state = value as State; - state.subscribe((newValue) => - element.setAttribute(directiveValue, newValue) - ); - break; - } - case "children": { - switch (directiveValue) { - case "set": { - const state = value as State; - state.subscribe((newValue) => { - element.innerHTML = ""; - element.append(...[newValue].flat()); - }); - break; - } - case "append": - case "prepend": { - try { - const [listState, toElement] = value as [ - listState: ListState, - StateItemConverter - ]; + break; + } + case "bind": { + const state = value as State; + state.subscribe( + (newValue) => (element[directiveValue] = newValue), + ); + element.addEventListener( + "input", + () => (state.value = (element as any)[directiveValue]), + ); + break; + } + case "toggle": { + if (value.subscribe) { + const state = value as State; + state.subscribe((newValue) => + element.toggleAttribute(directiveValue, newValue), + ); + } else { + element.toggleAttribute(directiveValue, value); + } + break; + } + case "set": { + const state = value as State; + state.subscribe((newValue) => + element.setAttribute(directiveValue, newValue), + ); + break; + } + case "children": { + switch (directiveValue) { + case "set": { + const state = value as State; + state.subscribe((newValue) => { + element.innerHTML = ""; + element.append(...[newValue].flat()); + }); + break; + } + case "append": + case "prepend": { + try { + const [listState, toElement] = value as [ + listState: ListState, + StateItemConverter, + ]; - listState.handleAddition((newItem) => { - const child = toElement(newItem); - listState.handleRemoval(newItem, () => - child.remove() - ); + listState.handleAddition((newItem) => { + const child = toElement(newItem); + listState.handleRemoval(newItem, () => + child.remove(), + ); - if (directiveValue == "append") { - element.append(child); - } else if (directiveValue == "prepend") { - element.prepend(child); - } - }); - } catch (error) { - console.error(error); - throw `error: cannot process subscribe:children directive. \n Usage: "children:append={[list, converter]}"; you can find a more detailed example in the documentation.`; - } - } - } - break; - } - default: - element.setAttribute(attributename, value); - } - }); + if (directiveValue == "append") { + element.append(child); + } else if (directiveValue == "prepend") { + element.prepend(child); + } + }); + } catch (error) { + console.error(error); + throw `error: cannot process subscribe:children directive. \n Usage: "children:append={[list, converter]}"; you can find a more detailed example in the documentation.`; + } + } + } + break; + } + default: + element.setAttribute(attributename, value); + } + }); children.filter((x) => x).forEach((child) => element.append(child)); diff --git a/src/types/styles.d.ts b/src/types/styles.d.ts index acdbccea..ef6d741f 100644 --- a/src/types/styles.d.ts +++ b/src/types/styles.d.ts @@ -1,2 +1 @@ -declare module "*.css" { -} +declare module "*.css" {}