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 00000000..26ecc9d2 Binary files /dev/null and b/src/Model/Utility/.utility.ts.swp differ diff --git a/src/Model/Utility/utility.ts b/src/Model/Utility/utility.ts index cf71678e..294369b7 100644 --- a/src/Model/Utility/utility.ts +++ b/src/Model/Utility/utility.ts @@ -1,5 +1,5 @@ import { checkIsValidObject, checkMatchesObjectStructure } from "./typeSafety"; -import * as Hammer from "hammerjs"; +import * as React from "../../react"; export interface Stringifiable { toString(): string; @@ -18,7 +18,7 @@ export function createTimestamp(): string { return new Date().toISOString(); } -// filters etc +// filters export type StringEntryObject = { [key: string]: Stringifiable | undefined }; export function filterObjectsByStringEntries( @@ -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 388ae278..e7479c10 100644 Binary files a/src/View/Modals/.connectionModal.tsx.swp and b/src/View/ChatPages/.taskPage.tsx.swp differ 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 63356017..00000000 Binary files a/src/ViewModel/Global/.connectionViewModel.ts.swp and /dev/null differ 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 00000000..a32dc84f Binary files /dev/null and b/src/ViewModel/Pages/.taskPageViewModel.ts.swp differ diff --git a/src/ViewModel/Pages/boardViewModel.ts b/src/ViewModel/Pages/boardViewModel.ts index c4a0a7f1..34bb4b74 100644 --- a/src/ViewModel/Pages/boardViewModel.ts +++ b/src/ViewModel/Pages/boardViewModel.ts @@ -1,10 +1,10 @@ -import * as React from "../../react"; import TaskViewModel from "./taskViewModel"; import TaskPageViewModel from "./taskPageViewModel"; import TaskContainingPageViewModel from "./taskContainingPageViewModel"; import SearchViewModel from "../Utility/searchViewModel"; import CoreViewModel from "../Global/coreViewModel"; import ChatViewModel, { ChatPageTypes } from "../Chat/chatViewModel"; +import * as React from "../../react"; import { Colors } from "../../colors"; import { CommonKeys } from "../../View/keystrokes"; import BoardsAndTasksModel, { @@ -115,11 +115,7 @@ export default class BoardViewModel extends TaskContainingPageViewModel { searchTerm, ]; this.coreViewModel.storageModel.write(suggestionPath, ""); - if ( - !this.searchSuggestions.value.has( - searchTerm, - ) && searchTerm != "" - ) { + if (!this.searchSuggestions.value.has(searchTerm) && searchTerm != "") { this.searchSuggestions.add(searchTerm); } @@ -133,7 +129,7 @@ export default class BoardViewModel extends TaskContainingPageViewModel { searchTerm, ]; this.coreViewModel.storageModel.remove(suggestionPath); - } + }; // view showTask = (taskFileContent: TaskFileContent): void => { @@ -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" {}