From 1ade38995c8545d0ac57d34ad561019cfe4eece7 Mon Sep 17 00:00:00 2001 From: curtisy Date: Sun, 14 Apr 2024 13:38:22 +0200 Subject: [PATCH 01/21] chore!: add biome instead of prettier for formatting This also sets up the preliminary work needed to use biome as a linter instead of eslint by running lint:biome --- .prettierignore | 6 - .prettierrc | 5 - biome.json | 28 + package.json | 5 +- src/App.tsx | 10 +- .../ContextMenu/configs/bodyMenu.config.ts | 426 +++++----- .../ContextMenu/configs/fileMenu.config.ts | 307 +++---- .../configs/multipleSelectedMenu.config.ts | 278 +++---- .../configs/sidebarDriveMenu.config.ts | 48 +- .../ContextMenu/configs/sidebarMenu.config.ts | 88 +- src/Components/ContextMenu/contextMenu.ts | 434 +++++----- src/Components/ContextMenu/index.tsx | 10 +- src/Components/Drives/drives.ts | 172 ++-- src/Components/Favorites/defaultFavorites.ts | 102 +-- src/Components/Favorites/favorites.ts | 60 +- src/Components/File/DetailFile.tsx | 8 +- src/Components/File/GridFile.tsx | 4 +- src/Components/File/index.tsx | 17 +- src/Components/Files/File Operation/copy.ts | 4 +- src/Components/Files/File Operation/cut.ts | 38 +- .../Files/File Operation/location.ts | 6 +- src/Components/Files/File Operation/new.ts | 40 +- src/Components/Files/File Operation/paste.ts | 150 ++-- src/Components/Files/File Operation/pin.ts | 38 +- src/Components/Files/File Operation/redo.ts | 122 +-- src/Components/Files/File Operation/rename.ts | 46 +- src/Components/Files/File Operation/search.ts | 170 ++-- src/Components/Files/File Operation/select.ts | 758 +++++++++--------- src/Components/Files/File Operation/trash.ts | 98 +-- src/Components/Files/File Operation/undo.ts | 124 +-- src/Components/Files/File Preview/preview.ts | 252 +++--- src/Components/Folder/new.ts | 32 +- src/Components/Functions/Loading/loading.ts | 12 +- src/Components/Functions/beep.ts | 8 +- src/Components/Functions/changePosition.ts | 72 +- src/Components/Functions/dragElement.ts | 78 +- .../Functions/elementClassNameContains.ts | 8 +- src/Components/Functions/extractExeIcon.ts | 51 +- src/Components/Functions/filesize.test.ts | 44 +- src/Components/Functions/filesize.ts | 14 +- src/Components/Functions/focusingPath.ts | 22 +- src/Components/Functions/lazyLoadingImage.ts | 72 +- src/Components/Functions/log.ts | 66 +- src/Components/Functions/new.ts | 32 +- .../Functions/path/basename.test.ts | 36 +- src/Components/Functions/path/basename.ts | 8 +- src/Components/Functions/path/dirname.test.ts | 44 +- src/Components/Functions/path/dirname.ts | 42 +- .../Functions/path/joinPath.test.ts | 36 +- src/Components/Functions/path/joinPath.ts | 29 +- .../Functions/path/normalizeSlash.test.ts | 36 +- .../Functions/path/normalizeSlash.ts | 11 +- src/Components/Functions/toggleHiddenFiles.ts | 14 +- src/Components/Functions/urlify.ts | 23 +- src/Components/Functions/validChecker.test.ts | 86 +- src/Components/Functions/validChecker.ts | 18 +- src/Components/Functions/viewport.ts | 16 +- src/Components/Header/SubHeader.tsx | 11 +- src/Components/Header/index.tsx | 6 +- src/Components/I18n/i18n.ts | 14 +- src/Components/Layout/home.ts | 80 +- src/Components/Layout/hover.ts | 125 +-- src/Components/Layout/infobar.ts | 24 +- src/Components/Layout/resizer.ts | 192 ++--- src/Components/Layout/sidebar.ts | 160 ++-- src/Components/Layout/tab.ts | 418 +++++----- src/Components/Layout/windowManager.ts | 118 +-- src/Components/LoadingBar/index.tsx | 10 +- src/Components/MainView/index.tsx | 4 +- src/Components/Open/defaultSort.ts | 44 +- src/Components/Open/displayFiles.ts | 273 ++++--- src/Components/Open/open.ts | 390 ++++----- src/Components/Open/recent.ts | 240 +++--- src/Components/Preview/DocxViewer.tsx | 8 +- src/Components/Preview/HtmlViewer.tsx | 8 +- src/Components/Preview/ImageViewer.tsx | 8 +- src/Components/Preview/MarkdownViewer.tsx | 8 +- src/Components/Preview/PdfViewer.tsx | 44 +- src/Components/Preview/PlaintextViewer.tsx | 8 +- src/Components/Preview/VideoViewer.tsx | 8 +- src/Components/Preview/XlsxViewer.tsx | 8 +- src/Components/Preview/index.tsx | 94 +-- src/Components/Prompt/ask.ts | 58 +- src/Components/Prompt/confirm.ts | 66 +- src/Components/Prompt/error.ts | 36 +- src/Components/Properties/index.tsx | 14 +- src/Components/Properties/properties.ts | 130 +-- src/Components/Setting/About/about.ts | 30 +- .../Setting/Appearance/Appearance.ts | 557 ++++++------- .../Setting/Preference/preference.ts | 252 +++--- src/Components/Setting/setting.ts | 132 +-- src/Components/SettingsView/index.tsx | 20 +- src/Components/Shortcut/shortcut.ts | 692 ++++++++-------- src/Components/Sidebar/index.tsx | 4 +- src/Components/Thumbnail/thumbnail.ts | 156 ++-- .../Thumbnail/thumbnailExtensionNode.ts | 16 +- .../Thumbnail/thumbnailExtensionTrie.ts | 74 +- src/Components/Thumbnail/thumbnailFileNode.ts | 16 +- src/Components/Thumbnail/thumbnailFileTrie.ts | 74 +- .../Thumbnail/thumbnailFolderNode.ts | 16 +- .../Thumbnail/thumbnailFolderTrie.ts | 74 +- src/Config/file.config.ts | 16 +- src/Config/folder.config.ts | 44 +- src/Locales/ar-SA.json | 224 +++--- src/Locales/base.json | 224 +++--- src/Locales/de-DE.json | 224 +++--- src/Locales/es-ES.json | 224 +++--- src/Locales/fr-FR.json | 224 +++--- src/Locales/hr-HR.json | 224 +++--- src/Locales/id-ID.json | 224 +++--- src/Locales/index.json | 40 +- src/Locales/it-IT.json | 224 +++--- src/Locales/ja-JP.json | 224 +++--- src/Locales/ko-KR.json | 224 +++--- src/Locales/ms-MY.json | 224 +++--- src/Locales/pl-PL.json | 224 +++--- src/Locales/pt-BR.json | 224 +++--- src/Locales/ru-RU.json | 224 +++--- src/Locales/tr-TR.json | 224 +++--- src/Locales/uk-UA.json | 224 +++--- src/Locales/zh-CN.json | 224 +++--- src/Locales/zh-TW.json | 224 +++--- src/Service/app.ts | 80 +- src/Service/cli.ts | 24 +- src/Service/clipboard.ts | 26 +- src/Service/directory.ts | 333 ++++---- src/Service/drives.ts | 160 ++-- src/Service/favorites.ts | 74 +- src/Service/files.ts | 375 ++++----- src/Service/locales.ts | 36 +- src/Service/operation.ts | 104 +-- src/Service/platform.ts | 36 +- src/Service/reveal.ts | 18 +- src/Service/storage.ts | 76 +- src/Service/trash.ts | 41 +- src/Service/window.ts | 78 +- src/Services/AppService.ts | 6 +- src/Services/CliService.ts | 6 +- src/Services/ClipboardService.ts | 2 +- src/Services/DirectoryService.ts | 6 +- src/Services/DrivesService.ts | 2 +- src/Services/FavoritesService.ts | 2 +- src/Services/FilesService.ts | 8 +- src/Services/LocaleService.ts | 23 +- src/Store/ActionCreators/AppActionCreators.ts | 43 +- src/Store/ActionCreators/CliActionCreators.ts | 21 +- .../ActionCreators/ClipboardActionCreators.ts | 44 +- .../ActionCreators/ConfigActionCreators.ts | 8 +- .../ActionCreators/DirectoryActionCreators.ts | 26 +- .../ActionCreators/DriveActionCreators.ts | 21 +- .../ActionCreators/FavoritesActionCreators.ts | 21 +- .../ActionCreators/FilesActionCreators.ts | 2 +- .../ActionCreators/LocalesActionCreators.ts | 23 +- .../ActionCreators/PlatformActionCreators.ts | 20 +- .../ActionCreators/SelectionActionCreators.ts | 2 +- .../ActionCreators/StorageActionCreators.ts | 70 +- src/Store/ActionCreators/TabActionCreators.ts | 2 +- .../ActionCreators/WindowActionCreators.ts | 20 +- src/Store/Reducers/AppReducer.ts | 39 +- src/Store/Reducers/CliReducer.ts | 31 +- src/Store/Reducers/ClipboardReducer.ts | 28 +- src/Store/Reducers/ConfigReducer.ts | 4 +- src/Store/Reducers/DirectoryReducer.ts | 6 +- src/Store/Reducers/DriveReducer.ts | 4 +- src/Store/Reducers/FavoritesReducer.ts | 9 +- src/Store/Reducers/FilesReducer.ts | 4 +- src/Store/Reducers/LocalesReducer.ts | 30 +- src/Store/Reducers/PlatformReducer.ts | 26 +- src/Store/Reducers/RequestReducer.ts | 4 +- src/Store/Reducers/SelectionReducer.ts | 4 +- src/Store/Reducers/StorageReducer.ts | 54 +- src/Store/Reducers/TabReducer.ts | 4 +- src/Store/Reducers/WindowReducer.ts | 70 +- src/Store/Reducers/index.ts | 34 +- src/Store/Sagas/AppSaga.ts | 44 +- src/Store/Sagas/CliSaga.ts | 20 +- src/Store/Sagas/ClipboardSaga.ts | 48 +- src/Store/Sagas/DirectorySaga.ts | 20 +- src/Store/Sagas/DrivesSaga.ts | 4 +- src/Store/Sagas/FavoritesSaga.ts | 20 +- src/Store/Sagas/FilesSaga.ts | 28 +- src/Store/Sagas/LocaleSaga.ts | 20 +- src/Store/Sagas/PlatformSaga.ts | 4 +- src/Store/Sagas/StorageSaga.ts | 83 +- src/Store/Sagas/TabSaga.ts | 10 +- src/Store/Sagas/WindowSaga.ts | 18 +- src/Store/Sagas/helpers.ts | 12 +- src/Store/index.ts | 4 +- src/Typings/Store/actions.ts | 6 +- src/Typings/Store/app.ts | 31 +- src/Typings/Store/cli.ts | 18 +- src/Typings/Store/clipboard.ts | 29 +- src/Typings/Store/config.ts | 2 +- src/Typings/Store/directory.ts | 24 +- src/Typings/Store/drive.ts | 2 +- src/Typings/Store/favorites.ts | 2 +- src/Typings/Store/files.ts | 4 +- src/Typings/Store/locales.ts | 22 +- src/Typings/Store/platform.ts | 10 +- src/Typings/Store/request.ts | 6 +- src/Typings/Store/selection.ts | 2 +- src/Typings/Store/storage.ts | 59 +- src/Typings/Store/store.ts | 28 +- src/Typings/Store/tab.ts | 15 +- src/Typings/Store/window.ts | 4 +- src/Typings/contextMenuItem.d.ts | 22 +- src/Typings/fileData.d.ts | 28 +- src/Typings/fileMetaData.d.ts | 38 +- src/Typings/mammoth.d.ts | 117 ++- src/Typings/select.d.ts | 4 +- src/Typings/storageData.d.ts | 2 +- src/Typings/svg.d.ts | 6 +- src/Typings/theme.d.ts | 20 +- src/Util/constants.ts | 26 +- src/Util/is-tauri.ts | 2 +- src/components/Infobar/index.tsx | 1 - src/components/Theme/_theme.ts | 313 ++++---- src/components/Theme/index.tsx | 2 +- src/index.tsx | 6 +- yarn.lock | 59 +- 220 files changed, 8591 insertions(+), 8460 deletions(-) delete mode 100644 .prettierignore delete mode 100644 .prettierrc create mode 100644 biome.json diff --git a/.prettierignore b/.prettierignore deleted file mode 100644 index 5d4fe03a..00000000 --- a/.prettierignore +++ /dev/null @@ -1,6 +0,0 @@ -build -dist -out -node_modules -*.min. -packages/**/*.ejs \ No newline at end of file diff --git a/.prettierrc b/.prettierrc deleted file mode 100644 index e1525349..00000000 --- a/.prettierrc +++ /dev/null @@ -1,5 +0,0 @@ -{ - "tabWidth": 4, - "useTabs": false, - "printWidth": 150 -} diff --git a/biome.json b/biome.json new file mode 100644 index 00000000..3239e615 --- /dev/null +++ b/biome.json @@ -0,0 +1,28 @@ +{ + "$schema": "https://biomejs.dev/schemas/1.6.4/schema.json", + "files": { + "ignore": [ + "node_modules", + "out", + "src-tauri", + "build", + "dist", + "*.min.js" + ] + }, + "organizeImports": { + "enabled": true + }, + "linter": { + "enabled": true, + "rules": { + "recommended": true + } + }, + "formatter": { + "enabled": true, + "indentStyle": "space", + "indentWidth": 4, + "lineWidth": 150 + } +} diff --git a/package.json b/package.json index 34df911e..e4909137 100644 --- a/package.json +++ b/package.json @@ -33,7 +33,8 @@ "postcrowdin:pull": "node scripts/post_crowdin_pull.js", "crowdin:sync": "yarn --cwd ./docs write-translations && crowdin upload && crowdin download", "lint": "eslint -c .eslintrc.yml --ext .ts ./src", - "prettier": "prettier --write src", + "lint:biome": "biome lint src", + "format": "biome format --write src", "grunt": "grunt", "css:minify": "cleancss --batch --batch-suffix \"\" out/**/*.css ", "prebuild": "yarn compile && yarn grunt && yarn css:minify", @@ -55,6 +56,7 @@ ], "license": "Apache-2.0", "devDependencies": { + "@biomejs/biome": "1.6.4", "@crowdin/cli": "^3.6.5", "@tauri-apps/cli": "^2.0.0-beta.14", "@types/jest": "^29.5.12", @@ -87,7 +89,6 @@ "node-watch": "^0.7.1", "patch-package": "^8.0.0", "postinstall-postinstall": "^2.1.0", - "prettier": "3.2.5", "rimraf": "^5.0.5", "sass": "^1.63.4", "sass-loader": "^14.1.1", diff --git a/src/App.tsx b/src/App.tsx index 681f437d..2d0c2b85 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -6,16 +6,16 @@ import SettingsView from "./Components/SettingsView"; import ContextMenu from "./Components/ContextMenu"; import Header from "./Components/Header"; +import Infobar from "./Components/Infobar"; import LoadingBar from "./Components/LoadingBar"; +import OperationBar from "./Components/OperationBar"; import Properties from "./Components/Properties"; import Sidebar from "./Components/Sidebar"; -import Infobar from "./Components/Infobar"; -import OperationBar from "./Components/OperationBar"; -import { setActiveTab } from "./Store/ActionCreators/TabActionCreators"; -import { IAppState } from "./Store/Reducers"; -import "./Public/style.scss"; import { ThemedDiv } from "./Components/Theme"; +import "./Public/style.scss"; +import { setActiveTab } from "./Store/ActionCreators/TabActionCreators"; +import type { IAppState } from "./Store/Reducers"; const App = () => { const dispatch = useDispatch(); diff --git a/src/Components/ContextMenu/configs/bodyMenu.config.ts b/src/Components/ContextMenu/configs/bodyMenu.config.ts index 74647fa2..17e1c2a8 100644 --- a/src/Components/ContextMenu/configs/bodyMenu.config.ts +++ b/src/Components/ContextMenu/configs/bodyMenu.config.ts @@ -1,217 +1,225 @@ -import contextMenuItem from '../../../Typings/contextMenuItem'; -import Storage from '../../../Service/storage'; -import { reload } from '../../Layout/windowManager'; -import Paste from '../../Files/File Operation/paste'; -import Undo from '../../Files/File Operation/undo'; -import Redo from '../../Files/File Operation/redo'; -import copyLocation from '../../Files/File Operation/location'; -import Pin from '../../Files/File Operation/pin'; -import Properties from '../../Properties/properties'; -import focusingPath from '../../Functions/focusingPath'; -import reveal from '../../../Service/reveal'; -import Translate from '../../I18n/i18n'; -import New from '../../Functions/new'; -import { isVSCodeInstalled } from '../../../Service/app'; -import { Purge, Restore } from '../../Files/File Operation/trash'; +import { isVSCodeInstalled } from "../../../Service/app"; +import reveal from "../../../Service/reveal"; +import Storage from "../../../Service/storage"; +import type contextMenuItem from "../../../Typings/contextMenuItem"; +import copyLocation from "../../Files/File Operation/location"; +import Paste from "../../Files/File Operation/paste"; +import Pin from "../../Files/File Operation/pin"; +import Redo from "../../Files/File Operation/redo"; +import { Purge, Restore } from "../../Files/File Operation/trash"; +import Undo from "../../Files/File Operation/undo"; +import focusingPath from "../../Functions/focusingPath"; +import New from "../../Functions/new"; +import Translate from "../../I18n/i18n"; +import { reload } from "../../Layout/windowManager"; +import Properties from "../../Properties/properties"; interface Favorites { - name: string; - path: string; + name: string; + path: string; } const BodyMenu = async (target: HTMLElement, filePath: string): Promise => { - const favorites: Favorites[] = (await Storage.get('sidebar'))?.favorites; - const isPinned = !!favorites?.filter((favorite) => favorite.path === filePath).length ?? false; - const _focusingPath = await focusingPath(); + const favorites: Favorites[] = (await Storage.get("sidebar"))?.favorites; + const isPinned = !!favorites?.filter((favorite) => favorite.path === filePath).length ?? false; + const _focusingPath = await focusingPath(); - const changeLayout = async (selectedLayout: 'l' | 'm' | 's' | 'd') => { - const layout = (await Storage.get('layout')) ?? {}; - layout[_focusingPath] = selectedLayout; - Storage.set('layout', layout); - reload(); - }; - const changeSortMethod = async (selectedMethod: 'A' | 'Z' | 'L' | 'F' | 'S' | 'T') => { - const sort = (await Storage.get('layout')) ?? {}; - sort[_focusingPath] = selectedMethod; - Storage.set('sort', sort); - reload(); - }; - return [ - [ - { - menu: await Translate('Layout Mode'), - submenu: [ - { - name: await Translate('Grid View (Large)'), - role: () => changeLayout('l'), - icon: 'grid_large', - }, - { - name: await Translate('Grid View (Medium)'), - role: () => changeLayout('m'), - icon: 'grid_medium', - }, - { - name: await Translate('Grid View (Small)'), - role: () => changeLayout('s'), - icon: 'grid_small', - }, - { - name: await Translate('Detail View'), - role: () => changeLayout('d'), - icon: 'detail', - }, - ], - icon: 'layout', - }, - { - menu: await Translate('Sort By'), - submenu: [ - { - name: await Translate('A-Z'), - role: () => changeSortMethod('A'), - }, - { - name: await Translate('Z-A'), - role: () => changeSortMethod('Z'), - }, - { - name: await Translate('Last Modified'), - role: () => changeSortMethod('L'), - }, - { - name: await Translate('First Modified'), - role: () => changeSortMethod('F'), - }, - { - name: await Translate('Size'), - role: () => changeSortMethod('S'), - }, - { - name: await Translate('Type'), - role: () => changeSortMethod('T'), - }, - ], - icon: 'sort', - }, - { - menu: await Translate('Reload'), - role: () => { - reload(); - }, - shortcut: 'F5', - icon: 'refresh', - }, - ], - [ - { - menu: await Translate('Paste'), - visible: !_focusingPath.startsWith('xplorer://'), - shortcut: 'Ctrl+V', - icon: 'paste', - role: () => { - Paste(filePath); - }, - }, - { - menu: await Translate('Undo Action'), - visible: !_focusingPath.startsWith('xplorer://'), - shortcut: 'Ctrl+Z', - icon: 'undo', - role: () => { - Undo(); - }, - }, - { - menu: await Translate('Redo Action'), - visible: !_focusingPath.startsWith('xplorer://'), - shortcut: 'Ctrl+Y', - icon: 'redo', - role: () => { - Redo(); - }, - }, - { - menu: await Translate('Copy Location Path'), - shortcut: 'Alt+Shift+C', - icon: 'location', - role: () => { - copyLocation(target); - }, - }, - { - menu: await Translate('Clear Recent List'), - icon: 'delete', - visible: _focusingPath === 'xplorer://Recent', - role: () => { - Storage.set('recent', []); - reload(); - }, - }, - ], - [ - { - menu: await Translate('Open in Terminal'), - visible: !_focusingPath.startsWith('xplorer://'), - shortcut: 'Alt+T', - icon: 'terminal', - role: () => reveal(filePath, 'terminal'), - }, - { - menu: await Translate('Open in VSCode'), - visible: (await isVSCodeInstalled()) && !_focusingPath.startsWith('xplorer://'), - shortcut: 'Shift+Enter', - icon: 'vscode', - role: () => { - reveal(filePath, 'vscode'); - }, - }, - { - menu: await Translate('Restore all files'), - visible: _focusingPath === 'xplorer://Trash', - icon: 'delete', - role: () => { - const filePaths = [...document.querySelectorAll('.file')].map((file) => decodeURI(file.dataset.path)); - Restore(filePaths); - }, - }, - { - menu: await Translate('Permanently delete all files'), - visible: _focusingPath === 'xplorer://Trash', - icon: 'delete', - role: () => { - const filePaths = [...document.querySelectorAll('.file')].map((file) => decodeURI(file.dataset.path)); - Purge(filePaths); - }, - }, - { - menu: await Translate('New'), - visible: !_focusingPath.startsWith('xplorer://'), - submenu: [ - { name: await Translate('Folder'), shortcut: 'Shift+N', role: () => New('folder') }, - { name: await Translate('File'), shortcut: 'Alt+N', role: () => New('file') }, - ], - icon: 'new', - }, - ], - [ - { - menu: await Translate(isPinned ? 'Unpin from Sidebar' : 'Pin to Sidebar'), - shortcut: 'Alt+P', - icon: 'pin', - role: () => { - Pin([filePath]); - }, - }, - { - menu: await Translate('Properties'), - shortcut: 'Ctrl+P', - icon: target?.dataset?.isdir ? 'folder setting' : 'file setting', - role: () => { - Properties(filePath); - }, - }, - ], - ]; + const changeLayout = async (selectedLayout: "l" | "m" | "s" | "d") => { + const layout = (await Storage.get("layout")) ?? {}; + layout[_focusingPath] = selectedLayout; + Storage.set("layout", layout); + reload(); + }; + const changeSortMethod = async (selectedMethod: "A" | "Z" | "L" | "F" | "S" | "T") => { + const sort = (await Storage.get("layout")) ?? {}; + sort[_focusingPath] = selectedMethod; + Storage.set("sort", sort); + reload(); + }; + return [ + [ + { + menu: await Translate("Layout Mode"), + submenu: [ + { + name: await Translate("Grid View (Large)"), + role: () => changeLayout("l"), + icon: "grid_large", + }, + { + name: await Translate("Grid View (Medium)"), + role: () => changeLayout("m"), + icon: "grid_medium", + }, + { + name: await Translate("Grid View (Small)"), + role: () => changeLayout("s"), + icon: "grid_small", + }, + { + name: await Translate("Detail View"), + role: () => changeLayout("d"), + icon: "detail", + }, + ], + icon: "layout", + }, + { + menu: await Translate("Sort By"), + submenu: [ + { + name: await Translate("A-Z"), + role: () => changeSortMethod("A"), + }, + { + name: await Translate("Z-A"), + role: () => changeSortMethod("Z"), + }, + { + name: await Translate("Last Modified"), + role: () => changeSortMethod("L"), + }, + { + name: await Translate("First Modified"), + role: () => changeSortMethod("F"), + }, + { + name: await Translate("Size"), + role: () => changeSortMethod("S"), + }, + { + name: await Translate("Type"), + role: () => changeSortMethod("T"), + }, + ], + icon: "sort", + }, + { + menu: await Translate("Reload"), + role: () => { + reload(); + }, + shortcut: "F5", + icon: "refresh", + }, + ], + [ + { + menu: await Translate("Paste"), + visible: !_focusingPath.startsWith("xplorer://"), + shortcut: "Ctrl+V", + icon: "paste", + role: () => { + Paste(filePath); + }, + }, + { + menu: await Translate("Undo Action"), + visible: !_focusingPath.startsWith("xplorer://"), + shortcut: "Ctrl+Z", + icon: "undo", + role: () => { + Undo(); + }, + }, + { + menu: await Translate("Redo Action"), + visible: !_focusingPath.startsWith("xplorer://"), + shortcut: "Ctrl+Y", + icon: "redo", + role: () => { + Redo(); + }, + }, + { + menu: await Translate("Copy Location Path"), + shortcut: "Alt+Shift+C", + icon: "location", + role: () => { + copyLocation(target); + }, + }, + { + menu: await Translate("Clear Recent List"), + icon: "delete", + visible: _focusingPath === "xplorer://Recent", + role: () => { + Storage.set("recent", []); + reload(); + }, + }, + ], + [ + { + menu: await Translate("Open in Terminal"), + visible: !_focusingPath.startsWith("xplorer://"), + shortcut: "Alt+T", + icon: "terminal", + role: () => reveal(filePath, "terminal"), + }, + { + menu: await Translate("Open in VSCode"), + visible: (await isVSCodeInstalled()) && !_focusingPath.startsWith("xplorer://"), + shortcut: "Shift+Enter", + icon: "vscode", + role: () => { + reveal(filePath, "vscode"); + }, + }, + { + menu: await Translate("Restore all files"), + visible: _focusingPath === "xplorer://Trash", + icon: "delete", + role: () => { + const filePaths = [...document.querySelectorAll(".file")].map((file) => decodeURI(file.dataset.path)); + Restore(filePaths); + }, + }, + { + menu: await Translate("Permanently delete all files"), + visible: _focusingPath === "xplorer://Trash", + icon: "delete", + role: () => { + const filePaths = [...document.querySelectorAll(".file")].map((file) => decodeURI(file.dataset.path)); + Purge(filePaths); + }, + }, + { + menu: await Translate("New"), + visible: !_focusingPath.startsWith("xplorer://"), + submenu: [ + { + name: await Translate("Folder"), + shortcut: "Shift+N", + role: () => New("folder"), + }, + { + name: await Translate("File"), + shortcut: "Alt+N", + role: () => New("file"), + }, + ], + icon: "new", + }, + ], + [ + { + menu: await Translate(isPinned ? "Unpin from Sidebar" : "Pin to Sidebar"), + shortcut: "Alt+P", + icon: "pin", + role: () => { + Pin([filePath]); + }, + }, + { + menu: await Translate("Properties"), + shortcut: "Ctrl+P", + icon: target?.dataset?.isdir ? "folder setting" : "file setting", + role: () => { + Properties(filePath); + }, + }, + ], + ]; }; export default BodyMenu; diff --git a/src/Components/ContextMenu/configs/fileMenu.config.ts b/src/Components/ContextMenu/configs/fileMenu.config.ts index 20294d28..9774e188 100644 --- a/src/Components/ContextMenu/configs/fileMenu.config.ts +++ b/src/Components/ContextMenu/configs/fileMenu.config.ts @@ -1,159 +1,162 @@ -import Preview from '../../Files/File Preview/preview'; -import { isVSCodeInstalled } from '../../../Service/app'; -import contextMenuItem from '../../../Typings/contextMenuItem'; -import { createNewTab } from '../../Layout/tab'; -import reveal from '../../../Service/reveal'; -import Cut from '../../Files/File Operation/cut'; -import Copy from '../../Files/File Operation/copy'; -import copyLocation from '../../Files/File Operation/location'; -import Rename from '../../Files/File Operation/rename'; -import { Purge, Restore, Trash } from '../../Files/File Operation/trash'; -import Pin from '../../Files/File Operation/pin'; -import Properties from '../../Properties/properties'; -import focusingPath from '../../Functions/focusingPath'; -import Translate from '../../I18n/i18n'; -import { OpenDir } from '../../Open/open'; -import FileAPI from '../../../Service/files'; -import Storage from '../../../Service/storage'; -import Ask from '../../Prompt/ask'; +import { isVSCodeInstalled } from "../../../Service/app"; +import FileAPI from "../../../Service/files"; +import reveal from "../../../Service/reveal"; +import Storage from "../../../Service/storage"; +import type contextMenuItem from "../../../Typings/contextMenuItem"; +import Copy from "../../Files/File Operation/copy"; +import Cut from "../../Files/File Operation/cut"; +import copyLocation from "../../Files/File Operation/location"; +import Pin from "../../Files/File Operation/pin"; +import Rename from "../../Files/File Operation/rename"; +import { Purge, Restore, Trash } from "../../Files/File Operation/trash"; +import Preview from "../../Files/File Preview/preview"; +import focusingPath from "../../Functions/focusingPath"; +import Translate from "../../I18n/i18n"; +import { createNewTab } from "../../Layout/tab"; +import { OpenDir } from "../../Open/open"; +import Ask from "../../Prompt/ask"; +import Properties from "../../Properties/properties"; interface Favorites { - name: string; - path: string; + name: string; + path: string; } const FileMenu = async (target: HTMLElement, filePath: string): Promise => { - const favorites: Favorites[] = (await Storage.get('sidebar'))?.favorites; - const isPinned = !!favorites?.filter((favorite) => favorite.path === filePath).length ?? false; - const _focusingPath = await focusingPath(); - return [ - [ - { - menu: await Translate('Open'), - shortcut: 'Enter', - icon: 'open', - role: () => { - if (target.dataset.isdir !== 'true') { - new FileAPI(filePath).openFile(); - } else OpenDir(filePath); - }, - }, - { - menu: await Translate('Open in New Tab'), - visible: target?.dataset?.isdir === 'true', - icon: 'open in new tab', - role: () => { - createNewTab(filePath); - }, - }, - { - menu: await Translate('Open in Terminal'), - visible: target?.dataset?.isdir === 'true', - shortcut: 'Alt+T', - icon: 'terminal', - role: () => { - reveal(filePath, 'terminal'); - }, - }, - { - menu: await Translate('Open in VSCode'), - visible: await isVSCodeInstalled(), - shortcut: 'Shift+Enter', - icon: 'vscode', - role: () => { - reveal(filePath, 'vscode'); - }, - }, - { - menu: await Translate('Preview'), - visible: target?.dataset?.isdir !== 'true', - shortcut: 'Ctrl+O', - icon: 'preview', - role: () => Preview(filePath), - }, - ], - [ - { - menu: await Translate('Cut'), - shortcut: 'Ctrl+X', - icon: 'cut', - role: () => Cut([filePath]), - }, - { - menu: await Translate('Copy'), - shortcut: 'Ctrl+C', - icon: 'copy', - role: () => Copy([filePath]), - }, - { - menu: await Translate('Copy Location Path'), - shortcut: 'Alt+Shift+C', - icon: 'location', - role: () => copyLocation(target), - }, - ], - [ - { - menu: await Translate('Rename'), - shortcut: 'F2', - icon: 'rename', - role: () => Rename(filePath), - }, - { - menu: await Translate('Delete'), - visible: _focusingPath !== 'xplorer://Trash', - shortcut: 'Del', - icon: 'delete', - role: () => Trash([filePath]), - }, - { - menu: await Translate('Restore'), - icon: 'delete', - visible: _focusingPath === 'xplorer://Trash', - role: () => { - Restore([decodeURI(filePath)]); - }, - }, - { - menu: await Translate('Permanently Delete'), - icon: 'delete', - visible: _focusingPath === 'xplorer://Trash', - shortcut: 'Shift+Del', - role: () => { - Purge([decodeURI(filePath)]); - }, - }, - { - menu: await Translate(isPinned ? 'Unpin from Sidebar' : 'Pin to Sidebar'), - shortcut: 'Alt+P', - icon: 'pin', - role: () => Pin([filePath]), - }, - { - menu: await Translate('Extract'), - visible: target?.dataset?.path?.endsWith('.zip') ?? false, - icon: 'unzip', - role: async () => { - const target = await Ask('Extract files', 'Extract files to', { value: filePath.replace('.zip', ''), selectFileName: false }); - new FileAPI(filePath).unzip(target); - }, - }, - { - menu: await Translate('Compress to Zip'), - icon: 'zip', - role: () => { - new FileAPI(filePath).zip(); - }, - }, - ], - [ - { - menu: await Translate('Properties'), - shortcut: 'Ctrl+P', - icon: target?.dataset?.isdir ? 'folder setting' : 'file setting', - role: () => Properties(filePath), - }, - ], - ]; + const favorites: Favorites[] = (await Storage.get("sidebar"))?.favorites; + const isPinned = !!favorites?.filter((favorite) => favorite.path === filePath).length ?? false; + const _focusingPath = await focusingPath(); + return [ + [ + { + menu: await Translate("Open"), + shortcut: "Enter", + icon: "open", + role: () => { + if (target.dataset.isdir !== "true") { + new FileAPI(filePath).openFile(); + } else OpenDir(filePath); + }, + }, + { + menu: await Translate("Open in New Tab"), + visible: target?.dataset?.isdir === "true", + icon: "open in new tab", + role: () => { + createNewTab(filePath); + }, + }, + { + menu: await Translate("Open in Terminal"), + visible: target?.dataset?.isdir === "true", + shortcut: "Alt+T", + icon: "terminal", + role: () => { + reveal(filePath, "terminal"); + }, + }, + { + menu: await Translate("Open in VSCode"), + visible: await isVSCodeInstalled(), + shortcut: "Shift+Enter", + icon: "vscode", + role: () => { + reveal(filePath, "vscode"); + }, + }, + { + menu: await Translate("Preview"), + visible: target?.dataset?.isdir !== "true", + shortcut: "Ctrl+O", + icon: "preview", + role: () => Preview(filePath), + }, + ], + [ + { + menu: await Translate("Cut"), + shortcut: "Ctrl+X", + icon: "cut", + role: () => Cut([filePath]), + }, + { + menu: await Translate("Copy"), + shortcut: "Ctrl+C", + icon: "copy", + role: () => Copy([filePath]), + }, + { + menu: await Translate("Copy Location Path"), + shortcut: "Alt+Shift+C", + icon: "location", + role: () => copyLocation(target), + }, + ], + [ + { + menu: await Translate("Rename"), + shortcut: "F2", + icon: "rename", + role: () => Rename(filePath), + }, + { + menu: await Translate("Delete"), + visible: _focusingPath !== "xplorer://Trash", + shortcut: "Del", + icon: "delete", + role: () => Trash([filePath]), + }, + { + menu: await Translate("Restore"), + icon: "delete", + visible: _focusingPath === "xplorer://Trash", + role: () => { + Restore([decodeURI(filePath)]); + }, + }, + { + menu: await Translate("Permanently Delete"), + icon: "delete", + visible: _focusingPath === "xplorer://Trash", + shortcut: "Shift+Del", + role: () => { + Purge([decodeURI(filePath)]); + }, + }, + { + menu: await Translate(isPinned ? "Unpin from Sidebar" : "Pin to Sidebar"), + shortcut: "Alt+P", + icon: "pin", + role: () => Pin([filePath]), + }, + { + menu: await Translate("Extract"), + visible: target?.dataset?.path?.endsWith(".zip") ?? false, + icon: "unzip", + role: async () => { + const target = await Ask("Extract files", "Extract files to", { + value: filePath.replace(".zip", ""), + selectFileName: false, + }); + new FileAPI(filePath).unzip(target); + }, + }, + { + menu: await Translate("Compress to Zip"), + icon: "zip", + role: () => { + new FileAPI(filePath).zip(); + }, + }, + ], + [ + { + menu: await Translate("Properties"), + shortcut: "Ctrl+P", + icon: target?.dataset?.isdir ? "folder setting" : "file setting", + role: () => Properties(filePath), + }, + ], + ]; }; export default FileMenu; diff --git a/src/Components/ContextMenu/configs/multipleSelectedMenu.config.ts b/src/Components/ContextMenu/configs/multipleSelectedMenu.config.ts index b2a30045..32dcab96 100644 --- a/src/Components/ContextMenu/configs/multipleSelectedMenu.config.ts +++ b/src/Components/ContextMenu/configs/multipleSelectedMenu.config.ts @@ -1,143 +1,143 @@ -import { getSelected } from '../../Files/File Operation/select'; -import contextMenuItem from '../../../Typings/contextMenuItem'; -import { isVSCodeInstalled } from '../../../Service/app'; -import { createNewTab } from '../../Layout/tab'; -import Cut from '../../Files/File Operation/cut'; -import Copy from '../../Files/File Operation/copy'; -import { Purge, Restore, Trash } from '../../Files/File Operation/trash'; -import Pin from '../../Files/File Operation/pin'; -import Translate from '../../I18n/i18n'; -import reveal from '../../../Service/reveal'; -import focusingPath from '../../Functions/focusingPath'; -import FileAPI from '../../../Service/files'; +import { isVSCodeInstalled } from "../../../Service/app"; +import FileAPI from "../../../Service/files"; +import reveal from "../../../Service/reveal"; +import type contextMenuItem from "../../../Typings/contextMenuItem"; +import Copy from "../../Files/File Operation/copy"; +import Cut from "../../Files/File Operation/cut"; +import Pin from "../../Files/File Operation/pin"; +import { getSelected } from "../../Files/File Operation/select"; +import { Purge, Restore, Trash } from "../../Files/File Operation/trash"; +import focusingPath from "../../Functions/focusingPath"; +import Translate from "../../I18n/i18n"; +import { createNewTab } from "../../Layout/tab"; const MultipleSelectedMenu = async (_: HTMLElement, _filePath: string): Promise => { - const _focusingPath = await focusingPath(); - const selectedFiles = getSelected(); - const SELECTED_FILES_ARE_FILES = Array.from(selectedFiles).every((file) => file.dataset.isdir !== 'true'); - return [ - [ - { - menu: await Translate('Open'), - shortcut: 'Enter', - icon: 'open', - visible: SELECTED_FILES_ARE_FILES, - role: () => { - selectedFiles.forEach((file) => { - new FileAPI(decodeURI(file.dataset.path)).openFile(); - }); - }, - }, - { - menu: await Translate('Open in New Tab'), - role: () => { - for (const element of getSelected()) { - if (element.dataset.isdir === 'true') { - createNewTab(decodeURI(element.dataset.path)); - } - } - }, - icon: 'open in new tab', - }, - { - menu: await Translate('Open in VSCode'), - role: () => { - for (const selected of getSelected()) { - const targetPath = decodeURI(selected.dataset.path) === 'undefined' ? _focusingPath : decodeURI(selected.dataset.path); - reveal(targetPath, 'vscode'); - } - }, - shortcut: 'Shift+Enter', - visible: await isVSCodeInstalled(), - icon: 'vscode', - }, - ], - [ - { - menu: await Translate('Cut'), - shortcut: 'Ctrl+X', - icon: 'cut', - role: () => { - const paths = []; - for (const element of getSelected()) { - paths.push(decodeURI(element.dataset.path)); - } - Cut(paths); - }, - }, - { - menu: await Translate('Copy'), - shortcut: 'Ctrl+C', - icon: 'copy', - role: () => { - const paths = []; - for (const element of getSelected()) { - paths.push(decodeURI(element.dataset.path)); - } - Copy(paths); - }, - }, - { - menu: await Translate('Delete'), - shortcut: 'Del', - icon: 'delete', - role: () => { - const paths = []; - for (const element of getSelected()) { - paths.push(decodeURI(element.dataset.path)); - } - Trash(paths); - }, - }, - { - menu: await Translate('Compress to Zip'), - icon: 'zip', - role: () => { - const selectedFilesPath = [...selectedFiles].map((file) => decodeURI(file.dataset.path)); - new FileAPI(selectedFilesPath).zip(); - }, - }, - ], - [ - { - menu: await Translate('Restore these files'), - visible: _focusingPath === 'xplorer://Trash', - icon: 'delete', - role: () => { - const filePaths = []; - for (const element of getSelected()) { - filePaths.push(decodeURI(element.dataset.path)); - } - Restore(filePaths); - }, - }, - { - menu: await Translate('Permanently delete these files'), - visible: _focusingPath === 'xplorer://Trash', - icon: 'delete', - role: () => { - const filePaths = []; - for (const element of getSelected()) { - filePaths.push(decodeURI(element.dataset.path)); - } - Purge(filePaths); - }, - }, - ], - [ - { - menu: await Translate('Pin to Sidebar'), - shortcut: 'Alt+P', - icon: 'pin', - role: () => { - const paths = []; - for (const element of getSelected()) { - paths.push(decodeURI(element.dataset.path)); - } - Pin(paths); - }, - }, - ], - ]; + const _focusingPath = await focusingPath(); + const selectedFiles = getSelected(); + const SELECTED_FILES_ARE_FILES = Array.from(selectedFiles).every((file) => file.dataset.isdir !== "true"); + return [ + [ + { + menu: await Translate("Open"), + shortcut: "Enter", + icon: "open", + visible: SELECTED_FILES_ARE_FILES, + role: () => { + selectedFiles.forEach((file) => { + new FileAPI(decodeURI(file.dataset.path)).openFile(); + }); + }, + }, + { + menu: await Translate("Open in New Tab"), + role: () => { + for (const element of getSelected()) { + if (element.dataset.isdir === "true") { + createNewTab(decodeURI(element.dataset.path)); + } + } + }, + icon: "open in new tab", + }, + { + menu: await Translate("Open in VSCode"), + role: () => { + for (const selected of getSelected()) { + const targetPath = decodeURI(selected.dataset.path) === "undefined" ? _focusingPath : decodeURI(selected.dataset.path); + reveal(targetPath, "vscode"); + } + }, + shortcut: "Shift+Enter", + visible: await isVSCodeInstalled(), + icon: "vscode", + }, + ], + [ + { + menu: await Translate("Cut"), + shortcut: "Ctrl+X", + icon: "cut", + role: () => { + const paths = []; + for (const element of getSelected()) { + paths.push(decodeURI(element.dataset.path)); + } + Cut(paths); + }, + }, + { + menu: await Translate("Copy"), + shortcut: "Ctrl+C", + icon: "copy", + role: () => { + const paths = []; + for (const element of getSelected()) { + paths.push(decodeURI(element.dataset.path)); + } + Copy(paths); + }, + }, + { + menu: await Translate("Delete"), + shortcut: "Del", + icon: "delete", + role: () => { + const paths = []; + for (const element of getSelected()) { + paths.push(decodeURI(element.dataset.path)); + } + Trash(paths); + }, + }, + { + menu: await Translate("Compress to Zip"), + icon: "zip", + role: () => { + const selectedFilesPath = [...selectedFiles].map((file) => decodeURI(file.dataset.path)); + new FileAPI(selectedFilesPath).zip(); + }, + }, + ], + [ + { + menu: await Translate("Restore these files"), + visible: _focusingPath === "xplorer://Trash", + icon: "delete", + role: () => { + const filePaths = []; + for (const element of getSelected()) { + filePaths.push(decodeURI(element.dataset.path)); + } + Restore(filePaths); + }, + }, + { + menu: await Translate("Permanently delete these files"), + visible: _focusingPath === "xplorer://Trash", + icon: "delete", + role: () => { + const filePaths = []; + for (const element of getSelected()) { + filePaths.push(decodeURI(element.dataset.path)); + } + Purge(filePaths); + }, + }, + ], + [ + { + menu: await Translate("Pin to Sidebar"), + shortcut: "Alt+P", + icon: "pin", + role: () => { + const paths = []; + for (const element of getSelected()) { + paths.push(decodeURI(element.dataset.path)); + } + Pin(paths); + }, + }, + ], + ]; }; export default MultipleSelectedMenu; diff --git a/src/Components/ContextMenu/configs/sidebarDriveMenu.config.ts b/src/Components/ContextMenu/configs/sidebarDriveMenu.config.ts index b401f011..1234bc34 100644 --- a/src/Components/ContextMenu/configs/sidebarDriveMenu.config.ts +++ b/src/Components/ContextMenu/configs/sidebarDriveMenu.config.ts @@ -1,29 +1,29 @@ -import { OpenDir } from '../../Open/open'; -import { createNewTab } from '../../Layout/tab'; -import contextMenuItem from '../../../Typings/contextMenuItem'; -import Translate from '../../I18n/i18n'; -import FileAPI from '../../../Service/files'; +import FileAPI from "../../../Service/files"; +import type contextMenuItem from "../../../Typings/contextMenuItem"; +import Translate from "../../I18n/i18n"; +import { createNewTab } from "../../Layout/tab"; +import { OpenDir } from "../../Open/open"; const SidebarDriveMenu = async (target: HTMLElement, filePath: string): Promise => { - return [ - [ - { - menu: await Translate('Open'), - icon: 'open', - role: () => { - target?.dataset?.isdir === 'true' ? OpenDir(filePath) : new FileAPI(filePath).openFile(); - }, - }, - { - menu: await Translate('Open in New Tab'), - visible: target?.dataset?.isdir === 'true', - icon: 'open in new tab', - role: () => { - createNewTab(filePath); - }, - }, - ], - ]; + return [ + [ + { + menu: await Translate("Open"), + icon: "open", + role: () => { + target?.dataset?.isdir === "true" ? OpenDir(filePath) : new FileAPI(filePath).openFile(); + }, + }, + { + menu: await Translate("Open in New Tab"), + visible: target?.dataset?.isdir === "true", + icon: "open in new tab", + role: () => { + createNewTab(filePath); + }, + }, + ], + ]; }; export default SidebarDriveMenu; diff --git a/src/Components/ContextMenu/configs/sidebarMenu.config.ts b/src/Components/ContextMenu/configs/sidebarMenu.config.ts index f8eec508..acbd0bf8 100644 --- a/src/Components/ContextMenu/configs/sidebarMenu.config.ts +++ b/src/Components/ContextMenu/configs/sidebarMenu.config.ts @@ -1,49 +1,49 @@ -import contextMenuItem from '../../../Typings/contextMenuItem'; -import { createNewTab } from '../../Layout/tab'; -import Pin from '../../Files/File Operation/pin'; -import Translate from '../../I18n/i18n'; -import Preview from '../../Files/File Preview/preview'; -import { OpenDir } from '../../Open/open'; -import FileAPI from '../../../Service/files'; +import FileAPI from "../../../Service/files"; +import type contextMenuItem from "../../../Typings/contextMenuItem"; +import Pin from "../../Files/File Operation/pin"; +import Preview from "../../Files/File Preview/preview"; +import Translate from "../../I18n/i18n"; +import { createNewTab } from "../../Layout/tab"; +import { OpenDir } from "../../Open/open"; const SidebarMenu = async (target: HTMLElement, filePath: string): Promise => { - return [ - [ - { - menu: await Translate('Open'), - icon: 'open', - role: () => { - target?.dataset?.isdir === 'true' ? OpenDir(filePath) : new FileAPI(filePath).openFile(); - }, - }, - { - menu: await Translate('Open in New Tab'), - visible: target?.dataset?.isdir === 'true', - icon: 'open in new tab', - role: () => { - createNewTab(filePath); - }, - }, - { - menu: await Translate('Preview'), - shortcut: 'Ctrl+O', - visible: target?.dataset?.isdir !== 'true', - icon: 'preview', - role: () => { - Preview(filePath); - }, - }, - ], - [ - { - menu: await Translate('Unpin from Sidebar'), - icon: 'pin', - role: () => { - Pin([filePath]); - }, - }, - ], - ]; + return [ + [ + { + menu: await Translate("Open"), + icon: "open", + role: () => { + target?.dataset?.isdir === "true" ? OpenDir(filePath) : new FileAPI(filePath).openFile(); + }, + }, + { + menu: await Translate("Open in New Tab"), + visible: target?.dataset?.isdir === "true", + icon: "open in new tab", + role: () => { + createNewTab(filePath); + }, + }, + { + menu: await Translate("Preview"), + shortcut: "Ctrl+O", + visible: target?.dataset?.isdir !== "true", + icon: "preview", + role: () => { + Preview(filePath); + }, + }, + ], + [ + { + menu: await Translate("Unpin from Sidebar"), + icon: "pin", + role: () => { + Pin([filePath]); + }, + }, + ], + ]; }; export default SidebarMenu; diff --git a/src/Components/ContextMenu/contextMenu.ts b/src/Components/ContextMenu/contextMenu.ts index 82ef5b49..82b0ca37 100644 --- a/src/Components/ContextMenu/contextMenu.ts +++ b/src/Components/ContextMenu/contextMenu.ts @@ -1,103 +1,103 @@ -import SidebarMenu from './configs/sidebarMenu.config'; -import SidebarDriveMenu from './configs/sidebarDriveMenu.config'; -import BodyMenu from './configs/bodyMenu.config'; -import MultipleSelectedMenu from './configs/multipleSelectedMenu.config'; -import contextMenuItem from '../../Typings/contextMenuItem'; -import fileThumbnail from '../Thumbnail/thumbnail'; -import { getSelected } from '../Files/File Operation/select'; -import FileMenu from './configs/fileMenu.config'; - -let contextMenu = document.querySelector('.contextmenu') as HTMLElement; -let contextMenuSubmenus = document.getElementById('contextmenu-submenus'); +import type contextMenuItem from "../../Typings/contextMenuItem"; +import { getSelected } from "../Files/File Operation/select"; +import fileThumbnail from "../Thumbnail/thumbnail"; +import BodyMenu from "./configs/bodyMenu.config"; +import FileMenu from "./configs/fileMenu.config"; +import MultipleSelectedMenu from "./configs/multipleSelectedMenu.config"; +import SidebarDriveMenu from "./configs/sidebarDriveMenu.config"; +import SidebarMenu from "./configs/sidebarMenu.config"; + +let contextMenu = document.querySelector(".contextmenu") as HTMLElement; +let contextMenuSubmenus = document.getElementById("contextmenu-submenus"); interface menuRoles { - [key: string]: () => void; + [key: string]: () => void; } const menuRoles: menuRoles = {}; -document.addEventListener('DOMContentLoaded', () => { - contextMenu = document.querySelector('.contextmenu') as HTMLElement; - contextMenuSubmenus = document.getElementById('contextmenu-submenus'); +document.addEventListener("DOMContentLoaded", () => { + contextMenu = document.querySelector(".contextmenu") as HTMLElement; + contextMenuSubmenus = document.getElementById("contextmenu-submenus"); }); const MenuToElements = async (menu: contextMenuItem[][]): Promise => { - for (let index = 0; index < menu.length; index++) { - const section = menu[index]; - for (let i = 0; i < section.length; i++) { - const item = section[i]; - if (item.visible || item.visible === undefined) { - const menu = document.createElement('span'); - menu.classList.add('contextmenu-item'); - - if (item.icon) { - if (item.shortcut) - menu.innerHTML = `${item?.menu.trim()}${item.shortcut}`; - else menu.innerHTML = `${item?.menu?.trim()}`; - } else { - if (item.shortcut) menu.innerHTML = `${item?.menu?.trim()}${item.shortcut}`; - else menu.innerHTML = item?.menu?.trim(); - } - - if (typeof item?.role === 'function') { - const roleIdentifier = Math.random().toString(36).substr(2, 10) + item?.menu?.replace(/\W/g, '')?.trim(); - menu.setAttribute('role', roleIdentifier); - menuRoles[roleIdentifier] = item?.role; - } - contextMenu.appendChild(menu); - - const submenuId = Math.random().toString(36).substr(2, 10); - - // Create submenu element for context menu - if (item.submenu) { - const submenu = document.createElement('div'); - submenu.classList.add('contextmenu-submenu'); - - menu.dataset.submenu = submenuId; - submenu.id = submenuId; - - contextMenuSubmenus.appendChild(submenu); - for (let j = 0; j < item.submenu.length; j++) { - const submenuItem = item.submenu[j]; - const submenuItemElement = document.createElement('span'); - submenuItemElement.classList.add('contextmenu-item'); - - if (submenuItem.icon) { - if (submenuItem.shortcut) - submenuItemElement.innerHTML = `${ - submenuItem.name ?? submenuItem - }${submenuItem.shortcut}`; - else - submenuItemElement.innerHTML = `${submenuItem?.name?.trim()}`; - } else { - if (submenuItem.shortcut) - submenuItemElement.innerHTML = `${submenuItem.name ?? submenuItem}${ - submenuItem.shortcut - }`; - else submenuItemElement.innerHTML = submenuItem.name; - } - - if (typeof submenuItem?.role === 'function') { - const roleIdentifier = Math.random().toString(36).substr(2, 10) + submenuItem?.name?.replace(/\W/g, '')?.trim(); - submenuItemElement.setAttribute('role', roleIdentifier); - menuRoles[roleIdentifier] = submenuItem?.role; - } - - submenu.appendChild(submenuItemElement); - } - } - } - } - if (index !== menu.length - 1 && section.filter((menu) => menu.visible !== false).length > 0) contextMenu.innerHTML += `
`; - } - return; + for (let index = 0; index < menu.length; index++) { + const section = menu[index]; + for (let i = 0; i < section.length; i++) { + const item = section[i]; + if (item.visible || item.visible === undefined) { + const menu = document.createElement("span"); + menu.classList.add("contextmenu-item"); + + if (item.icon) { + if (item.shortcut) + menu.innerHTML = `${item?.menu.trim()}${item.shortcut}`; + else menu.innerHTML = `${item?.menu?.trim()}`; + } else { + if (item.shortcut) menu.innerHTML = `${item?.menu?.trim()}${item.shortcut}`; + else menu.innerHTML = item?.menu?.trim(); + } + + if (typeof item?.role === "function") { + const roleIdentifier = Math.random().toString(36).substr(2, 10) + item?.menu?.replace(/\W/g, "")?.trim(); + menu.setAttribute("role", roleIdentifier); + menuRoles[roleIdentifier] = item?.role; + } + contextMenu.appendChild(menu); + + const submenuId = Math.random().toString(36).substr(2, 10); + + // Create submenu element for context menu + if (item.submenu) { + const submenu = document.createElement("div"); + submenu.classList.add("contextmenu-submenu"); + + menu.dataset.submenu = submenuId; + submenu.id = submenuId; + + contextMenuSubmenus.appendChild(submenu); + for (let j = 0; j < item.submenu.length; j++) { + const submenuItem = item.submenu[j]; + const submenuItemElement = document.createElement("span"); + submenuItemElement.classList.add("contextmenu-item"); + + if (submenuItem.icon) { + if (submenuItem.shortcut) + submenuItemElement.innerHTML = `${ + submenuItem.name ?? submenuItem + }${submenuItem.shortcut}`; + else + submenuItemElement.innerHTML = `${submenuItem?.name?.trim()}`; + } else { + if (submenuItem.shortcut) + submenuItemElement.innerHTML = `${submenuItem.name ?? submenuItem}${ + submenuItem.shortcut + }`; + else submenuItemElement.innerHTML = submenuItem.name; + } + + if (typeof submenuItem?.role === "function") { + const roleIdentifier = Math.random().toString(36).substr(2, 10) + submenuItem?.name?.replace(/\W/g, "")?.trim(); + submenuItemElement.setAttribute("role", roleIdentifier); + menuRoles[roleIdentifier] = submenuItem?.role; + } + + submenu.appendChild(submenuItemElement); + } + } + } + } + if (index !== menu.length - 1 && section.filter((menu) => menu.visible !== false).length > 0) contextMenu.innerHTML += `
`; + } + return; }; /** @@ -105,131 +105,131 @@ const MenuToElements = async (menu: contextMenuItem[][]): Promise => { * @returns {void} */ const ContextMenu = (): void => { - document.addEventListener('contextmenu', async (e) => { - e.preventDefault(); - document.querySelectorAll('.hover-preview').forEach((element) => { - element.parentNode.removeChild(element); - }); - contextMenu.innerHTML = ''; - contextMenu.style.height = 'initial'; - contextMenu.style.overflowY = 'initial'; - contextMenuSubmenus.innerHTML = ''; - let coorX = e.pageX; - let coorY = e.pageY; - - let target = e.target as HTMLElement; - if (target.classList.contains('workspace')) target = target.querySelector('.workspace-tab'); - else if (target.classList.contains('contextmenu')) { - exitContextMenu(); - return; - } else { - while (target.dataset && !target.dataset.path) { - target = target.parentNode as HTMLElement; - } - } - if (!target?.dataset?.path && !target?.classList?.contains('workspace')) return; - - const filePath = decodeURI(target.dataset.path); - - // Create the context menu - if (getSelected().length > 1) { - await MenuToElements(await MultipleSelectedMenu(target, filePath)); - } else if (target.classList.contains('favorite-item')) { - await MenuToElements(await SidebarMenu(target, filePath)); - } else if (target.classList.contains('drive-item')) { - await MenuToElements(await SidebarDriveMenu(target, filePath)); - } else if (target.classList.contains('workspace-tab')) { - await MenuToElements(await BodyMenu(target, filePath)); - } else { - await MenuToElements(await FileMenu(target, filePath)); - } - - if (coorY + contextMenu.offsetHeight > window.innerHeight && coorY - contextMenu.offsetHeight > -50) { - coorY -= contextMenu.offsetHeight; - } - if (coorX + contextMenu.offsetWidth > window.innerWidth) coorX = window.innerWidth - contextMenu.offsetWidth; - if (contextMenu.offsetHeight + coorY > window.innerHeight) { - contextMenu.style.height = `${ - window.innerHeight - coorY - parseInt(window.getComputedStyle(contextMenu).getPropertyValue('padding-top')) * 2 - }px`; - contextMenu.style.overflowY = 'auto'; - } - - contextMenu.style.left = coorX + 'px'; - contextMenu.style.top = coorY + 'px'; - contextMenu.scrollTop = 0; - - document.addEventListener('click', exitContextMenu); - }); - const exitContextMenu = () => { - contextMenu.style.left = '-100vw'; - contextMenu.style.top = '-100vh'; - contextMenuSubmenus.innerHTML = ''; - document.removeEventListener('click', exitContextMenu); - }; - - // Submenu handler - document.addEventListener('mousemove', (e) => { - // Expand contextmenu - if ( - (e.pageX >= contextMenu.offsetLeft + contextMenu.offsetWidth - 15 || e.pageX <= contextMenu.offsetLeft + 15) && - e.pageX < contextMenu.offsetLeft + contextMenu.offsetWidth + 100 - ) { - return; - } - - if (!((e.target as HTMLElement).parentNode as HTMLElement).className.startsWith('contextmenu-submenu')) { - document.querySelectorAll('.contextmenu-submenu').forEach((submenu) => ((submenu as HTMLElement).style.display = 'none')); - } - if ( - (e.target as HTMLElement).dataset.submenu || - ((e.target as HTMLElement).parentNode as HTMLElement).className.startsWith('contextmenu-submenu') - ) { - const submenuElement = document.getElementById((e.target as HTMLElement).dataset.submenu); - if (!submenuElement) return; - - const menuCoordinate = (e.target as HTMLElement).getBoundingClientRect(); - - submenuElement.style.display = 'block'; - submenuElement.style.height = 'initial'; - submenuElement.style.overflowY = 'initial'; - - let submenuCoorX = contextMenu.offsetLeft + contextMenu.offsetWidth; - if (submenuCoorX + submenuElement.offsetWidth * 0.5 >= window.innerWidth) { - submenuCoorX = contextMenu.offsetLeft - submenuElement.offsetWidth; - } - if (submenuElement.offsetHeight + menuCoordinate.top > window.innerHeight) { - submenuElement.style.height = `${ - window.innerHeight - - submenuElement.offsetHeight - - parseInt(window.getComputedStyle(submenuElement).getPropertyValue('padding-top')) * 2 - }px`; - submenuElement.style.overflowY = 'auto'; - } - submenuElement.style.left = submenuCoorX + 'px'; - submenuElement.style.top = menuCoordinate.top + 'px'; - submenuElement.scrollTop = 0; - } - }); - - contextMenu.addEventListener('click', (e) => { - exitContextMenu(); - - const menuClicked = e.target as HTMLElement; - const menuRole = menuClicked?.getAttribute('role'); - if (!menuRole) return; - - menuRoles[menuRole](); - }); - contextMenuSubmenus.addEventListener('click', (e) => { - exitContextMenu(); - - const menuClicked = e.target as HTMLElement; - const menuRole = menuClicked?.getAttribute('role'); - if (!menuRole) return; - - menuRoles[menuRole](); - }); + document.addEventListener("contextmenu", async (e) => { + e.preventDefault(); + document.querySelectorAll(".hover-preview").forEach((element) => { + element.parentNode.removeChild(element); + }); + contextMenu.innerHTML = ""; + contextMenu.style.height = "initial"; + contextMenu.style.overflowY = "initial"; + contextMenuSubmenus.innerHTML = ""; + let coorX = e.pageX; + let coorY = e.pageY; + + let target = e.target as HTMLElement; + if (target.classList.contains("workspace")) target = target.querySelector(".workspace-tab"); + else if (target.classList.contains("contextmenu")) { + exitContextMenu(); + return; + } else { + while (target.dataset && !target.dataset.path) { + target = target.parentNode as HTMLElement; + } + } + if (!target?.dataset?.path && !target?.classList?.contains("workspace")) return; + + const filePath = decodeURI(target.dataset.path); + + // Create the context menu + if (getSelected().length > 1) { + await MenuToElements(await MultipleSelectedMenu(target, filePath)); + } else if (target.classList.contains("favorite-item")) { + await MenuToElements(await SidebarMenu(target, filePath)); + } else if (target.classList.contains("drive-item")) { + await MenuToElements(await SidebarDriveMenu(target, filePath)); + } else if (target.classList.contains("workspace-tab")) { + await MenuToElements(await BodyMenu(target, filePath)); + } else { + await MenuToElements(await FileMenu(target, filePath)); + } + + if (coorY + contextMenu.offsetHeight > window.innerHeight && coorY - contextMenu.offsetHeight > -50) { + coorY -= contextMenu.offsetHeight; + } + if (coorX + contextMenu.offsetWidth > window.innerWidth) coorX = window.innerWidth - contextMenu.offsetWidth; + if (contextMenu.offsetHeight + coorY > window.innerHeight) { + contextMenu.style.height = `${ + window.innerHeight - coorY - Number.parseInt(window.getComputedStyle(contextMenu).getPropertyValue("padding-top")) * 2 + }px`; + contextMenu.style.overflowY = "auto"; + } + + contextMenu.style.left = coorX + "px"; + contextMenu.style.top = coorY + "px"; + contextMenu.scrollTop = 0; + + document.addEventListener("click", exitContextMenu); + }); + const exitContextMenu = () => { + contextMenu.style.left = "-100vw"; + contextMenu.style.top = "-100vh"; + contextMenuSubmenus.innerHTML = ""; + document.removeEventListener("click", exitContextMenu); + }; + + // Submenu handler + document.addEventListener("mousemove", (e) => { + // Expand contextmenu + if ( + (e.pageX >= contextMenu.offsetLeft + contextMenu.offsetWidth - 15 || e.pageX <= contextMenu.offsetLeft + 15) && + e.pageX < contextMenu.offsetLeft + contextMenu.offsetWidth + 100 + ) { + return; + } + + if (!((e.target as HTMLElement).parentNode as HTMLElement).className.startsWith("contextmenu-submenu")) { + document.querySelectorAll(".contextmenu-submenu").forEach((submenu) => ((submenu as HTMLElement).style.display = "none")); + } + if ( + (e.target as HTMLElement).dataset.submenu || + ((e.target as HTMLElement).parentNode as HTMLElement).className.startsWith("contextmenu-submenu") + ) { + const submenuElement = document.getElementById((e.target as HTMLElement).dataset.submenu); + if (!submenuElement) return; + + const menuCoordinate = (e.target as HTMLElement).getBoundingClientRect(); + + submenuElement.style.display = "block"; + submenuElement.style.height = "initial"; + submenuElement.style.overflowY = "initial"; + + let submenuCoorX = contextMenu.offsetLeft + contextMenu.offsetWidth; + if (submenuCoorX + submenuElement.offsetWidth * 0.5 >= window.innerWidth) { + submenuCoorX = contextMenu.offsetLeft - submenuElement.offsetWidth; + } + if (submenuElement.offsetHeight + menuCoordinate.top > window.innerHeight) { + submenuElement.style.height = `${ + window.innerHeight - + submenuElement.offsetHeight - + Number.parseInt(window.getComputedStyle(submenuElement).getPropertyValue("padding-top")) * 2 + }px`; + submenuElement.style.overflowY = "auto"; + } + submenuElement.style.left = submenuCoorX + "px"; + submenuElement.style.top = menuCoordinate.top + "px"; + submenuElement.scrollTop = 0; + } + }); + + contextMenu.addEventListener("click", (e) => { + exitContextMenu(); + + const menuClicked = e.target as HTMLElement; + const menuRole = menuClicked?.getAttribute("role"); + if (!menuRole) return; + + menuRoles[menuRole](); + }); + contextMenuSubmenus.addEventListener("click", (e) => { + exitContextMenu(); + + const menuClicked = e.target as HTMLElement; + const menuRole = menuClicked?.getAttribute("role"); + if (!menuRole) return; + + menuRoles[menuRole](); + }); }; export default ContextMenu; diff --git a/src/Components/ContextMenu/index.tsx b/src/Components/ContextMenu/index.tsx index e8e015bf..ed6a014e 100644 --- a/src/Components/ContextMenu/index.tsx +++ b/src/Components/ContextMenu/index.tsx @@ -1,10 +1,10 @@ -import React from 'react'; +import React from "react"; const ContextMenu = () => ( - <> -
-
- + <> +
+
+ ); export default ContextMenu; diff --git a/src/Components/Drives/drives.ts b/src/Components/Drives/drives.ts index 7942e607..8c41df49 100644 --- a/src/Components/Drives/drives.ts +++ b/src/Components/Drives/drives.ts @@ -1,21 +1,21 @@ -import formatBytes from '../Functions/filesize'; -import Translate from '../I18n/i18n'; -import fileThumbnail from '../Thumbnail/thumbnail'; -import { updateTheme } from '../Theme/theme'; -import DrivesAPI, { Drive } from '../../Service/drives'; -import OS from '../../Service/platform'; -import Storage from '../../Service/storage'; +import DrivesAPI, { type Drive } from "../../Service/drives"; +import OS from "../../Service/platform"; +import Storage from "../../Service/storage"; +import formatBytes from "../Functions/filesize"; +import Translate from "../I18n/i18n"; +import { updateTheme } from "../Theme/theme"; +import fileThumbnail from "../Thumbnail/thumbnail"; // Initialize values let platform: string; let driveInfo: DrivesAPI; (async () => { - if (!platform) { - platform = await OS(); - } - if (!driveInfo) { - driveInfo = new DrivesAPI(); - driveInfo.build(); - } + if (!platform) { + platform = await OS(); + } + if (!driveInfo) { + driveInfo = new DrivesAPI(); + driveInfo.build(); + } })(); /** @@ -24,27 +24,27 @@ let driveInfo: DrivesAPI; * @returns {Promise} Result */ const drivesToElements = async (drives: Drive[]): Promise => { - let result = drives.length ? `

${await Translate(platform === 'linux' ? 'Pendrives' : 'Drives')}

` : ''; // Element Result - for (const drive of drives) { - const driveName = drive.mount_point.split('/')[drive.mount_point.split('/').length - 1]; // Get name of drive - result += ` + let result = drives.length ? `

${await Translate(platform === "linux" ? "Pendrives" : "Drives")}

` : ""; // Element Result + for (const drive of drives) { + const driveName = drive.mount_point.split("/")[drive.mount_point.split("/").length - 1]; // Get name of drive + result += `
- USB icon + USB icon
${ - drive.name ?? drive.disk_type - ? `

${drive.name && /[^?]/.test(drive.name) ? drive.name : drive.disk_type} (${driveName})

` //eslint-disable-line - : `

${driveName}

` - } + drive.name ?? drive.disk_type + ? `

${drive.name && /[^?]/.test(drive.name) ? drive.name : drive.disk_type} (${driveName})

` //eslint-disable-line + : `

${driveName}

` + }
-

${formatBytes(drive.available_space)} ${await Translate('free of')} ${formatBytes(drive.total_space)}

+ ((drive.total_space - drive.available_space) / drive.total_space) * 100 + "%" + }">
+

${formatBytes(drive.available_space)} ${await Translate("free of")} ${formatBytes(drive.total_space)}

`; - } - return result; + } + return result; }; /** @@ -52,15 +52,15 @@ const drivesToElements = async (drives: Drive[]): Promise => { * @returns {Promise} drive section HTML code */ const Drives = async (): Promise => { - //if (focusingPath() === 'xplorer://Home') { - switch (platform) { - case 'darwin': - return ''; // Xplorer does not support drives for macOS currently - case 'win32': - default: - return `
${await drivesToElements(driveInfo.DRIVES)}
`; - } - //} else return ''; + //if (focusingPath() === 'xplorer://Home') { + switch (platform) { + case "darwin": + return ""; // Xplorer does not support drives for macOS currently + case "win32": + default: + return `
${await drivesToElements(driveInfo.DRIVES)}
`; + } + //} else return ''; }; /** @@ -68,40 +68,40 @@ const Drives = async (): Promise => { * @returns {Promise} */ const writeSidebarDriveItems = async (): Promise => { - const drives = driveInfo.DRIVES; - const isWin32 = platform === 'win32'; - const driveElement = document.querySelector('#sidebar-drives'); - const driveBtnText = driveElement.querySelector('.sidebar-text'); - driveBtnText.textContent = await Translate(isWin32 ? 'Drives' : 'Pendrives'); - if (!drives.length || platform === 'darwin') { - driveElement.hidden = true; - return; - } - let content = ''; - for (const drive of drives) { - let driveName: string; - if (platform === 'win32') { - const hasName = drive.name && /[^?]/.test(drive.name); - driveName = hasName ? drive.name : drive.disk_type; - driveName += ' (' + drive.mount_point.replace(/\\$/g, '') + ')'; - } else driveName = drive.mount_point.split('/').at(-1); - const driveType = drive.is_removable ? 'usb' : 'hard-disk'; - const iconPath = await fileThumbnail(driveType, 'favorites', false); - content += - `\n` + - ` \n` + - ` ${driveName}\n` + - ``; - } - const sidebar = await Storage.get('sidebar'); - const driveList = driveElement.querySelector('.sidebar-nav-list'); - driveList.innerHTML = content; - if (sidebar?.hideSection?.drives) { - const sidebarCollapseClass = 'sidebar-nav-dropdown-collapsed'; - driveElement.classList.add(sidebarCollapseClass); - } + const drives = driveInfo.DRIVES; + const isWin32 = platform === "win32"; + const driveElement = document.querySelector("#sidebar-drives"); + const driveBtnText = driveElement.querySelector(".sidebar-text"); + driveBtnText.textContent = await Translate(isWin32 ? "Drives" : "Pendrives"); + if (!drives.length || platform === "darwin") { + driveElement.hidden = true; + return; + } + let content = ""; + for (const drive of drives) { + let driveName: string; + if (platform === "win32") { + const hasName = drive.name && /[^?]/.test(drive.name); + driveName = hasName ? drive.name : drive.disk_type; + driveName += " (" + drive.mount_point.replace(/\\$/g, "") + ")"; + } else driveName = drive.mount_point.split("/").at(-1); + const driveType = drive.is_removable ? "usb" : "hard-disk"; + const iconPath = await fileThumbnail(driveType, "favorites", false); + content += + `\n` + + ` \n` + + ` ${driveName}\n` + + ``; + } + const sidebar = await Storage.get("sidebar"); + const driveList = driveElement.querySelector(".sidebar-nav-list"); + driveList.innerHTML = content; + if (sidebar?.hideSection?.drives) { + const sidebarCollapseClass = "sidebar-nav-dropdown-collapsed"; + driveElement.classList.add(sidebarCollapseClass); + } }; /** @@ -109,21 +109,21 @@ const writeSidebarDriveItems = async (): Promise => { * @returns {Promise} */ const detectDriveInit = async (): Promise => { - if (!(await Storage.get('preference'))?.detectDriveChange) return; - if (!driveInfo) { - driveInfo = new DrivesAPI(); - await driveInfo.build(); - } - driveInfo.detectChange(async () => { - if (document.querySelector('.path-navigator').value === 'xplorer://Home') { - const MAIN_DRIVES_ELEMENT = document.getElementById('drives'); - if (MAIN_DRIVES_ELEMENT.classList.contains('hidden')) MAIN_DRIVES_ELEMENT.classList.remove('hidden'); - const _driveSection = await Drives(); - MAIN_DRIVES_ELEMENT.innerHTML = _driveSection; - } - await writeSidebarDriveItems(); - updateTheme('favorites'); - }); + if (!(await Storage.get("preference"))?.detectDriveChange) return; + if (!driveInfo) { + driveInfo = new DrivesAPI(); + await driveInfo.build(); + } + driveInfo.detectChange(async () => { + if (document.querySelector(".path-navigator").value === "xplorer://Home") { + const MAIN_DRIVES_ELEMENT = document.getElementById("drives"); + if (MAIN_DRIVES_ELEMENT.classList.contains("hidden")) MAIN_DRIVES_ELEMENT.classList.remove("hidden"); + const _driveSection = await Drives(); + MAIN_DRIVES_ELEMENT.innerHTML = _driveSection; + } + await writeSidebarDriveItems(); + updateTheme("favorites"); + }); }; export { writeSidebarDriveItems, Drives, drivesToElements, detectDriveInit }; diff --git a/src/Components/Favorites/defaultFavorites.ts b/src/Components/Favorites/defaultFavorites.ts index 5dcd7187..51e9292c 100644 --- a/src/Components/Favorites/defaultFavorites.ts +++ b/src/Components/Favorites/defaultFavorites.ts @@ -1,56 +1,56 @@ -import fileThumbnail from '../Thumbnail/thumbnail'; -import FavoritesAPI from '../../Service/favorites'; +import FavoritesAPI from "../../Service/favorites"; +import fileThumbnail from "../Thumbnail/thumbnail"; let FavoritesData: FavoritesAPI; interface Favorites { - name: string; - path: string; - icon: string; + name: string; + path: string; + icon: string; } export default async function defaultFavorites(): Promise { - if (!FavoritesData) { - FavoritesData = new FavoritesAPI(); - await FavoritesData.build(); - } - return [ - { - name: 'Recent', - path: 'xplorer://Recent', - icon: await fileThumbnail('recent', 'folder', false), - }, - { - name: 'Desktop', - path: FavoritesData.DESKTOP_PATH, - icon: await fileThumbnail('desktop', 'folder', false), - }, - { - name: 'Documents', - path: FavoritesData.DOCUMENT_PATH, - icon: await fileThumbnail('document', 'folder', false), - }, - { - name: 'Downloads', - path: FavoritesData.DOWNLOAD_PATH, - icon: await fileThumbnail('download', 'folder', false), - }, - { - name: 'Pictures', - path: FavoritesData.PICTURE_PATH, - icon: await fileThumbnail('picture', 'folder', false), - }, - { - name: 'Music', - path: FavoritesData.MUSIC_PATH, - icon: await fileThumbnail('music', 'folder', false), - }, - { - name: 'Videos', - path: FavoritesData.VIDEO_PATH, - icon: await fileThumbnail('video', 'folder', false), - }, - { - name: 'Trash', - path: 'xplorer://Trash', - icon: await fileThumbnail('trash', 'folder', false), - }, - ]; + if (!FavoritesData) { + FavoritesData = new FavoritesAPI(); + await FavoritesData.build(); + } + return [ + { + name: "Recent", + path: "xplorer://Recent", + icon: await fileThumbnail("recent", "folder", false), + }, + { + name: "Desktop", + path: FavoritesData.DESKTOP_PATH, + icon: await fileThumbnail("desktop", "folder", false), + }, + { + name: "Documents", + path: FavoritesData.DOCUMENT_PATH, + icon: await fileThumbnail("document", "folder", false), + }, + { + name: "Downloads", + path: FavoritesData.DOWNLOAD_PATH, + icon: await fileThumbnail("download", "folder", false), + }, + { + name: "Pictures", + path: FavoritesData.PICTURE_PATH, + icon: await fileThumbnail("picture", "folder", false), + }, + { + name: "Music", + path: FavoritesData.MUSIC_PATH, + icon: await fileThumbnail("music", "folder", false), + }, + { + name: "Videos", + path: FavoritesData.VIDEO_PATH, + icon: await fileThumbnail("video", "folder", false), + }, + { + name: "Trash", + path: "xplorer://Trash", + icon: await fileThumbnail("trash", "folder", false), + }, + ]; } diff --git a/src/Components/Favorites/favorites.ts b/src/Components/Favorites/favorites.ts index 9a2c10eb..31b15916 100644 --- a/src/Components/Favorites/favorites.ts +++ b/src/Components/Favorites/favorites.ts @@ -1,12 +1,12 @@ -import Translate from '../I18n/i18n'; -import fileThumbnail from '../Thumbnail/thumbnail'; -import DirectoryAPI from '../../Service/directory'; -import Storage from '../../Service/storage'; -import defaultFavorites from './defaultFavorites'; -import FileAPI from '../../Service/files'; +import DirectoryAPI from "../../Service/directory"; +import FileAPI from "../../Service/files"; +import Storage from "../../Service/storage"; +import Translate from "../I18n/i18n"; +import fileThumbnail from "../Thumbnail/thumbnail"; +import defaultFavorites from "./defaultFavorites"; const isDefaultFavorite = async (filePath: string) => { - return (await defaultFavorites()).some((favorite) => favorite.path === filePath); + return (await defaultFavorites()).some((favorite) => favorite.path === filePath); }; /** @@ -14,28 +14,28 @@ const isDefaultFavorite = async (filePath: string) => { * @returns {{Promise} Favorites section HTML code */ const Favorites = async (): Promise => { - const data = await Storage.get('favorites'); // Get user favorites data on sidebar - const favorites = data?.favorites ?? (await defaultFavorites()); + const data = await Storage.get("favorites"); // Get user favorites data on sidebar + const favorites = data?.favorites ?? (await defaultFavorites()); - let result = '
'; - result += `

${await Translate('Favorites')}

`; - const defaultFavoritesList = (await defaultFavorites()).map((favorite) => favorite.name); - for (const favorite of favorites) { - if (!favorite.path) continue; - if (favorite.path === 'xplorer://Home') continue; - const fileData = new FileAPI(favorite.path); - const exists = await fileData.exists(); - if (!exists && !(await isDefaultFavorite(favorite.path))) continue; - let icon = favorite.icon; - if (!icon) { - if (defaultFavoritesList.indexOf(favorite.name) === -1) { - const isdir = await new DirectoryAPI(favorite.path).isDir(); - icon = await fileThumbnail(exists ? favorite.path : favorite.name, isdir ? 'folder' : 'file', false); - } else { - icon = await fileThumbnail(favorite.name.toLowerCase(), 'folder', false); - } - } - result += `
${await Translate("Favorites")}`; + const defaultFavoritesList = (await defaultFavorites()).map((favorite) => favorite.name); + for (const favorite of favorites) { + if (!favorite.path) continue; + if (favorite.path === "xplorer://Home") continue; + const fileData = new FileAPI(favorite.path); + const exists = await fileData.exists(); + if (!exists && !(await isDefaultFavorite(favorite.path))) continue; + let icon = favorite.icon; + if (!icon) { + if (defaultFavoritesList.indexOf(favorite.name) === -1) { + const isdir = await new DirectoryAPI(favorite.path).isDir(); + icon = await fileThumbnail(exists ? favorite.path : favorite.name, isdir ? "folder" : "file", false); + } else { + icon = await fileThumbnail(favorite.name.toLowerCase(), "folder", false); + } + } + result += `
=> { />${await Translate(favorite.name)}
`; - } - return result; + } + return result; }; export default Favorites; diff --git a/src/Components/File/DetailFile.tsx b/src/Components/File/DetailFile.tsx index b976e8c3..b8540691 100644 --- a/src/Components/File/DetailFile.tsx +++ b/src/Components/File/DetailFile.tsx @@ -1,8 +1,8 @@ -import React, { MouseEvent } from "react"; -import FileMetaData from "../../Typings/fileMetaData"; -import { ThemedButton, ThemedSpan } from "../Theme"; +import React, { type MouseEvent } from "react"; import { useSelector } from "react-redux"; -import { IAppState } from "../../Store/Reducers"; +import type { IAppState } from "../../Store/Reducers"; +import type FileMetaData from "../../Typings/fileMetaData"; +import { ThemedButton, ThemedSpan } from "../Theme"; export interface IDetailFileProps { metadata: FileMetaData; handleFileRightClick: (e: MouseEvent, path: string) => void; diff --git a/src/Components/File/GridFile.tsx b/src/Components/File/GridFile.tsx index 62b523f8..8e424ae0 100644 --- a/src/Components/File/GridFile.tsx +++ b/src/Components/File/GridFile.tsx @@ -1,5 +1,5 @@ -import React, { MouseEvent } from "react"; -import FileMetaData from "../../Typings/fileMetaData"; +import React, { type MouseEvent } from "react"; +import type FileMetaData from "../../Typings/fileMetaData"; import { ThemedButton } from "../Theme"; export interface IGridFileProps { diff --git a/src/Components/File/index.tsx b/src/Components/File/index.tsx index 2daed9ef..53498afc 100644 --- a/src/Components/File/index.tsx +++ b/src/Components/File/index.tsx @@ -1,14 +1,11 @@ -import React, { MouseEvent } from "react"; +import React, { type MouseEvent } from "react"; import { useDispatch, useSelector } from "react-redux"; -import GridFile from "./GridFile"; import DetailFile from "./DetailFile"; +import GridFile from "./GridFile"; import { getStandardPath } from "../../Helpers/paths"; -import { openFileRequest, openFilePreview } from "../../Store/ActionCreators/FilesActionCreators"; -import { setActiveTab, updateTab } from "../../Store/ActionCreators/TabActionCreators"; -import { IAppState } from "../../Store/Reducers"; -import FileMetaData from "../../Typings/fileMetaData"; +import { openFilePreview, openFileRequest } from "../../Store/ActionCreators/FilesActionCreators"; import { updateSelection } from "../../Store/ActionCreators/SelectionActionCreators"; import { sortFiles } from "../MainView"; @@ -60,7 +57,13 @@ export const File = ({ mode, metadata }: IFileProps): JSX.Element => { name: filePath.split("\\").pop() || "", }), ); - dispatch(setActiveTab({ name: filePath.split("\\").pop() || "", path: getStandardPath(filePath), id: activeTab.id })); + dispatch( + setActiveTab({ + name: filePath.split("\\").pop() || "", + path: getStandardPath(filePath), + id: activeTab.id, + }), + ); }; switch (mode) { diff --git a/src/Components/Files/File Operation/copy.ts b/src/Components/Files/File Operation/copy.ts index 0418f049..aefa4799 100644 --- a/src/Components/Files/File Operation/copy.ts +++ b/src/Components/Files/File Operation/copy.ts @@ -1,4 +1,4 @@ -import Storage from '../../../Service/storage'; +import Storage from "../../../Service/storage"; /** * Copy (a) file/s * @@ -6,7 +6,7 @@ import Storage from '../../../Service/storage'; * @returns {void} */ const Copy = (files: Array): void => { - Storage.set('clipboard', { command: 'cp', files: files }); + Storage.set("clipboard", { command: "cp", files: files }); }; export default Copy; diff --git a/src/Components/Files/File Operation/cut.ts b/src/Components/Files/File Operation/cut.ts index 6228221d..1cd5fedb 100644 --- a/src/Components/Files/File Operation/cut.ts +++ b/src/Components/Files/File Operation/cut.ts @@ -1,4 +1,4 @@ -import Storage from '../../../Service/storage'; +import Storage from "../../../Service/storage"; /** * Cut (a) file/s * @@ -6,25 +6,25 @@ import Storage from '../../../Service/storage'; * @returns {any} */ const Cut = (files: Array): void => { - Storage.set('clipboard', { command: 'cut', files: files }); - for (const file of files) { - document.querySelector(`.file[data-path="${encodeURI(file)}"]`).classList.add('cut'); - } + Storage.set("clipboard", { command: "cut", files: files }); + for (const file of files) { + document.querySelector(`.file[data-path="${encodeURI(file)}"]`).classList.add("cut"); + } - (async function detectClipboardChange() { - let n: NodeJS.Timeout; //eslint-disable-line - if ((await Storage.get('clipboard')).files !== files) { - global.clearTimeout(n); - document.querySelectorAll('.file.cut').forEach((file) => { - if (files.indexOf(decodeURI(file.dataset.path)) !== -1) { - file.classList.remove('cut'); - } - }); - return; - } - n = setTimeout(detectClipboardChange, 100); - })(); - return; + (async function detectClipboardChange() { + let n: NodeJS.Timeout; //eslint-disable-line + if ((await Storage.get("clipboard")).files !== files) { + global.clearTimeout(n); + document.querySelectorAll(".file.cut").forEach((file) => { + if (files.indexOf(decodeURI(file.dataset.path)) !== -1) { + file.classList.remove("cut"); + } + }); + return; + } + n = setTimeout(detectClipboardChange, 100); + })(); + return; }; export default Cut; diff --git a/src/Components/Files/File Operation/location.ts b/src/Components/Files/File Operation/location.ts index bf5d0ca3..2d5fcd4d 100644 --- a/src/Components/Files/File Operation/location.ts +++ b/src/Components/Files/File Operation/location.ts @@ -1,4 +1,4 @@ -import { writeTextToClipboard } from '../../../Service/clipboard'; +import { writeTextToClipboard } from "../../../Service/clipboard"; /** * Copy file location from file element into clipborad @@ -6,8 +6,8 @@ import { writeTextToClipboard } from '../../../Service/clipboard'; * @returns {void} */ const copyLocation = (element: HTMLElement): void => { - const path = decodeURI(element.dataset.path); - writeTextToClipboard(path); + const path = decodeURI(element.dataset.path); + writeTextToClipboard(path); }; export default copyLocation; diff --git a/src/Components/Files/File Operation/new.ts b/src/Components/Files/File Operation/new.ts index 1e44bcdb..8489e202 100644 --- a/src/Components/Files/File Operation/new.ts +++ b/src/Components/Files/File Operation/new.ts @@ -1,7 +1,7 @@ -import { OperationLog } from '../../Functions/log'; -import focusingPath from '../../Functions/focusingPath'; -import FileAPI from '../../../Service/files'; -import PromptError from '../../Prompt/error'; +import FileAPI from "../../../Service/files"; +import focusingPath from "../../Functions/focusingPath"; +import { OperationLog } from "../../Functions/log"; +import PromptError from "../../Prompt/error"; /** * Create a new file @@ -11,24 +11,24 @@ import PromptError from '../../Prompt/error'; * @returns {Promise} */ const NewFile = async (fileName: string, parentDir?: string, writeLog = true): Promise => { - if (!parentDir) parentDir = await focusingPath(); - const newFile = new FileAPI(fileName, parentDir); + if (!parentDir) parentDir = await focusingPath(); + const newFile = new FileAPI(fileName, parentDir); - if (await newFile.exists()) { - PromptError('Error creating file', `Failed to create file ${newFile.fileName}: File already existed`); - } else { - try { - await newFile.createFile(); - } catch (err) { - PromptError('Error creating file', `Failed to create file ${newFile.fileName}: Something went wrong (${err})`); - } + if (await newFile.exists()) { + PromptError("Error creating file", `Failed to create file ${newFile.fileName}: File already existed`); + } else { + try { + await newFile.createFile(); + } catch (err) { + PromptError("Error creating file", `Failed to create file ${newFile.fileName}: Something went wrong (${err})`); + } - if (writeLog) { - if (typeof newFile.fileName === 'string') { - OperationLog('newfile', null, newFile.fileName); - } - } - } + if (writeLog) { + if (typeof newFile.fileName === "string") { + OperationLog("newfile", null, newFile.fileName); + } + } + } }; export default NewFile; diff --git a/src/Components/Files/File Operation/paste.ts b/src/Components/Files/File Operation/paste.ts index ee62fdf4..a85db289 100644 --- a/src/Components/Files/File Operation/paste.ts +++ b/src/Components/Files/File Operation/paste.ts @@ -1,81 +1,81 @@ -import Storage from '../../../Service/storage'; -import OperationAPI from '../../../Service/operation'; -import DirectoryAPI from '../../../Service/directory'; -import joinPath from '../../Functions/path/joinPath'; -import getBasename from '../../Functions/path/basename'; -import getDirname from '../../Functions/path/dirname'; -import NormalizeSlash from '../../Functions/path/normalizeSlash'; -import FileAPI from '../../../Service/files'; -import ConfirmDialog from '../../Prompt/confirm'; -import normalizeSlash from '../../Functions/path/normalizeSlash'; -import { OperationLog } from '../../Functions/log'; +import DirectoryAPI from "../../../Service/directory"; +import FileAPI from "../../../Service/files"; +import OperationAPI from "../../../Service/operation"; +import Storage from "../../../Service/storage"; +import { OperationLog } from "../../Functions/log"; +import getBasename from "../../Functions/path/basename"; +import getDirname from "../../Functions/path/dirname"; +import joinPath from "../../Functions/path/joinPath"; +import NormalizeSlash from "../../Functions/path/normalizeSlash"; +import normalizeSlash from "../../Functions/path/normalizeSlash"; +import ConfirmDialog from "../../Prompt/confirm"; const cpy = async (src: string, dest: string) => { - dest = joinPath(dest, getBasename(src)); - if (NormalizeSlash(getDirname(src)) === NormalizeSlash(dest)) { - dest += ' - COPY'; - } - if (await new FileAPI(dest).exists()) { - if (!(await ConfirmDialog('Target file exists', 'Target directory with the same file name exists, do you want to overwrite it?', 'No'))) - return; - } - new OperationAPI(src, dest).copyFile(); + dest = joinPath(dest, getBasename(src)); + if (NormalizeSlash(getDirname(src)) === NormalizeSlash(dest)) { + dest += " - COPY"; + } + if (await new FileAPI(dest).exists()) { + if (!(await ConfirmDialog("Target file exists", "Target directory with the same file name exists, do you want to overwrite it?", "No"))) + return; + } + new OperationAPI(src, dest).copyFile(); }; const Paste = async (target: string): Promise => { - const clipboard = await Storage.get('clipboard'); + const clipboard = await Storage.get("clipboard"); - const recuriveCopy = async (_path: string, _target: string, firstRecursion = false) => { - let useCopySuffix = false; - if (firstRecursion && normalizeSlash(getDirname(_path)) === normalizeSlash(_target)) { - useCopySuffix = true; - } - const subdirInfo = new DirectoryAPI(normalizeSlash(_path)); - if (await subdirInfo.isDir()) { - let _dest = joinPath(_target, getBasename(_path)); - if (useCopySuffix) _dest += '- COPY'; - await new DirectoryAPI(_dest).mkdir(); - (await subdirInfo.getFiles()).files.forEach(async (subsubdir) => { - await recuriveCopy(subsubdir.file_path, _dest); - }); - } else { - cpy(_path, _target); - } - }; - for (const file of clipboard.files) { - const dirInfo = new DirectoryAPI(file); - const dest = joinPath(target, getBasename(file)); - switch (clipboard.command) { - case 'cp': - if (await dirInfo.isDir()) { - await recuriveCopy(file, target, true); - } else { - cpy(file, target); - } - break; - case 'cut': - if (await new DirectoryAPI(dest).exists()) { - if ( - !(await ConfirmDialog( - 'Target file exists', - 'Target directory with the same file/dir name exists, do you want to overwrite it?', - 'No' - )) - ) - return; - else { - await new OperationAPI(dest).unlink(); - } - } - await new OperationAPI(file, dest).cut(); - break; - } - } - switch (clipboard.command) { - case 'cp': - OperationLog('copy', clipboard.files, target); - break; - case 'cut': - OperationLog('cut', clipboard.files, target); - break; - } + const recuriveCopy = async (_path: string, _target: string, firstRecursion = false) => { + let useCopySuffix = false; + if (firstRecursion && normalizeSlash(getDirname(_path)) === normalizeSlash(_target)) { + useCopySuffix = true; + } + const subdirInfo = new DirectoryAPI(normalizeSlash(_path)); + if (await subdirInfo.isDir()) { + let _dest = joinPath(_target, getBasename(_path)); + if (useCopySuffix) _dest += "- COPY"; + await new DirectoryAPI(_dest).mkdir(); + (await subdirInfo.getFiles()).files.forEach(async (subsubdir) => { + await recuriveCopy(subsubdir.file_path, _dest); + }); + } else { + cpy(_path, _target); + } + }; + for (const file of clipboard.files) { + const dirInfo = new DirectoryAPI(file); + const dest = joinPath(target, getBasename(file)); + switch (clipboard.command) { + case "cp": + if (await dirInfo.isDir()) { + await recuriveCopy(file, target, true); + } else { + cpy(file, target); + } + break; + case "cut": + if (await new DirectoryAPI(dest).exists()) { + if ( + !(await ConfirmDialog( + "Target file exists", + "Target directory with the same file/dir name exists, do you want to overwrite it?", + "No", + )) + ) + return; + else { + await new OperationAPI(dest).unlink(); + } + } + await new OperationAPI(file, dest).cut(); + break; + } + } + switch (clipboard.command) { + case "cp": + OperationLog("copy", clipboard.files, target); + break; + case "cut": + OperationLog("cut", clipboard.files, target); + break; + } }; export default Paste; diff --git a/src/Components/Files/File Operation/pin.ts b/src/Components/Files/File Operation/pin.ts index fc02eec9..d385d014 100644 --- a/src/Components/Files/File Operation/pin.ts +++ b/src/Components/Files/File Operation/pin.ts @@ -1,11 +1,11 @@ -import createSidebar from '../../Layout/sidebar'; -import defaultFavorites from '../../Favorites/defaultFavorites'; -import Storage from '../../../Service/storage'; -import basename from '../../Functions/path/basename'; +import Storage from "../../../Service/storage"; +import defaultFavorites from "../../Favorites/defaultFavorites"; +import basename from "../../Functions/path/basename"; +import createSidebar from "../../Layout/sidebar"; interface Favorites { - name: string; - path: string; - icon: string; + name: string; + path: string; + icon: string; } /** @@ -14,18 +14,18 @@ interface Favorites { * @returns {void} */ const Pin = async (filePaths: string[]): Promise => { - const data = await Storage.get('favorites'); - let favorites = data?.favorites ?? [{ path: 'xplorer://Home', name: 'Home' }, ...(await defaultFavorites())]; - favorites.forEach((v: Favorites) => delete v.icon); - for (const filePath of filePaths) { - if (favorites.filter((favorite: Favorites) => favorite.path === filePath).length) { - favorites = favorites.filter((favorite: Favorites) => favorite.path !== filePath); - } else { - favorites.push({ name: basename(filePath), path: filePath }); - } - } - Storage.set('favorites', { favorites }); - createSidebar(); + const data = await Storage.get("favorites"); + let favorites = data?.favorites ?? [{ path: "xplorer://Home", name: "Home" }, ...(await defaultFavorites())]; + favorites.forEach((v: Favorites) => delete v.icon); + for (const filePath of filePaths) { + if (favorites.filter((favorite: Favorites) => favorite.path === filePath).length) { + favorites = favorites.filter((favorite: Favorites) => favorite.path !== filePath); + } else { + favorites.push({ name: basename(filePath), path: filePath }); + } + } + Storage.set("favorites", { favorites }); + createSidebar(); }; export default Pin; diff --git a/src/Components/Files/File Operation/redo.ts b/src/Components/Files/File Operation/redo.ts index b9f3070c..f7792a12 100644 --- a/src/Components/Files/File Operation/redo.ts +++ b/src/Components/Files/File Operation/redo.ts @@ -1,68 +1,68 @@ -import Copy from './copy'; -import Paste from './paste'; -import windowName from '../../../Service/window'; -import Storage from '../../../Service/storage'; -import NewFile from './new'; -import getBasename from '../../Functions/path/basename'; -import getDirname from '../../Functions/path/dirname'; -import NewFolder from '../../Folder/new'; -import DirectoryAPI from '../../../Service/directory'; -import ConfirmDialog from '../../Prompt/confirm'; -import OperationAPI from '../../../Service/operation'; -import joinPath from '../../Functions/path/joinPath'; -import { Trash } from './trash'; +import DirectoryAPI from "../../../Service/directory"; +import OperationAPI from "../../../Service/operation"; +import Storage from "../../../Service/storage"; +import windowName from "../../../Service/window"; +import NewFolder from "../../Folder/new"; +import getBasename from "../../Functions/path/basename"; +import getDirname from "../../Functions/path/dirname"; +import joinPath from "../../Functions/path/joinPath"; +import ConfirmDialog from "../../Prompt/confirm"; +import Copy from "./copy"; +import NewFile from "./new"; +import Paste from "./paste"; +import { Trash } from "./trash"; /** * Redo the _undo_ed Operation * @returns {Promise} */ const Redo = async (): Promise => { - const operationLogs = await Storage.get(`operations-${windowName}`); - const latestOperation = operationLogs.operations[operationLogs.currentIndex + 1]; - const increaseIndex = () => { - if (operationLogs.currentIndex + 2 >= operationLogs.operations.length) operationLogs.currentIndex = operationLogs.currentIndex + 1; - }; - switch (latestOperation.operationType) { - case 'copy': - Copy(latestOperation.sources); - Paste(latestOperation.destination); - break; - case 'cut': - for (const source of latestOperation.sources) { - const dest = joinPath(latestOperation.destination, getBasename(source)); - if (await new DirectoryAPI(dest).exists()) { - if ( - !(await ConfirmDialog( - 'Target file exists', - 'Target directory with the same file/dir name exists, do you want to overwrite it?', - 'No' - )) - ) - return; - else { - await new OperationAPI(dest).unlink(); - } - } - await new OperationAPI(source, dest).rename(); - } - increaseIndex(); - break; - case 'newfile': - NewFile(getBasename(latestOperation.destination), getDirname(latestOperation.destination), false); - increaseIndex(); - break; - case 'newfolder': - NewFolder(getBasename(latestOperation.destination), getDirname(latestOperation.destination), false); - increaseIndex(); - break; - case 'delete': - Trash(latestOperation.sources); - increaseIndex(); - break; - case 'rename': - await new OperationAPI(latestOperation.sources, latestOperation.destination).rename(); - increaseIndex(); - break; - } - Storage.set(`operations-${windowName}`, operationLogs); + const operationLogs = await Storage.get(`operations-${windowName}`); + const latestOperation = operationLogs.operations[operationLogs.currentIndex + 1]; + const increaseIndex = () => { + if (operationLogs.currentIndex + 2 >= operationLogs.operations.length) operationLogs.currentIndex = operationLogs.currentIndex + 1; + }; + switch (latestOperation.operationType) { + case "copy": + Copy(latestOperation.sources); + Paste(latestOperation.destination); + break; + case "cut": + for (const source of latestOperation.sources) { + const dest = joinPath(latestOperation.destination, getBasename(source)); + if (await new DirectoryAPI(dest).exists()) { + if ( + !(await ConfirmDialog( + "Target file exists", + "Target directory with the same file/dir name exists, do you want to overwrite it?", + "No", + )) + ) + return; + else { + await new OperationAPI(dest).unlink(); + } + } + await new OperationAPI(source, dest).rename(); + } + increaseIndex(); + break; + case "newfile": + NewFile(getBasename(latestOperation.destination), getDirname(latestOperation.destination), false); + increaseIndex(); + break; + case "newfolder": + NewFolder(getBasename(latestOperation.destination), getDirname(latestOperation.destination), false); + increaseIndex(); + break; + case "delete": + Trash(latestOperation.sources); + increaseIndex(); + break; + case "rename": + await new OperationAPI(latestOperation.sources, latestOperation.destination).rename(); + increaseIndex(); + break; + } + Storage.set(`operations-${windowName}`, operationLogs); }; export default Redo; diff --git a/src/Components/Files/File Operation/rename.ts b/src/Components/Files/File Operation/rename.ts index 09a7f8dd..9c99341c 100644 --- a/src/Components/Files/File Operation/rename.ts +++ b/src/Components/Files/File Operation/rename.ts @@ -1,32 +1,32 @@ -import { OperationLog } from '../../Functions/log'; -import focusingPath from '../../Functions/focusingPath'; -import Ask from '../../Prompt/ask'; -import basename from '../../Functions/path/basename'; -import getDirname from '../../Functions/path/dirname'; -import joinPath from '../../Functions/path/joinPath'; -import OperationAPI from '../../../Service/operation'; -import PromptError from '../../Prompt/error'; -import FileAPI from '../../../Service/files'; -import ConfirmDialog from '../../Prompt/confirm'; +import FileAPI from "../../../Service/files"; +import OperationAPI from "../../../Service/operation"; +import focusingPath from "../../Functions/focusingPath"; +import { OperationLog } from "../../Functions/log"; +import basename from "../../Functions/path/basename"; +import getDirname from "../../Functions/path/dirname"; +import joinPath from "../../Functions/path/joinPath"; +import Ask from "../../Prompt/ask"; +import ConfirmDialog from "../../Prompt/confirm"; +import PromptError from "../../Prompt/error"; /** * Rename file/folder name * @param {string} path - location of the file/folder * @returns {void} */ const Rename = (filePath: string): void => { - Ask('Rename', 'New File Name:', { value: basename(filePath) }).then(async (newName: string) => { - const target = getDirname(newName) === '.' ? joinPath(await focusingPath(), newName) : joinPath(getDirname(filePath), newName); - if (await new FileAPI(target).exists()) { - const confirm = await ConfirmDialog('File Exists', 'The new name already exists, do you want to overwrite it?', 'No'); - if (!confirm) return; - } - try { - new OperationAPI(filePath, target).rename(); - } catch (err) { - PromptError('Error renaming file', `Failed to rename ${filePath} [${err}]`); - } - OperationLog('rename', decodeURI(filePath), target); - }); + Ask("Rename", "New File Name:", { value: basename(filePath) }).then(async (newName: string) => { + const target = getDirname(newName) === "." ? joinPath(await focusingPath(), newName) : joinPath(getDirname(filePath), newName); + if (await new FileAPI(target).exists()) { + const confirm = await ConfirmDialog("File Exists", "The new name already exists, do you want to overwrite it?", "No"); + if (!confirm) return; + } + try { + new OperationAPI(filePath, target).rename(); + } catch (err) { + PromptError("Error renaming file", `Failed to rename ${filePath} [${err}]`); + } + OperationLog("rename", decodeURI(filePath), target); + }); }; export default Rename; diff --git a/src/Components/Files/File Operation/search.ts b/src/Components/Files/File Operation/search.ts index 2c88a9e6..137679f8 100644 --- a/src/Components/Files/File Operation/search.ts +++ b/src/Components/Files/File Operation/search.ts @@ -1,20 +1,20 @@ -import Translate from '../../I18n/i18n'; -import focusingPath from '../../Functions/focusingPath'; -import DirectoryAPI from '../../../Service/directory'; -import { startLoading, stopLoading } from '../../Functions/Loading/loading'; -import displayFiles from '../../Open/displayFiles'; -import changePosition from '../../Functions/changePosition'; -import { LOAD_IMAGE } from '../../Functions/lazyLoadingImage'; -import { updateTheme } from '../../Theme/theme'; -import { OpenLog } from '../../Functions/log'; -import { OpenDir } from '../../Open/open'; -import isTauri from '../../../Util/is-tauri'; -import { GET_TAB_ELEMENT } from '../../../Util/constants'; +import DirectoryAPI from "../../../Service/directory"; +import { GET_TAB_ELEMENT } from "../../../Util/constants"; +import isTauri from "../../../Util/is-tauri"; +import { startLoading, stopLoading } from "../../Functions/Loading/loading"; +import changePosition from "../../Functions/changePosition"; +import focusingPath from "../../Functions/focusingPath"; +import { LOAD_IMAGE } from "../../Functions/lazyLoadingImage"; +import { OpenLog } from "../../Functions/log"; +import Translate from "../../I18n/i18n"; +import displayFiles from "../../Open/displayFiles"; +import { OpenDir } from "../../Open/open"; +import { updateTheme } from "../../Theme/theme"; let being_watch: string; const stopSearchingProcess = async (): Promise => { - being_watch = null; - if (await new DirectoryAPI('').stopSearching()) stopLoading(); + being_watch = null; + if (await new DirectoryAPI("").stopSearching()) stopLoading(); }; /** @@ -24,33 +24,33 @@ const stopSearchingProcess = async (): Promise => { * @returns {Promise} */ const processSearch = async (to_search: string, search_in: string): Promise => { - const MAIN_ELEMENT = GET_TAB_ELEMENT(); - MAIN_ELEMENT.innerHTML = ''; - if (!to_search.length) OpenDir(search_in); - startLoading(); - const search_path = `Search: [[${to_search}]] inside [[${search_in}]]`; - changePosition(search_path); - let foundSomething = false; + const MAIN_ELEMENT = GET_TAB_ELEMENT(); + MAIN_ELEMENT.innerHTML = ""; + if (!to_search.length) OpenDir(search_in); + startLoading(); + const search_path = `Search: [[${to_search}]] inside [[${search_in}]]`; + changePosition(search_path); + let foundSomething = false; - const finalResult = await new DirectoryAPI(search_in).search(to_search, async (partialFound) => { - let _el = document.createElement('div') as HTMLElement; - foundSomething = true; - if (document.querySelector('.path-navigator').value.startsWith('Search: ')) - _el = await displayFiles(partialFound, search_path, _el, null, true); - for (const childEl of _el.children) { - MAIN_ELEMENT.appendChild(childEl); - } - }); - const _el = document.createElement('div'); - MAIN_ELEMENT.appendChild(await displayFiles(finalResult, search_path, _el, null, true)); - if (!finalResult.length && !foundSomething) { - MAIN_ELEMENT.classList.add('empty-dir-notification'); - MAIN_ELEMENT.innerText = "Can't find specified query"; - } - stopLoading(); - updateTheme('grid'); - LOAD_IMAGE(); - OpenLog(search_path); + const finalResult = await new DirectoryAPI(search_in).search(to_search, async (partialFound) => { + let _el = document.createElement("div") as HTMLElement; + foundSomething = true; + if (document.querySelector(".path-navigator").value.startsWith("Search: ")) + _el = await displayFiles(partialFound, search_path, _el, null, true); + for (const childEl of _el.children) { + MAIN_ELEMENT.appendChild(childEl); + } + }); + const _el = document.createElement("div"); + MAIN_ELEMENT.appendChild(await displayFiles(finalResult, search_path, _el, null, true)); + if (!finalResult.length && !foundSomething) { + MAIN_ELEMENT.classList.add("empty-dir-notification"); + MAIN_ELEMENT.innerText = "Can't find specified query"; + } + stopLoading(); + updateTheme("grid"); + LOAD_IMAGE(); + OpenLog(search_path); }; /** @@ -58,57 +58,57 @@ const processSearch = async (to_search: string, search_in: string): Promise} */ const getFocusingPath = async (): Promise => { - let _focusingPath = await focusingPath(); - if (_focusingPath.startsWith('Search: ')) { - const splitByInsideKeyword = _focusingPath.split(' inside '); - if (splitByInsideKeyword.length === 2) { - _focusingPath = splitByInsideKeyword[1].slice(2, -2); - } else { - for (let i = 0; i < splitByInsideKeyword.length; i++) { - if (splitByInsideKeyword[i]?.endsWith(']]') && splitByInsideKeyword[i + 1]?.startsWith('[[')) { - _focusingPath = splitByInsideKeyword - .slice(i + 1) - .join(' inside ') - .slice(2, -2); - } - } - } - } - return _focusingPath; + let _focusingPath = await focusingPath(); + if (_focusingPath.startsWith("Search: ")) { + const splitByInsideKeyword = _focusingPath.split(" inside "); + if (splitByInsideKeyword.length === 2) { + _focusingPath = splitByInsideKeyword[1].slice(2, -2); + } else { + for (let i = 0; i < splitByInsideKeyword.length; i++) { + if (splitByInsideKeyword[i]?.endsWith("]]") && splitByInsideKeyword[i + 1]?.startsWith("[[")) { + _focusingPath = splitByInsideKeyword + .slice(i + 1) + .join(" inside ") + .slice(2, -2); + } + } + } + } + return _focusingPath; }; /** * Initialize search feature in Xplorer * @returns {Promise} */ const Search = async (): Promise => { - let listener: ReturnType; - const searchElement = document.querySelector('.search-bar'); - if (!isTauri) { - searchElement.setAttribute('disabled', ''); - } - searchElement.placeholder = `🔎 ${await Translate('Search')}`; - searchElement.addEventListener('keydown', async (e: KeyboardEvent) => { - clearTimeout(listener); - if (e.ctrlKey && e.key === 'f') { - return; - } else if (e.key === 'Enter') { - const value = (e.target as HTMLInputElement).value; - if (value !== being_watch) { - processSearch(value, await getFocusingPath()); - being_watch = value; - } - } else { - listener = setTimeout(async () => { - const value = (e.target as HTMLInputElement).value; - if (value === '') { - OpenDir(await getFocusingPath()); - } else if (value !== being_watch) { - processSearch(value, await getFocusingPath()); - being_watch = value; - } - }, 1000); - } - }); + let listener: ReturnType; + const searchElement = document.querySelector(".search-bar"); + if (!isTauri) { + searchElement.setAttribute("disabled", ""); + } + searchElement.placeholder = `🔎 ${await Translate("Search")}`; + searchElement.addEventListener("keydown", async (e: KeyboardEvent) => { + clearTimeout(listener); + if (e.ctrlKey && e.key === "f") { + return; + } else if (e.key === "Enter") { + const value = (e.target as HTMLInputElement).value; + if (value !== being_watch) { + processSearch(value, await getFocusingPath()); + being_watch = value; + } + } else { + listener = setTimeout(async () => { + const value = (e.target as HTMLInputElement).value; + if (value === "") { + OpenDir(await getFocusingPath()); + } else if (value !== being_watch) { + processSearch(value, await getFocusingPath()); + being_watch = value; + } + }, 1000); + } + }); }; export default Search; export { processSearch, stopSearchingProcess }; diff --git a/src/Components/Files/File Operation/select.ts b/src/Components/Files/File Operation/select.ts index 57a1abc9..94ddf3d5 100644 --- a/src/Components/Files/File Operation/select.ts +++ b/src/Components/Files/File Operation/select.ts @@ -1,19 +1,19 @@ -import { elementClassNameContains } from '../../Functions/elementClassNameContains'; -import Storage from '../../../Service/storage'; -import { UpdateInfo } from '../../Layout/infobar'; -import FileAPI from '../../../Service/files'; -import formatBytes from '../../Functions/filesize'; -import Preview from '../File Preview/preview'; -import { ensureElementInViewPort } from '../../Functions/viewport'; -import { MAIN_BOX_ELEMENT } from '../../../Util/constants'; -import { direction } from '../../../Typings/select'; +import FileAPI from "../../../Service/files"; +import Storage from "../../../Service/storage"; +import type { direction } from "../../../Typings/select"; +import { MAIN_BOX_ELEMENT } from "../../../Util/constants"; +import { elementClassNameContains } from "../../Functions/elementClassNameContains"; +import formatBytes from "../../Functions/filesize"; +import { ensureElementInViewPort } from "../../Functions/viewport"; +import { UpdateInfo } from "../../Layout/infobar"; +import Preview from "../File Preview/preview"; let latestSelected: HTMLElement; let latestShiftSelected: HTMLElement; //Mouse drag selection vars class Point { - private _x: number; + private _x: number; private _y: number; constructor(x = 0, y = 0) { @@ -21,48 +21,63 @@ class Point { this._y = y; } - public get x(): number { return this._x; } - public get y(): number { return this._y; } + public get x(): number { + return this._x; + } + public get y(): number { + return this._y; + } - public set x(newX: number) { this._x = newX; } - public set y(newY: number) { this._y = newY; } + public set x(newX: number) { + this._x = newX; + } + public set y(newY: number) { + this._y = newY; + } public Set(x: number, y: number) { this.x = x; this.y = y; } - public delta(target: Point) { - return new Point(this.x - target.x, this.y - target.y); - } + public delta(target: Point) { + return new Point(this.x - target.x, this.y - target.y); + } } -let selectingDiv: HTMLElement = document.createElement('div'); -selectingDiv.setAttribute('style', 'position: absolute; background-color: rgba(100, 100, 255, 0.2); z-index: 100;'); -let isSelecting: boolean = false; +const selectingDiv: HTMLElement = document.createElement("div"); +selectingDiv.setAttribute("style", "position: absolute; background-color: rgba(100, 100, 255, 0.2); z-index: 100;"); +let isSelecting = false; let selectingOrigin: Point; let mainBoxBounds: DOMRect; let selected = 0; -const selectingDivBounds = { left: 0, top: 0, right: 0, bottom: 0, height: 0, width: 0 }; +const selectingDivBounds = { + left: 0, + top: 0, + right: 0, + bottom: 0, + height: 0, + width: 0, +}; /** * Call this function whenever user selected (a) file grid(s). * @returns {Promise} */ const ChangeSelectedEvent = async (): Promise => { - const selectedFileGrid = document.querySelectorAll('.file-grid.selected'); - if (!selectedFileGrid.length) UpdateInfo('selected-files', ''); - else { - const selectedFilePaths = Array.from(selectedFileGrid).map((element) => decodeURI((element as HTMLElement).dataset.path)); - const total_sizes = await new FileAPI(selectedFilePaths).calculateFilesSize(); - UpdateInfo('selected-files', `${selectedFileGrid.length} file${selectedFileGrid.length > 1 ? 's' : ''} selected ${formatBytes(total_sizes)}`); - if ( - selectedFilePaths.length === 1 && - document.querySelectorAll('.preview').length > 0 && - ((await Storage.get('preference'))?.automaticallyChangePreviewFile ?? true) - ) { - Preview(selectedFilePaths[0]); - } - } + const selectedFileGrid = document.querySelectorAll(".file-grid.selected"); + if (!selectedFileGrid.length) UpdateInfo("selected-files", ""); + else { + const selectedFilePaths = Array.from(selectedFileGrid).map((element) => decodeURI((element as HTMLElement).dataset.path)); + const total_sizes = await new FileAPI(selectedFilePaths).calculateFilesSize(); + UpdateInfo("selected-files", `${selectedFileGrid.length} file${selectedFileGrid.length > 1 ? "s" : ""} selected ${formatBytes(total_sizes)}`); + if ( + selectedFilePaths.length === 1 && + document.querySelectorAll(".preview").length > 0 && + ((await Storage.get("preference"))?.automaticallyChangePreviewFile ?? true) + ) { + Preview(selectedFilePaths[0]); + } + } }; /** * Select a file grid... @@ -78,32 +93,32 @@ const ChangeSelectedEvent = async (): Promise => { * @returns {void} */ const Select = (element: HTMLElement, ctrl: boolean, shift: boolean): void => { - if (!ctrl && !shift) unselectAllSelected(); - // add 'selected' class if element classlist does not contain it... - if (!element.classList.contains('selected')) element.classList.add('selected'); - // ...Otherwise, remove it - else element.classList.remove('selected'); - if (shift && latestSelected) { - let start = false; - for (const _element of document.querySelectorAll('.file')) { - if (start) _element.classList.add('selected'); - else _element.classList.remove('selected'); - if (_element === latestSelected) { - start = !start; - _element.classList.add('selected'); - } else if (_element === element) { - start = !start; - _element.classList.add('selected'); - } - } - } else { - const { getSelectedAllStatus } = require('../../Shortcut/shortcut'); //eslint-disable-line - if (getSelectedAllStatus() && ctrl) return; - latestSelected = element; - latestShiftSelected = element; - } - ChangeSelectedEvent(); - ensureElementInViewPort(element); + if (!ctrl && !shift) unselectAllSelected(); + // add 'selected' class if element classlist does not contain it... + if (!element.classList.contains("selected")) element.classList.add("selected"); + // ...Otherwise, remove it + else element.classList.remove("selected"); + if (shift && latestSelected) { + let start = false; + for (const _element of document.querySelectorAll(".file")) { + if (start) _element.classList.add("selected"); + else _element.classList.remove("selected"); + if (_element === latestSelected) { + start = !start; + _element.classList.add("selected"); + } else if (_element === element) { + start = !start; + _element.classList.add("selected"); + } + } + } else { + const { getSelectedAllStatus } = require("../../Shortcut/shortcut"); //eslint-disable-line + if (getSelectedAllStatus() && ctrl) return; + latestSelected = element; + latestShiftSelected = element; + } + ChangeSelectedEvent(); + ensureElementInViewPort(element); }; /** @@ -111,15 +126,15 @@ const Select = (element: HTMLElement, ctrl: boolean, shift: boolean): void => { * @returns {Promise} */ const selectFirstFile = async (): Promise => { - const hideHiddenFiles = (await Storage.get('preference'))?.hideHiddenFiles ?? true; - const firstFileElement = MAIN_BOX_ELEMENT().querySelector(`.file${hideHiddenFiles ? ':not([data-hidden-file])' : ''}`); - firstFileElement.classList.add('selected'); - ChangeSelectedEvent(); - latestSelected = firstFileElement as HTMLElement; + const hideHiddenFiles = (await Storage.get("preference"))?.hideHiddenFiles ?? true; + const firstFileElement = MAIN_BOX_ELEMENT().querySelector(`.file${hideHiddenFiles ? ":not([data-hidden-file])" : ""}`); + firstFileElement.classList.add("selected"); + ChangeSelectedEvent(); + latestSelected = firstFileElement as HTMLElement; }; const elementIndex = (element: HTMLElement): number => { - return Array.from(element.parentNode.children).indexOf(element); + return Array.from(element.parentNode.children).indexOf(element); }; /** @@ -127,191 +142,200 @@ const elementIndex = (element: HTMLElement): number => { * @returns {void} */ const SelectInit = (): void => { - //Saving the main box element in a variable, better than calling MAIN_BOX_ELEMENT() everytime - const MAIN_BOX_EL: HTMLElement = MAIN_BOX_ELEMENT(); - mainBoxBounds = MAIN_BOX_EL.getBoundingClientRect(); - - MAIN_BOX_EL.addEventListener('click', (e) => { - if ( - !(e.target as HTMLElement).className.split(' ').some(function (c) { - return /file/.test(c); - }) && - //If user doesn't drag the mouse - (e.pageX - mainBoxBounds.left == selectingOrigin.x && - e.pageY - mainBoxBounds.top == selectingOrigin.y) - ) { - unselectAllSelected(); - latestSelected = null; - latestShiftSelected = null; - } - let fileTarget = e.target as HTMLElement; - while (fileTarget?.classList && !fileTarget.classList.contains('file')) fileTarget = fileTarget.parentNode as HTMLElement; - if (fileTarget.id === 'workspace' || !fileTarget?.classList?.contains('file')) return; - - Select(fileTarget, e.ctrlKey, e.shiftKey); - }); - - MAIN_BOX_EL.addEventListener('mousedown', (e) => { - /// SelectInit is called async, therefore bounds come before full element calculation. - /// Here is to avoid wrong div placement, but we can find a better way without calling getBoundingClientRect each mousedown - mainBoxBounds = MAIN_BOX_EL.getBoundingClientRect(); - //Start selection - isSelecting = true; - //Save selection starting point - selectingOrigin = new Point(e.pageX - mainBoxBounds.left, e.pageY - mainBoxBounds.top); - if ( - !(e.target as HTMLElement).className.split(' ').some(function (c) { - return /file/.test(c); - }) - ) { - MAIN_BOX_EL.prepend(selectingDiv); - selectingDiv.style.inset = selectingOrigin.y + 'px auto ' + selectingOrigin.x + 'px auto'; - selectingDiv.style.width = selectingDiv.style.height = 'auto'; - } - }); - - //Check when mouse is released. On window to catch events outside of main box - window.addEventListener('mouseup', (e) => { - if(isSelecting) { - isSelecting = false; - - selectingDiv.style.inset = selectingDiv.style.width = selectingDiv.style.height = 'auto'; - - selectingDiv.remove(); - } - }); - - //Calculates selection div size and position + which files are selected - MAIN_BOX_EL.addEventListener('mousemove', async(e) => { - const POSITION = new Point(e.pageX - mainBoxBounds.left, e.pageY - mainBoxBounds.top); - if(isSelecting) { - const DIRECTION = await getSelectingDivDirection(selectingOrigin, POSITION); - let top, right, bottom, left, - height = Math.abs(selectingOrigin.y - POSITION.y), - width = Math.abs(selectingOrigin.x - POSITION.x); - - switch(DIRECTION.y) { - case 0: - top = selectingOrigin.y; - bottom = mainBoxBounds.height - selectingOrigin.y; - break; - case -1: - bottom = mainBoxBounds.height - selectingOrigin.y; - top = 'auto'; - break; - case 1: - bottom = 'auto'; - top = selectingOrigin.y; - break; - } - - switch(DIRECTION.x) { - case 0: - left = selectingOrigin.x; - right = mainBoxBounds.width - selectingOrigin.x; - break; - case -1: - left = 'auto'; - right = mainBoxBounds.width - selectingOrigin.x; - break; - case 1: - left = selectingOrigin.x; - right = 'auto'; - break; - } - - //Updating selecting div bounds manually so we don't call getBoundingClientRect each mousemove - selectingDivBounds.bottom = bottom == 'auto' ? mainBoxBounds.height - (top as number) - height : bottom as number; - selectingDivBounds.top = top == 'auto' ? mainBoxBounds.height - (bottom as number) - height : top as number; - selectingDivBounds.left = left == 'auto' ? mainBoxBounds.width - (right as number) - width : left as number; - selectingDivBounds.right = right == 'auto' ? mainBoxBounds.width - (left as number) - width : right as number; - selectingDivBounds.width = width; - selectingDivBounds.height = height; - - selectingDiv.style.inset = top + (top == 'auto' ? ' ' : 'px ') + right + (right == 'auto' ? ' ' : 'px ') + - bottom + (bottom == 'auto' ? ' ' : 'px ') + left + (left == 'auto' ? ' ' : 'px '); - selectingDiv.style.height = height + 'px'; - selectingDiv.style.width = width + 'px'; - - const FILES = MAIN_BOX_EL.getElementsByClassName('file'); - - for(let x = 0; x < FILES.length; x++) { - const CURRENT = FILES[x] as HTMLElement; - //This should be fine since this function is async - const BOUNDS = CURRENT.getBoundingClientRect(); - - //If overlaps - if(!(BOUNDS.right - mainBoxBounds.left < selectingDivBounds.left || - BOUNDS.left - mainBoxBounds.left > mainBoxBounds.width - selectingDivBounds.right || - BOUNDS.bottom - mainBoxBounds.top < selectingDivBounds.top || - BOUNDS.top - mainBoxBounds.top > mainBoxBounds.height - selectingDivBounds.bottom) && - isSelecting) - { - if(!CURRENT.classList.contains('selected')) CURRENT.classList.add('selected'); - selected++; - } else { - if(CURRENT.classList.contains('selected')) { - CURRENT.classList.remove('selected'); - selected--; - } - } - } - if(selected == 0) unselectAllSelected(); - } - }); - - //Updates main box bounds on resize - MAIN_BOX_EL.addEventListener('resize', (e) => { - mainBoxBounds = MAIN_BOX_EL.getBoundingClientRect(); - }); - - const selectShortcut = async (e: KeyboardEvent) => { - // Ignore keyboard shortcuts for select files if input element has focus. - if (document.activeElement.tagName === 'INPUT') return; - - const hideHiddenFiles = (await Storage.get('preference'))?.hideHiddenFiles ?? true; - - const keyHandlers: { - [key: string]: (e: KeyboardEvent, hideHiddenFiles: boolean) => void; - } = { - ArrowRight: arrowRightHandler, - ArrowLeft: arrowLeftHandler, - ArrowDown: arrowDownHandler, - ArrowUp: arrowUpHandler, - }; - - if (!e.altKey && keyHandlers[e.key]) { - if (!document.contains(latestSelected)) { - await selectFirstFile(); - return; - } - - keyHandlers[e.key](e, hideHiddenFiles); - } - }; - document.addEventListener('keydown', selectShortcut); + //Saving the main box element in a variable, better than calling MAIN_BOX_ELEMENT() everytime + const MAIN_BOX_EL: HTMLElement = MAIN_BOX_ELEMENT(); + mainBoxBounds = MAIN_BOX_EL.getBoundingClientRect(); + + MAIN_BOX_EL.addEventListener("click", (e) => { + if ( + !(e.target as HTMLElement).className.split(" ").some((c) => /file/.test(c)) && + //If user doesn't drag the mouse + e.pageX - mainBoxBounds.left == selectingOrigin.x && + e.pageY - mainBoxBounds.top == selectingOrigin.y + ) { + unselectAllSelected(); + latestSelected = null; + latestShiftSelected = null; + } + let fileTarget = e.target as HTMLElement; + while (fileTarget?.classList && !fileTarget.classList.contains("file")) fileTarget = fileTarget.parentNode as HTMLElement; + if (fileTarget.id === "workspace" || !fileTarget?.classList?.contains("file")) return; + + Select(fileTarget, e.ctrlKey, e.shiftKey); + }); + + MAIN_BOX_EL.addEventListener("mousedown", (e) => { + /// SelectInit is called async, therefore bounds come before full element calculation. + /// Here is to avoid wrong div placement, but we can find a better way without calling getBoundingClientRect each mousedown + mainBoxBounds = MAIN_BOX_EL.getBoundingClientRect(); + //Start selection + isSelecting = true; + //Save selection starting point + selectingOrigin = new Point(e.pageX - mainBoxBounds.left, e.pageY - mainBoxBounds.top); + if (!(e.target as HTMLElement).className.split(" ").some((c) => /file/.test(c))) { + MAIN_BOX_EL.prepend(selectingDiv); + selectingDiv.style.inset = selectingOrigin.y + "px auto " + selectingOrigin.x + "px auto"; + selectingDiv.style.width = selectingDiv.style.height = "auto"; + } + }); + + //Check when mouse is released. On window to catch events outside of main box + window.addEventListener("mouseup", (e) => { + if (isSelecting) { + isSelecting = false; + + selectingDiv.style.inset = selectingDiv.style.width = selectingDiv.style.height = "auto"; + + selectingDiv.remove(); + } + }); + + //Calculates selection div size and position + which files are selected + MAIN_BOX_EL.addEventListener("mousemove", async (e) => { + const POSITION = new Point(e.pageX - mainBoxBounds.left, e.pageY - mainBoxBounds.top); + if (isSelecting) { + const DIRECTION = await getSelectingDivDirection(selectingOrigin, POSITION); + let top, + right, + bottom, + left, + height = Math.abs(selectingOrigin.y - POSITION.y), + width = Math.abs(selectingOrigin.x - POSITION.x); + + switch (DIRECTION.y) { + case 0: + top = selectingOrigin.y; + bottom = mainBoxBounds.height - selectingOrigin.y; + break; + case -1: + bottom = mainBoxBounds.height - selectingOrigin.y; + top = "auto"; + break; + case 1: + bottom = "auto"; + top = selectingOrigin.y; + break; + } + + switch (DIRECTION.x) { + case 0: + left = selectingOrigin.x; + right = mainBoxBounds.width - selectingOrigin.x; + break; + case -1: + left = "auto"; + right = mainBoxBounds.width - selectingOrigin.x; + break; + case 1: + left = selectingOrigin.x; + right = "auto"; + break; + } + + //Updating selecting div bounds manually so we don't call getBoundingClientRect each mousemove + selectingDivBounds.bottom = bottom == "auto" ? mainBoxBounds.height - (top as number) - height : (bottom as number); + selectingDivBounds.top = top == "auto" ? mainBoxBounds.height - (bottom as number) - height : (top as number); + selectingDivBounds.left = left == "auto" ? mainBoxBounds.width - (right as number) - width : (left as number); + selectingDivBounds.right = right == "auto" ? mainBoxBounds.width - (left as number) - width : (right as number); + selectingDivBounds.width = width; + selectingDivBounds.height = height; + + selectingDiv.style.inset = + top + + (top == "auto" ? " " : "px ") + + right + + (right == "auto" ? " " : "px ") + + bottom + + (bottom == "auto" ? " " : "px ") + + left + + (left == "auto" ? " " : "px "); + selectingDiv.style.height = height + "px"; + selectingDiv.style.width = width + "px"; + + const FILES = MAIN_BOX_EL.getElementsByClassName("file"); + + for (let x = 0; x < FILES.length; x++) { + const CURRENT = FILES[x] as HTMLElement; + //This should be fine since this function is async + const BOUNDS = CURRENT.getBoundingClientRect(); + + //If overlaps + if ( + !( + BOUNDS.right - mainBoxBounds.left < selectingDivBounds.left || + BOUNDS.left - mainBoxBounds.left > mainBoxBounds.width - selectingDivBounds.right || + BOUNDS.bottom - mainBoxBounds.top < selectingDivBounds.top || + BOUNDS.top - mainBoxBounds.top > mainBoxBounds.height - selectingDivBounds.bottom + ) && + isSelecting + ) { + if (!CURRENT.classList.contains("selected")) CURRENT.classList.add("selected"); + selected++; + } else { + if (CURRENT.classList.contains("selected")) { + CURRENT.classList.remove("selected"); + selected--; + } + } + } + if (selected == 0) unselectAllSelected(); + } + }); + + //Updates main box bounds on resize + MAIN_BOX_EL.addEventListener("resize", (e) => { + mainBoxBounds = MAIN_BOX_EL.getBoundingClientRect(); + }); + + const selectShortcut = async (e: KeyboardEvent) => { + // Ignore keyboard shortcuts for select files if input element has focus. + if (document.activeElement.tagName === "INPUT") return; + + const hideHiddenFiles = (await Storage.get("preference"))?.hideHiddenFiles ?? true; + + const keyHandlers: { + [key: string]: (e: KeyboardEvent, hideHiddenFiles: boolean) => void; + } = { + ArrowRight: arrowRightHandler, + ArrowLeft: arrowLeftHandler, + ArrowDown: arrowDownHandler, + ArrowUp: arrowUpHandler, + }; + + if (!e.altKey && keyHandlers[e.key]) { + if (!document.contains(latestSelected)) { + await selectFirstFile(); + return; + } + + keyHandlers[e.key](e, hideHiddenFiles); + } + }; + document.addEventListener("keydown", selectShortcut); }; /** - * + * * @param origin - mouse drag selection origin point * @param last - last mouse position * @returns {Promise} - direction based on coord deltas, x and y can be either -1, 0 or 1 indicating the direction relative to point 0,0 */ -const getSelectingDivDirection = async(origin: Point, last: Point): Promise => { - const delta = origin.delta(last); +const getSelectingDivDirection = async (origin: Point, last: Point): Promise => { + const delta = origin.delta(last); - return { x: delta.x == 0 ? 0 : delta.x > 0 ? -1 : 1, - y: delta.y == 0 ? 0 : delta.y > 0 ? -1 : 1 }; -} + return { + x: delta.x == 0 ? 0 : delta.x > 0 ? -1 : 1, + y: delta.y == 0 ? 0 : delta.y > 0 ? -1 : 1, + }; +}; /** * Unselect all selected file grids. * @returns {void} */ const unselectAllSelected = (): void => { - document.querySelectorAll('.selected').forEach((element) => element.classList.remove('selected')); - ChangeSelectedEvent(); - return; + document.querySelectorAll(".selected").forEach((element) => element.classList.remove("selected")); + ChangeSelectedEvent(); + return; }; /** @@ -319,146 +343,146 @@ const unselectAllSelected = (): void => { * @returns {NodeListOf} */ const getSelected = (): NodeListOf => { - return document.querySelectorAll('.selected'); + return document.querySelectorAll(".selected"); }; const arrowRightHandler = (e: KeyboardEvent, hideHiddenFiles: boolean): void => { - if (latestShiftSelected && elementIndex(latestShiftSelected) < elementIndex(latestSelected)) { - latestShiftSelected = latestSelected; - } - e.preventDefault(); - let nextSibling = (e.shiftKey ? latestShiftSelected.nextSibling : latestSelected.nextSibling) as HTMLElement; - if (hideHiddenFiles) { - while (nextSibling && nextSibling.dataset.isHidden === 'true') { - nextSibling = nextSibling.nextSibling as HTMLElement; - } - } - if (elementClassNameContains(nextSibling, /file/)) { - ensureElementInViewPort(nextSibling); - unselectAllSelected(); - if (e.shiftKey) { - let start = false; - for (const sibling of latestSelected.parentNode.children) { - if (start || sibling === nextSibling || sibling === latestSelected) { - if (!(hideHiddenFiles && (sibling as HTMLElement).dataset.isHidden === 'true')) sibling.classList.add('selected'); - } - if (sibling === latestSelected) start = true; - if (sibling === nextSibling) break; - } - latestShiftSelected = nextSibling; - } else { - latestSelected.classList.remove('selected'); - latestSelected = nextSibling; - nextSibling.classList.add('selected'); - } - ChangeSelectedEvent(); - } + if (latestShiftSelected && elementIndex(latestShiftSelected) < elementIndex(latestSelected)) { + latestShiftSelected = latestSelected; + } + e.preventDefault(); + let nextSibling = (e.shiftKey ? latestShiftSelected.nextSibling : latestSelected.nextSibling) as HTMLElement; + if (hideHiddenFiles) { + while (nextSibling && nextSibling.dataset.isHidden === "true") { + nextSibling = nextSibling.nextSibling as HTMLElement; + } + } + if (elementClassNameContains(nextSibling, /file/)) { + ensureElementInViewPort(nextSibling); + unselectAllSelected(); + if (e.shiftKey) { + let start = false; + for (const sibling of latestSelected.parentNode.children) { + if (start || sibling === nextSibling || sibling === latestSelected) { + if (!(hideHiddenFiles && (sibling as HTMLElement).dataset.isHidden === "true")) sibling.classList.add("selected"); + } + if (sibling === latestSelected) start = true; + if (sibling === nextSibling) break; + } + latestShiftSelected = nextSibling; + } else { + latestSelected.classList.remove("selected"); + latestSelected = nextSibling; + nextSibling.classList.add("selected"); + } + ChangeSelectedEvent(); + } }; const arrowLeftHandler = (e: KeyboardEvent, hideHiddenFiles: boolean): void => { - if (latestShiftSelected && elementIndex(latestShiftSelected) > elementIndex(latestSelected)) latestShiftSelected = latestSelected; - - e.preventDefault(); - let previousSibling = (e.shiftKey ? latestShiftSelected.previousSibling : latestSelected.previousSibling) as HTMLElement; - if (hideHiddenFiles) { - while (previousSibling && previousSibling.dataset.isHidden === 'true') { - previousSibling = previousSibling.previousSibling as HTMLElement; - } - } - if (elementClassNameContains(previousSibling, /file/)) { - ensureElementInViewPort(previousSibling); - let start = false; - unselectAllSelected(); - if (e.shiftKey) { - for (const sibling of latestSelected.parentNode.children) { - if (start || sibling === previousSibling || sibling === latestSelected) { - if (!(hideHiddenFiles && (sibling as HTMLElement).dataset.isHidden === 'true')) sibling.classList.add('selected'); - } - if (sibling === previousSibling) start = true; - if (sibling === latestSelected) break; - } - latestShiftSelected = previousSibling; - } else { - latestSelected.classList.remove('selected'); - latestSelected = previousSibling; - previousSibling.classList.add('selected'); - } - ChangeSelectedEvent(); - } + if (latestShiftSelected && elementIndex(latestShiftSelected) > elementIndex(latestSelected)) latestShiftSelected = latestSelected; + + e.preventDefault(); + let previousSibling = (e.shiftKey ? latestShiftSelected.previousSibling : latestSelected.previousSibling) as HTMLElement; + if (hideHiddenFiles) { + while (previousSibling && previousSibling.dataset.isHidden === "true") { + previousSibling = previousSibling.previousSibling as HTMLElement; + } + } + if (elementClassNameContains(previousSibling, /file/)) { + ensureElementInViewPort(previousSibling); + let start = false; + unselectAllSelected(); + if (e.shiftKey) { + for (const sibling of latestSelected.parentNode.children) { + if (start || sibling === previousSibling || sibling === latestSelected) { + if (!(hideHiddenFiles && (sibling as HTMLElement).dataset.isHidden === "true")) sibling.classList.add("selected"); + } + if (sibling === previousSibling) start = true; + if (sibling === latestSelected) break; + } + latestShiftSelected = previousSibling; + } else { + latestSelected.classList.remove("selected"); + latestSelected = previousSibling; + previousSibling.classList.add("selected"); + } + ChangeSelectedEvent(); + } }; const arrowDownHandler = (e: KeyboardEvent, hideHiddenFiles: boolean): void => { - if (latestShiftSelected && elementIndex(latestShiftSelected) < elementIndex(latestSelected)) latestShiftSelected = latestSelected; - - e.preventDefault(); - const totalGridInArrow = Math.floor( - (latestSelected.parentNode as HTMLElement).offsetWidth / - (latestSelected.offsetWidth + parseInt(getComputedStyle(latestSelected).marginLeft) * 2) - ); // Calculate the total of grids in arrow - const siblings = latestSelected.parentNode.children; - let elementBelow = siblings[Array.from(siblings).indexOf(e.shiftKey ? latestShiftSelected : latestSelected) + totalGridInArrow] as HTMLElement; - if (hideHiddenFiles) { - while (elementBelow && elementBelow.dataset.isHidden === 'true') { - elementBelow = siblings[Array.from(siblings).indexOf(elementBelow) + totalGridInArrow] as HTMLElement; - } - } - if (elementClassNameContains(elementBelow, /file/)) { - ensureElementInViewPort(elementBelow); - let start = false; - unselectAllSelected(); - if (e.shiftKey) { - for (const sibling of latestSelected.parentNode.children) { - if (start || sibling === elementBelow || sibling === latestSelected) { - if (!(hideHiddenFiles && (sibling as HTMLElement).dataset.isHidden === 'true')) sibling.classList.add('selected'); - } - if (sibling === latestSelected) start = true; - if (sibling === elementBelow) break; - } - latestShiftSelected = elementBelow; - } else { - latestSelected.classList.remove('selected'); - latestSelected = elementBelow; - elementBelow.classList.add('selected'); - } - ChangeSelectedEvent(); - } + if (latestShiftSelected && elementIndex(latestShiftSelected) < elementIndex(latestSelected)) latestShiftSelected = latestSelected; + + e.preventDefault(); + const totalGridInArrow = Math.floor( + (latestSelected.parentNode as HTMLElement).offsetWidth / + (latestSelected.offsetWidth + Number.parseInt(getComputedStyle(latestSelected).marginLeft) * 2), + ); // Calculate the total of grids in arrow + const siblings = latestSelected.parentNode.children; + let elementBelow = siblings[Array.from(siblings).indexOf(e.shiftKey ? latestShiftSelected : latestSelected) + totalGridInArrow] as HTMLElement; + if (hideHiddenFiles) { + while (elementBelow && elementBelow.dataset.isHidden === "true") { + elementBelow = siblings[Array.from(siblings).indexOf(elementBelow) + totalGridInArrow] as HTMLElement; + } + } + if (elementClassNameContains(elementBelow, /file/)) { + ensureElementInViewPort(elementBelow); + let start = false; + unselectAllSelected(); + if (e.shiftKey) { + for (const sibling of latestSelected.parentNode.children) { + if (start || sibling === elementBelow || sibling === latestSelected) { + if (!(hideHiddenFiles && (sibling as HTMLElement).dataset.isHidden === "true")) sibling.classList.add("selected"); + } + if (sibling === latestSelected) start = true; + if (sibling === elementBelow) break; + } + latestShiftSelected = elementBelow; + } else { + latestSelected.classList.remove("selected"); + latestSelected = elementBelow; + elementBelow.classList.add("selected"); + } + ChangeSelectedEvent(); + } }; const arrowUpHandler = (e: KeyboardEvent, hideHiddenFiles: boolean): void => { - if (latestShiftSelected && elementIndex(latestShiftSelected) > elementIndex(latestSelected)) latestShiftSelected = latestSelected; - - e.preventDefault(); - const totalGridInArrow = Math.floor( - (latestSelected.parentNode as HTMLElement).offsetWidth / - (latestSelected.offsetWidth + parseInt(getComputedStyle(latestSelected).marginLeft) * 2) - ); // Calculate the total of grids in arrow - const siblings = latestSelected.parentNode.children; - let elementAbove = siblings[Array.from(siblings).indexOf(e.shiftKey ? latestShiftSelected : latestSelected) - totalGridInArrow] as HTMLElement; - if (hideHiddenFiles) { - while (elementAbove && elementAbove.dataset.isHidden === 'true') { - elementAbove = siblings[Array.from(siblings).indexOf(elementAbove) - totalGridInArrow] as HTMLElement; - } - } - if (elementClassNameContains(elementAbove, /file/)) { - ensureElementInViewPort(elementAbove); - let start = false; - unselectAllSelected(); - if (e.shiftKey) { - for (const sibling of latestSelected.parentNode.children) { - if (start || sibling === elementAbove || sibling === latestSelected) { - if (!(hideHiddenFiles && (sibling as HTMLElement).dataset.isHidden === 'true')) sibling.classList.add('selected'); - } - if (sibling === elementAbove) start = true; - if (sibling === latestSelected) break; - } - latestShiftSelected = elementAbove; - } else { - latestSelected.classList.remove('selected'); - latestSelected = elementAbove; - elementAbove.classList.add('selected'); - } - ChangeSelectedEvent(); - } + if (latestShiftSelected && elementIndex(latestShiftSelected) > elementIndex(latestSelected)) latestShiftSelected = latestSelected; + + e.preventDefault(); + const totalGridInArrow = Math.floor( + (latestSelected.parentNode as HTMLElement).offsetWidth / + (latestSelected.offsetWidth + Number.parseInt(getComputedStyle(latestSelected).marginLeft) * 2), + ); // Calculate the total of grids in arrow + const siblings = latestSelected.parentNode.children; + let elementAbove = siblings[Array.from(siblings).indexOf(e.shiftKey ? latestShiftSelected : latestSelected) - totalGridInArrow] as HTMLElement; + if (hideHiddenFiles) { + while (elementAbove && elementAbove.dataset.isHidden === "true") { + elementAbove = siblings[Array.from(siblings).indexOf(elementAbove) - totalGridInArrow] as HTMLElement; + } + } + if (elementClassNameContains(elementAbove, /file/)) { + ensureElementInViewPort(elementAbove); + let start = false; + unselectAllSelected(); + if (e.shiftKey) { + for (const sibling of latestSelected.parentNode.children) { + if (start || sibling === elementAbove || sibling === latestSelected) { + if (!(hideHiddenFiles && (sibling as HTMLElement).dataset.isHidden === "true")) sibling.classList.add("selected"); + } + if (sibling === elementAbove) start = true; + if (sibling === latestSelected) break; + } + latestShiftSelected = elementAbove; + } else { + latestSelected.classList.remove("selected"); + latestSelected = elementAbove; + elementAbove.classList.add("selected"); + } + ChangeSelectedEvent(); + } }; export { Select, SelectInit, getSelected, ChangeSelectedEvent, unselectAllSelected }; diff --git a/src/Components/Files/File Operation/trash.ts b/src/Components/Files/File Operation/trash.ts index a747853b..a1739f4b 100644 --- a/src/Components/Files/File Operation/trash.ts +++ b/src/Components/Files/File Operation/trash.ts @@ -1,10 +1,10 @@ -import { OperationLog } from '../../Functions/log'; -import PromptError from '../../Prompt/error'; -import OS from '../../../Service/platform'; -import { DeleteFiles, PurgeFiles, RestoreFiles, RestoreFile as RestoreFileAPI } from '../../../Service/trash'; -import OperationAPI from '../../../Service/operation'; -import ConfirmDialog from '../../Prompt/confirm'; -import { reload } from '../../Layout/windowManager'; +import OperationAPI from "../../../Service/operation"; +import OS from "../../../Service/platform"; +import { DeleteFiles, PurgeFiles, RestoreFile as RestoreFileAPI, RestoreFiles } from "../../../Service/trash"; +import { OperationLog } from "../../Functions/log"; +import { reload } from "../../Layout/windowManager"; +import ConfirmDialog from "../../Prompt/confirm"; +import PromptError from "../../Prompt/error"; let platform: string; /** @@ -13,29 +13,29 @@ let platform: string; * @returns {Promise} */ const Restore = async (filePaths: string[]): Promise => { - if (!platform) platform = await OS(); - if (platform === 'darwin') return; + if (!platform) platform = await OS(); + if (platform === "darwin") return; - const result = await RestoreFiles(filePaths); - if (result.request_confirmation) { - const confirm = await ConfirmDialog('Something went wrong when trying to restore the file/dir', result.message, 'Yes'); - if (!confirm) return; - RestoreFiles(filePaths, true); - } - reload(); + const result = await RestoreFiles(filePaths); + if (result.request_confirmation) { + const confirm = await ConfirmDialog("Something went wrong when trying to restore the file/dir", result.message, "Yes"); + if (!confirm) return; + RestoreFiles(filePaths, true); + } + reload(); }; const Purge = async (filePaths: string[]): Promise => { - if (!platform) platform = await OS(); - if (platform === 'darwin') return; - const confirm = await ConfirmDialog( - 'Permanently delete file', - "Are you sure to permanently delete these files/dirs? This can't be undone.", - 'Yes' - ); - if (!confirm) return; - PurgeFiles(filePaths); - reload(); + if (!platform) platform = await OS(); + if (platform === "darwin") return; + const confirm = await ConfirmDialog( + "Permanently delete file", + "Are you sure to permanently delete these files/dirs? This can't be undone.", + "Yes", + ); + if (!confirm) return; + PurgeFiles(filePaths); + reload(); }; /** @@ -44,15 +44,15 @@ const Purge = async (filePaths: string[]): Promise => { * @returns {Promise} */ const Trash = async (filePaths: string[]): Promise => { - if (!platform) platform = await OS(); - try { - DeleteFiles(filePaths); - } catch (err) { - PromptError('Failed to delete files/dirs', `Failed to move ` + filePaths.join(', ') + ` to trash. [${err}]`); - } - if (platform !== 'darwin') { - OperationLog('delete', filePaths); - } + if (!platform) platform = await OS(); + try { + DeleteFiles(filePaths); + } catch (err) { + PromptError("Failed to delete files/dirs", `Failed to move ` + filePaths.join(", ") + ` to trash. [${err}]`); + } + if (platform !== "darwin") { + OperationLog("delete", filePaths); + } }; /** @@ -62,9 +62,9 @@ const Trash = async (filePaths: string[]): Promise => { * @returns {Promise} */ const RestoreFile = async (original_parent: string, basename: string): Promise => { - if (!platform) platform = await OS(); - if (platform === 'darwin') return; - await RestoreFileAPI(original_parent, basename); + if (!platform) platform = await OS(); + if (platform === "darwin") return; + await RestoreFileAPI(original_parent, basename); }; /** @@ -73,17 +73,17 @@ const RestoreFile = async (original_parent: string, basename: string): Promise => { - const confirm = await ConfirmDialog( - 'Permanently delete file', - filePaths.length > 1 - ? "Are you sure to permanently delete these files/dirs? This can't be undone." - : "Are you sure to permanently delete this file/dir? This can't be undone.", - 'Yes' - ); - if (!confirm) return; - for (const filePath of filePaths) { - await new OperationAPI(filePath).unlink(); - } + const confirm = await ConfirmDialog( + "Permanently delete file", + filePaths.length > 1 + ? "Are you sure to permanently delete these files/dirs? This can't be undone." + : "Are you sure to permanently delete this file/dir? This can't be undone.", + "Yes", + ); + if (!confirm) return; + for (const filePath of filePaths) { + await new OperationAPI(filePath).unlink(); + } }; export { Trash, PermanentDelete, Restore, Purge, RestoreFile }; diff --git a/src/Components/Files/File Operation/undo.ts b/src/Components/Files/File Operation/undo.ts index 6d1ee1f3..e396df28 100644 --- a/src/Components/Files/File Operation/undo.ts +++ b/src/Components/Files/File Operation/undo.ts @@ -1,70 +1,70 @@ -import windowName from '../../../Service/window'; -import OperationAPI from '../../../Service/operation'; -import Storage from '../../../Service/storage'; -import joinPath from '../../Functions/path/joinPath'; -import getBasename from '../../Functions/path/basename'; -import FileAPI from '../../../Service/files'; -import ConfirmDialog from '../../Prompt/confirm'; -import DirectoryAPI from '../../../Service/directory'; -import { RestoreFile } from './trash'; -import getDirname from '../../Functions/path/dirname'; -import NormalizeSlash from '../../Functions/path/normalizeSlash'; +import DirectoryAPI from "../../../Service/directory"; +import FileAPI from "../../../Service/files"; +import OperationAPI from "../../../Service/operation"; +import Storage from "../../../Service/storage"; +import windowName from "../../../Service/window"; +import getBasename from "../../Functions/path/basename"; +import getDirname from "../../Functions/path/dirname"; +import joinPath from "../../Functions/path/joinPath"; +import NormalizeSlash from "../../Functions/path/normalizeSlash"; +import ConfirmDialog from "../../Prompt/confirm"; +import { RestoreFile } from "./trash"; /** * Undo the latest operation * @returns {Promise} */ const Undo = async (): Promise => { - const operationLogs = await Storage.get(`operations-${windowName}`); - const latestOperation = operationLogs?.operations[operationLogs?.currentIndex]; - switch (latestOperation?.operationType) { - case 'copy': - for (const source of latestOperation.sources) { - const filename = joinPath(latestOperation.destination, getBasename(source)); - const filenameWithCopySuffix = `${filename - .split('.') - .splice(0, filename.split('.').length - 1) - .join('.')} - Copy.${filename.split('.').splice(filename.split('.').length - 1)}`; - const copiedFile = (await new FileAPI(filenameWithCopySuffix).exists()) ? filenameWithCopySuffix : filename; - new OperationAPI(copiedFile).unlink(); - } - break; - case 'cut': - for (const source of latestOperation.sources) { - const dest = joinPath(latestOperation.destination, getBasename(source)); - if (await new DirectoryAPI(source).exists()) { - if ( - !(await ConfirmDialog( - 'Target file exists', - 'Target directory with the same file/dir name exists, do you want to overwrite it?', - 'No' - )) - ) - return; - else { - await new OperationAPI(source).unlink(); - } - } - await new OperationAPI(dest, source).rename(); - break; - } - break; - case 'newfile': - new OperationAPI(latestOperation.destination).unlink(); - break; - case 'newfolder': - new OperationAPI(latestOperation.destination).unlink(); - break; - case 'delete': - for (const source of latestOperation.sources) { - RestoreFile(NormalizeSlash(getDirname(source)), NormalizeSlash(getBasename(source))); - } - break; - case 'rename': - await new OperationAPI(latestOperation.destination, latestOperation.sources).rename(); - break; - } - if (operationLogs.currentIndex > -1) operationLogs.currentIndex -= 1; - Storage.set(`operations-${windowName}`, operationLogs); + const operationLogs = await Storage.get(`operations-${windowName}`); + const latestOperation = operationLogs?.operations[operationLogs?.currentIndex]; + switch (latestOperation?.operationType) { + case "copy": + for (const source of latestOperation.sources) { + const filename = joinPath(latestOperation.destination, getBasename(source)); + const filenameWithCopySuffix = `${filename + .split(".") + .splice(0, filename.split(".").length - 1) + .join(".")} - Copy.${filename.split(".").splice(filename.split(".").length - 1)}`; + const copiedFile = (await new FileAPI(filenameWithCopySuffix).exists()) ? filenameWithCopySuffix : filename; + new OperationAPI(copiedFile).unlink(); + } + break; + case "cut": + for (const source of latestOperation.sources) { + const dest = joinPath(latestOperation.destination, getBasename(source)); + if (await new DirectoryAPI(source).exists()) { + if ( + !(await ConfirmDialog( + "Target file exists", + "Target directory with the same file/dir name exists, do you want to overwrite it?", + "No", + )) + ) + return; + else { + await new OperationAPI(source).unlink(); + } + } + await new OperationAPI(dest, source).rename(); + break; + } + break; + case "newfile": + new OperationAPI(latestOperation.destination).unlink(); + break; + case "newfolder": + new OperationAPI(latestOperation.destination).unlink(); + break; + case "delete": + for (const source of latestOperation.sources) { + RestoreFile(NormalizeSlash(getDirname(source)), NormalizeSlash(getBasename(source))); + } + break; + case "rename": + await new OperationAPI(latestOperation.destination, latestOperation.sources).rename(); + break; + } + if (operationLogs.currentIndex > -1) operationLogs.currentIndex -= 1; + Storage.set(`operations-${windowName}`, operationLogs); }; export default Undo; diff --git a/src/Components/Files/File Preview/preview.ts b/src/Components/Files/File Preview/preview.ts index 54a3bc82..97042387 100644 --- a/src/Components/Files/File Preview/preview.ts +++ b/src/Components/Files/File Preview/preview.ts @@ -1,33 +1,33 @@ -import PromptError from '../../Prompt/error'; -import { HTML_TYPES, IMAGE_TYPES, VIDEO_TYPES, PLAINTEXT_TYPES, MARKDOWN_TYPES } from '../../../Config/file.config'; -import getBasename from '../../Functions/path/basename'; -import xlsx from 'xlsx'; -import FileAPI from '../../../Service/files'; -import { eURLify, URLify } from '../../Functions/urlify'; -import hljs from 'highlight.js'; -import ConfirmDialog from '../../Prompt/confirm'; -import { marked } from 'marked'; -import getDirname from '../../Functions/path/dirname'; -import isTauri from '../../../Util/is-tauri'; -import { GET_WORKSPACE_ELEMENT } from '../../../Util/constants'; +import hljs from "highlight.js"; +import { marked } from "marked"; +import xlsx from "xlsx"; +import { HTML_TYPES, IMAGE_TYPES, MARKDOWN_TYPES, PLAINTEXT_TYPES, VIDEO_TYPES } from "../../../Config/file.config"; +import FileAPI from "../../../Service/files"; +import { GET_WORKSPACE_ELEMENT } from "../../../Util/constants"; +import isTauri from "../../../Util/is-tauri"; +import getBasename from "../../Functions/path/basename"; +import getDirname from "../../Functions/path/dirname"; +import { URLify, eURLify } from "../../Functions/urlify"; +import ConfirmDialog from "../../Prompt/confirm"; +import PromptError from "../../Prompt/error"; const isValidURL = (text: string) => { - let url; - try { - url = new URL(text); - } catch (_) { - return false; - } - return (url.protocol === 'http:' || url.protocol === 'https:') && url.hostname !== window.location.hostname; + let url; + try { + url = new URL(text); + } catch (_) { + return false; + } + return (url.protocol === "http:" || url.protocol === "https:") && url.hostname !== window.location.hostname; }; /** * Close the preview file * @returns {void} */ const closePreviewFile = (): void => { - GET_WORKSPACE_ELEMENT(1).classList.remove('workspace-split'); - document.querySelectorAll('.preview').forEach((element) => element.parentNode.removeChild(element)); - document.querySelector('.main-box').style.overflowY = 'auto'; + GET_WORKSPACE_ELEMENT(1).classList.remove("workspace-split"); + document.querySelectorAll(".preview").forEach((element) => element.parentNode.removeChild(element)); + document.querySelector(".main-box").style.overflowY = "auto"; }; /** * Show preview file @@ -35,18 +35,18 @@ const closePreviewFile = (): void => { * @returns {void} */ const Preview = async (filePath: string): Promise => { - if (!isTauri) { - PromptError('Preview unavailable', 'Preview is currently unavailable on Web version'); - return; - } - closePreviewFile(); + if (!isTauri) { + PromptError("Preview unavailable", "Preview is currently unavailable on Web version"); + return; + } + closePreviewFile(); - const previewElement = document.createElement('div'); - previewElement.classList.add('preview'); + const previewElement = document.createElement("div"); + previewElement.classList.add("preview"); - const changePreview = (html: string) => { - if (!html) return; - previewElement.innerHTML = ` + const changePreview = (html: string) => { + if (!html) return; + previewElement.innerHTML = `
${getBasename(filePath)} × @@ -54,103 +54,105 @@ const Preview = async (filePath: string): Promise => { ${html} `; - document.querySelector('.main-box').scrollTop = 0; - document.querySelector('.main-box').style.overflowY = 'hidden'; - GET_WORKSPACE_ELEMENT(1).classList.toggle('workspace-split'); - GET_WORKSPACE_ELEMENT(1).appendChild(previewElement); - previewElement.querySelector('.preview-exit-btn').addEventListener('click', () => closePreviewFile()); - return; - }; + document.querySelector(".main-box").scrollTop = 0; + document.querySelector(".main-box").style.overflowY = "hidden"; + GET_WORKSPACE_ELEMENT(1).classList.toggle("workspace-split"); + GET_WORKSPACE_ELEMENT(1).appendChild(previewElement); + previewElement.querySelector(".preview-exit-btn").addEventListener("click", () => closePreviewFile()); + return; + }; - const ext = filePath.split('.').pop().toLowerCase(); + const ext = filePath.split(".").pop().toLowerCase(); - let previewed = true; - if (ext === 'pdf') { - changePreview( - `` - ); - } else if (HTML_TYPES.indexOf(ext) !== -1) { - changePreview(``); - } else if (['doc', 'docb', 'docm', 'dot', 'dotm', 'docx', 'rtf'].indexOf(ext) !== -1) { - const { convertToHtml } = require('./mammoth.browser.min'); - const buf = await new FileAPI(filePath).readBuffer(); - const { value } = await convertToHtml({ arrayBuffer: buf }); - changePreview(`
${eURLify(value)}
`); - } else if (['xlsx', 'xls', 'xlsb', 'xls', 'ods', 'fods', 'csv'].indexOf(ext) !== -1) { - const xlsxData = xlsx.read(await new FileAPI(filePath).readBuffer(), { type: 'buffer' }); - const parsedData = xlsx.utils.sheet_to_html(xlsxData.Sheets[xlsxData.SheetNames[0]]); - changePreview(`
${URLify(parsedData)}
`); - } else if (IMAGE_TYPES.indexOf(ext) !== -1) { - changePreview(`
`); - } else if (VIDEO_TYPES.indexOf(ext) !== -1) { - changePreview( - `
` - ); - // } else if (AUDIO_TYPES.indexOf(ext) !== -1) { - // changePreview( - // ` - //
- // - //
` - // ); - } else if (PLAINTEXT_TYPES.indexOf(ext) !== -1) { - changePreview(`
${await new FileAPI(filePath).readFile()}
`); - } else if (MARKDOWN_TYPES.indexOf(ext) !== -1) { - const html = marked(await new FileAPI(filePath).readFile()); - changePreview(`
${eURLify(html)}
`); - previewElement.querySelectorAll('img').forEach(async (img) => { - if (!isValidURL(img.src)) { - let imgData = new FileAPI(img.src); - if (!(await imgData.exists())) { - let imgPath = new URL(img.src).pathname; - if (imgPath.charAt(0) === '/') imgPath = imgPath.substr(1); - imgData = new FileAPI(`${getDirname(filePath)}${imgPath}`); - if (await imgData.exists()) { - img.src = imgData.readAsset(); - } - } else { - img.src = await imgData.readFile(); - } - } - }); - } else { - try { - const fileData = new FileAPI(filePath); - const property = await fileData.properties(); - let highlight = true; - if (property.size > 1024 * 100) { - const confirm = await ConfirmDialog( - 'File too large', - 'File size is larger than 100kb, proceeding previewing file might crashes Xplorer, do you want to proceed?', - 'Yes' - ); - if (!confirm) return; - } - if (property.size > 1024 * 10) { - highlight = false; - } - const fileText = await fileData.readFile(); - const highlightedCode = hljs.highlightAuto(fileText).value; + let previewed = true; + if (ext === "pdf") { + changePreview( + ``, + ); + } else if (HTML_TYPES.indexOf(ext) !== -1) { + changePreview(``); + } else if (["doc", "docb", "docm", "dot", "dotm", "docx", "rtf"].indexOf(ext) !== -1) { + const { convertToHtml } = require("./mammoth.browser.min"); + const buf = await new FileAPI(filePath).readBuffer(); + const { value } = await convertToHtml({ arrayBuffer: buf }); + changePreview(`
${eURLify(value)}
`); + } else if (["xlsx", "xls", "xlsb", "xls", "ods", "fods", "csv"].indexOf(ext) !== -1) { + const xlsxData = xlsx.read(await new FileAPI(filePath).readBuffer(), { + type: "buffer", + }); + const parsedData = xlsx.utils.sheet_to_html(xlsxData.Sheets[xlsxData.SheetNames[0]]); + changePreview(`
${URLify(parsedData)}
`); + } else if (IMAGE_TYPES.indexOf(ext) !== -1) { + changePreview(`
`); + } else if (VIDEO_TYPES.indexOf(ext) !== -1) { + changePreview( + `
`, + ); + // } else if (AUDIO_TYPES.indexOf(ext) !== -1) { + // changePreview( + // ` + //
+ // + //
` + // ); + } else if (PLAINTEXT_TYPES.indexOf(ext) !== -1) { + changePreview(`
${await new FileAPI(filePath).readFile()}
`); + } else if (MARKDOWN_TYPES.indexOf(ext) !== -1) { + const html = marked(await new FileAPI(filePath).readFile()); + changePreview(`
${eURLify(html)}
`); + previewElement.querySelectorAll("img").forEach(async (img) => { + if (!isValidURL(img.src)) { + let imgData = new FileAPI(img.src); + if (!(await imgData.exists())) { + let imgPath = new URL(img.src).pathname; + if (imgPath.charAt(0) === "/") imgPath = imgPath.substr(1); + imgData = new FileAPI(`${getDirname(filePath)}${imgPath}`); + if (await imgData.exists()) { + img.src = imgData.readAsset(); + } + } else { + img.src = await imgData.readFile(); + } + } + }); + } else { + try { + const fileData = new FileAPI(filePath); + const property = await fileData.properties(); + let highlight = true; + if (property.size > 1024 * 100) { + const confirm = await ConfirmDialog( + "File too large", + "File size is larger than 100kb, proceeding previewing file might crashes Xplorer, do you want to proceed?", + "Yes", + ); + if (!confirm) return; + } + if (property.size > 1024 * 10) { + highlight = false; + } + const fileText = await fileData.readFile(); + const highlightedCode = hljs.highlightAuto(fileText).value; - changePreview( - highlight - ? `
${highlightedCode}
` - : `
${fileText}
` - ); - } catch (_) { - previewed = false; - } - } + changePreview( + highlight + ? `
${highlightedCode}
` + : `
${fileText}
`, + ); + } catch (_) { + previewed = false; + } + } - if (!previewed) PromptError('No preview handler', 'There is no preview handler for this file type yet.'); + if (!previewed) PromptError("No preview handler", "There is no preview handler for this file type yet."); }; export default Preview; export { closePreviewFile }; diff --git a/src/Components/Folder/new.ts b/src/Components/Folder/new.ts index 99ed1267..8ff5a162 100644 --- a/src/Components/Folder/new.ts +++ b/src/Components/Folder/new.ts @@ -1,7 +1,7 @@ -import { OperationLog } from '../Functions/log'; -import focusingPath from '../Functions/focusingPath'; -import FolderAPI from '../../Service/directory'; -import PromptError from '../Prompt/error'; +import FolderAPI from "../../Service/directory"; +import focusingPath from "../Functions/focusingPath"; +import { OperationLog } from "../Functions/log"; +import PromptError from "../Prompt/error"; /** * Create a folder * @param {string} folderName - name for the new folder @@ -10,20 +10,20 @@ import PromptError from '../Prompt/error'; * @returns {void} */ const NewFolder = async (folderName: string, parentDir?: string, writeLog = true): Promise => { - if (!parentDir) parentDir = await focusingPath(); + if (!parentDir) parentDir = await focusingPath(); - const newFolder = new FolderAPI(folderName, parentDir); + const newFolder = new FolderAPI(folderName, parentDir); - if (await newFolder.exists()) { - PromptError('Error creating folder', `Failed to create folder ${newFolder.dirName}: Folder already existed`); - } else { - try { - await newFolder.mkdir(); - if (writeLog) OperationLog('newfolder', null, newFolder.dirName); - } catch (err) { - PromptError('Error creating file', `Failed to create file ${newFolder.dirName}: Something went wrong (${err})`); - } - } + if (await newFolder.exists()) { + PromptError("Error creating folder", `Failed to create folder ${newFolder.dirName}: Folder already existed`); + } else { + try { + await newFolder.mkdir(); + if (writeLog) OperationLog("newfolder", null, newFolder.dirName); + } catch (err) { + PromptError("Error creating file", `Failed to create file ${newFolder.dirName}: Something went wrong (${err})`); + } + } }; export default NewFolder; diff --git a/src/Components/Functions/Loading/loading.ts b/src/Components/Functions/Loading/loading.ts index 2eb584ff..bfec9074 100644 --- a/src/Components/Functions/Loading/loading.ts +++ b/src/Components/Functions/Loading/loading.ts @@ -3,16 +3,16 @@ * @returns {void} */ const startLoading = (): void => { - const LOADING_BAR = document.querySelector('.loading-bar'); - LOADING_BAR.dataset.loading = 'true'; + const LOADING_BAR = document.querySelector(".loading-bar"); + LOADING_BAR.dataset.loading = "true"; }; /** * Check if the loading animation is running * @returns {any} */ const isLoading = (): boolean => { - const LOADING_BAR = document.querySelector('.loading-bar'); - return LOADING_BAR.dataset.loading === 'true'; + const LOADING_BAR = document.querySelector(".loading-bar"); + return LOADING_BAR.dataset.loading === "true"; }; /** @@ -20,8 +20,8 @@ const isLoading = (): boolean => { * @returns {void} */ const stopLoading = (): void => { - const LOADING_BAR = document.querySelector('.loading-bar'); - LOADING_BAR.dataset.loading = 'false'; + const LOADING_BAR = document.querySelector(".loading-bar"); + LOADING_BAR.dataset.loading = "false"; }; export { startLoading, stopLoading, isLoading }; diff --git a/src/Components/Functions/beep.ts b/src/Components/Functions/beep.ts index c73c99c5..cc8b63dd 100644 --- a/src/Components/Functions/beep.ts +++ b/src/Components/Functions/beep.ts @@ -1,7 +1,7 @@ function beep(): void { - const snd = new Audio( - 'data:audio/wav;base64,//uQRAAAAWMSLwUIYAAsYkXgoQwAEaYLWfkWgAI0wWs/ItAAAGDgYtAgAyN+QWaAAihwMWm4G8QQRDiMcCBcH3Cc+CDv/7xA4Tvh9Rz/y8QADBwMWgQAZG/ILNAARQ4GLTcDeIIIhxGOBAuD7hOfBB3/94gcJ3w+o5/5eIAIAAAVwWgQAVQ2ORaIQwEMAJiDg95G4nQL7mQVWI6GwRcfsZAcsKkJvxgxEjzFUgfHoSQ9Qq7KNwqHwuB13MA4a1q/DmBrHgPcmjiGoh//EwC5nGPEmS4RcfkVKOhJf+WOgoxJclFz3kgn//dBA+ya1GhurNn8zb//9NNutNuhz31f////9vt///z+IdAEAAAK4LQIAKobHItEIYCGAExBwe8jcToF9zIKrEdDYIuP2MgOWFSE34wYiR5iqQPj0JIeoVdlG4VD4XA67mAcNa1fhzA1jwHuTRxDUQ//iYBczjHiTJcIuPyKlHQkv/LHQUYkuSi57yQT//uggfZNajQ3Vmz+Zt//+mm3Wm3Q576v////+32///5/EOgAAADVghQAAAAA//uQZAUAB1WI0PZugAAAAAoQwAAAEk3nRd2qAAAAACiDgAAAAAAABCqEEQRLCgwpBGMlJkIz8jKhGvj4k6jzRnqasNKIeoh5gI7BJaC1A1AoNBjJgbyApVS4IDlZgDU5WUAxEKDNmmALHzZp0Fkz1FMTmGFl1FMEyodIavcCAUHDWrKAIA4aa2oCgILEBupZgHvAhEBcZ6joQBxS76AgccrFlczBvKLC0QI2cBoCFvfTDAo7eoOQInqDPBtvrDEZBNYN5xwNwxQRfw8ZQ5wQVLvO8OYU+mHvFLlDh05Mdg7BT6YrRPpCBznMB2r//xKJjyyOh+cImr2/4doscwD6neZjuZR4AgAABYAAAABy1xcdQtxYBYYZdifkUDgzzXaXn98Z0oi9ILU5mBjFANmRwlVJ3/6jYDAmxaiDG3/6xjQQCCKkRb/6kg/wW+kSJ5//rLobkLSiKmqP/0ikJuDaSaSf/6JiLYLEYnW/+kXg1WRVJL/9EmQ1YZIsv/6Qzwy5qk7/+tEU0nkls3/zIUMPKNX/6yZLf+kFgAfgGyLFAUwY//uQZAUABcd5UiNPVXAAAApAAAAAE0VZQKw9ISAAACgAAAAAVQIygIElVrFkBS+Jhi+EAuu+lKAkYUEIsmEAEoMeDmCETMvfSHTGkF5RWH7kz/ESHWPAq/kcCRhqBtMdokPdM7vil7RG98A2sc7zO6ZvTdM7pmOUAZTnJW+NXxqmd41dqJ6mLTXxrPpnV8avaIf5SvL7pndPvPpndJR9Kuu8fePvuiuhorgWjp7Mf/PRjxcFCPDkW31srioCExivv9lcwKEaHsf/7ow2Fl1T/9RkXgEhYElAoCLFtMArxwivDJJ+bR1HTKJdlEoTELCIqgEwVGSQ+hIm0NbK8WXcTEI0UPoa2NbG4y2K00JEWbZavJXkYaqo9CRHS55FcZTjKEk3NKoCYUnSQ0rWxrZbFKbKIhOKPZe1cJKzZSaQrIyULHDZmV5K4xySsDRKWOruanGtjLJXFEmwaIbDLX0hIPBUQPVFVkQkDoUNfSoDgQGKPekoxeGzA4DUvnn4bxzcZrtJyipKfPNy5w+9lnXwgqsiyHNeSVpemw4bWb9psYeq//uQZBoABQt4yMVxYAIAAAkQoAAAHvYpL5m6AAgAACXDAAAAD59jblTirQe9upFsmZbpMudy7Lz1X1DYsxOOSWpfPqNX2WqktK0DMvuGwlbNj44TleLPQ+Gsfb+GOWOKJoIrWb3cIMeeON6lz2umTqMXV8Mj30yWPpjoSa9ujK8SyeJP5y5mOW1D6hvLepeveEAEDo0mgCRClOEgANv3B9a6fikgUSu/DmAMATrGx7nng5p5iimPNZsfQLYB2sDLIkzRKZOHGAaUyDcpFBSLG9MCQALgAIgQs2YunOszLSAyQYPVC2YdGGeHD2dTdJk1pAHGAWDjnkcLKFymS3RQZTInzySoBwMG0QueC3gMsCEYxUqlrcxK6k1LQQcsmyYeQPdC2YfuGPASCBkcVMQQqpVJshui1tkXQJQV0OXGAZMXSOEEBRirXbVRQW7ugq7IM7rPWSZyDlM3IuNEkxzCOJ0ny2ThNkyRai1b6ev//3dzNGzNb//4uAvHT5sURcZCFcuKLhOFs8mLAAEAt4UWAAIABAAAAAB4qbHo0tIjVkUU//uQZAwABfSFz3ZqQAAAAAngwAAAE1HjMp2qAAAAACZDgAAAD5UkTE1UgZEUExqYynN1qZvqIOREEFmBcJQkwdxiFtw0qEOkGYfRDifBui9MQg4QAHAqWtAWHoCxu1Yf4VfWLPIM2mHDFsbQEVGwyqQoQcwnfHeIkNt9YnkiaS1oizycqJrx4KOQjahZxWbcZgztj2c49nKmkId44S71j0c8eV9yDK6uPRzx5X18eDvjvQ6yKo9ZSS6l//8elePK/Lf//IInrOF/FvDoADYAGBMGb7FtErm5MXMlmPAJQVgWta7Zx2go+8xJ0UiCb8LHHdftWyLJE0QIAIsI+UbXu67dZMjmgDGCGl1H+vpF4NSDckSIkk7Vd+sxEhBQMRU8j/12UIRhzSaUdQ+rQU5kGeFxm+hb1oh6pWWmv3uvmReDl0UnvtapVaIzo1jZbf/pD6ElLqSX+rUmOQNpJFa/r+sa4e/pBlAABoAAAAA3CUgShLdGIxsY7AUABPRrgCABdDuQ5GC7DqPQCgbbJUAoRSUj+NIEig0YfyWUho1VBBBA//uQZB4ABZx5zfMakeAAAAmwAAAAF5F3P0w9GtAAACfAAAAAwLhMDmAYWMgVEG1U0FIGCBgXBXAtfMH10000EEEEEECUBYln03TTTdNBDZopopYvrTTdNa325mImNg3TTPV9q3pmY0xoO6bv3r00y+IDGid/9aaaZTGMuj9mpu9Mpio1dXrr5HERTZSmqU36A3CumzN/9Robv/Xx4v9ijkSRSNLQhAWumap82WRSBUqXStV/YcS+XVLnSS+WLDroqArFkMEsAS+eWmrUzrO0oEmE40RlMZ5+ODIkAyKAGUwZ3mVKmcamcJnMW26MRPgUw6j+LkhyHGVGYjSUUKNpuJUQoOIAyDvEyG8S5yfK6dhZc0Tx1KI/gviKL6qvvFs1+bWtaz58uUNnryq6kt5RzOCkPWlVqVX2a/EEBUdU1KrXLf40GoiiFXK///qpoiDXrOgqDR38JB0bw7SoL+ZB9o1RCkQjQ2CBYZKd/+VJxZRRZlqSkKiws0WFxUyCwsKiMy7hUVFhIaCrNQsKkTIsLivwKKigsj8XYlwt/WKi2N4d//uQRCSAAjURNIHpMZBGYiaQPSYyAAABLAAAAAAAACWAAAAApUF/Mg+0aohSIRobBAsMlO//Kk4soosy1JSFRYWaLC4qZBYWFRGZdwqKiwkNBVmoWFSJkWFxX4FFRQWR+LsS4W/rFRb/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////VEFHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAU291bmRib3kuZGUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMjAwNGh0dHA6Ly93d3cuc291bmRib3kuZGUAAAAAAAAAACU=' - ); - snd.play(); + const snd = new Audio( + "data:audio/wav;base64,//uQRAAAAWMSLwUIYAAsYkXgoQwAEaYLWfkWgAI0wWs/ItAAAGDgYtAgAyN+QWaAAihwMWm4G8QQRDiMcCBcH3Cc+CDv/7xA4Tvh9Rz/y8QADBwMWgQAZG/ILNAARQ4GLTcDeIIIhxGOBAuD7hOfBB3/94gcJ3w+o5/5eIAIAAAVwWgQAVQ2ORaIQwEMAJiDg95G4nQL7mQVWI6GwRcfsZAcsKkJvxgxEjzFUgfHoSQ9Qq7KNwqHwuB13MA4a1q/DmBrHgPcmjiGoh//EwC5nGPEmS4RcfkVKOhJf+WOgoxJclFz3kgn//dBA+ya1GhurNn8zb//9NNutNuhz31f////9vt///z+IdAEAAAK4LQIAKobHItEIYCGAExBwe8jcToF9zIKrEdDYIuP2MgOWFSE34wYiR5iqQPj0JIeoVdlG4VD4XA67mAcNa1fhzA1jwHuTRxDUQ//iYBczjHiTJcIuPyKlHQkv/LHQUYkuSi57yQT//uggfZNajQ3Vmz+Zt//+mm3Wm3Q576v////+32///5/EOgAAADVghQAAAAA//uQZAUAB1WI0PZugAAAAAoQwAAAEk3nRd2qAAAAACiDgAAAAAAABCqEEQRLCgwpBGMlJkIz8jKhGvj4k6jzRnqasNKIeoh5gI7BJaC1A1AoNBjJgbyApVS4IDlZgDU5WUAxEKDNmmALHzZp0Fkz1FMTmGFl1FMEyodIavcCAUHDWrKAIA4aa2oCgILEBupZgHvAhEBcZ6joQBxS76AgccrFlczBvKLC0QI2cBoCFvfTDAo7eoOQInqDPBtvrDEZBNYN5xwNwxQRfw8ZQ5wQVLvO8OYU+mHvFLlDh05Mdg7BT6YrRPpCBznMB2r//xKJjyyOh+cImr2/4doscwD6neZjuZR4AgAABYAAAABy1xcdQtxYBYYZdifkUDgzzXaXn98Z0oi9ILU5mBjFANmRwlVJ3/6jYDAmxaiDG3/6xjQQCCKkRb/6kg/wW+kSJ5//rLobkLSiKmqP/0ikJuDaSaSf/6JiLYLEYnW/+kXg1WRVJL/9EmQ1YZIsv/6Qzwy5qk7/+tEU0nkls3/zIUMPKNX/6yZLf+kFgAfgGyLFAUwY//uQZAUABcd5UiNPVXAAAApAAAAAE0VZQKw9ISAAACgAAAAAVQIygIElVrFkBS+Jhi+EAuu+lKAkYUEIsmEAEoMeDmCETMvfSHTGkF5RWH7kz/ESHWPAq/kcCRhqBtMdokPdM7vil7RG98A2sc7zO6ZvTdM7pmOUAZTnJW+NXxqmd41dqJ6mLTXxrPpnV8avaIf5SvL7pndPvPpndJR9Kuu8fePvuiuhorgWjp7Mf/PRjxcFCPDkW31srioCExivv9lcwKEaHsf/7ow2Fl1T/9RkXgEhYElAoCLFtMArxwivDJJ+bR1HTKJdlEoTELCIqgEwVGSQ+hIm0NbK8WXcTEI0UPoa2NbG4y2K00JEWbZavJXkYaqo9CRHS55FcZTjKEk3NKoCYUnSQ0rWxrZbFKbKIhOKPZe1cJKzZSaQrIyULHDZmV5K4xySsDRKWOruanGtjLJXFEmwaIbDLX0hIPBUQPVFVkQkDoUNfSoDgQGKPekoxeGzA4DUvnn4bxzcZrtJyipKfPNy5w+9lnXwgqsiyHNeSVpemw4bWb9psYeq//uQZBoABQt4yMVxYAIAAAkQoAAAHvYpL5m6AAgAACXDAAAAD59jblTirQe9upFsmZbpMudy7Lz1X1DYsxOOSWpfPqNX2WqktK0DMvuGwlbNj44TleLPQ+Gsfb+GOWOKJoIrWb3cIMeeON6lz2umTqMXV8Mj30yWPpjoSa9ujK8SyeJP5y5mOW1D6hvLepeveEAEDo0mgCRClOEgANv3B9a6fikgUSu/DmAMATrGx7nng5p5iimPNZsfQLYB2sDLIkzRKZOHGAaUyDcpFBSLG9MCQALgAIgQs2YunOszLSAyQYPVC2YdGGeHD2dTdJk1pAHGAWDjnkcLKFymS3RQZTInzySoBwMG0QueC3gMsCEYxUqlrcxK6k1LQQcsmyYeQPdC2YfuGPASCBkcVMQQqpVJshui1tkXQJQV0OXGAZMXSOEEBRirXbVRQW7ugq7IM7rPWSZyDlM3IuNEkxzCOJ0ny2ThNkyRai1b6ev//3dzNGzNb//4uAvHT5sURcZCFcuKLhOFs8mLAAEAt4UWAAIABAAAAAB4qbHo0tIjVkUU//uQZAwABfSFz3ZqQAAAAAngwAAAE1HjMp2qAAAAACZDgAAAD5UkTE1UgZEUExqYynN1qZvqIOREEFmBcJQkwdxiFtw0qEOkGYfRDifBui9MQg4QAHAqWtAWHoCxu1Yf4VfWLPIM2mHDFsbQEVGwyqQoQcwnfHeIkNt9YnkiaS1oizycqJrx4KOQjahZxWbcZgztj2c49nKmkId44S71j0c8eV9yDK6uPRzx5X18eDvjvQ6yKo9ZSS6l//8elePK/Lf//IInrOF/FvDoADYAGBMGb7FtErm5MXMlmPAJQVgWta7Zx2go+8xJ0UiCb8LHHdftWyLJE0QIAIsI+UbXu67dZMjmgDGCGl1H+vpF4NSDckSIkk7Vd+sxEhBQMRU8j/12UIRhzSaUdQ+rQU5kGeFxm+hb1oh6pWWmv3uvmReDl0UnvtapVaIzo1jZbf/pD6ElLqSX+rUmOQNpJFa/r+sa4e/pBlAABoAAAAA3CUgShLdGIxsY7AUABPRrgCABdDuQ5GC7DqPQCgbbJUAoRSUj+NIEig0YfyWUho1VBBBA//uQZB4ABZx5zfMakeAAAAmwAAAAF5F3P0w9GtAAACfAAAAAwLhMDmAYWMgVEG1U0FIGCBgXBXAtfMH10000EEEEEECUBYln03TTTdNBDZopopYvrTTdNa325mImNg3TTPV9q3pmY0xoO6bv3r00y+IDGid/9aaaZTGMuj9mpu9Mpio1dXrr5HERTZSmqU36A3CumzN/9Robv/Xx4v9ijkSRSNLQhAWumap82WRSBUqXStV/YcS+XVLnSS+WLDroqArFkMEsAS+eWmrUzrO0oEmE40RlMZ5+ODIkAyKAGUwZ3mVKmcamcJnMW26MRPgUw6j+LkhyHGVGYjSUUKNpuJUQoOIAyDvEyG8S5yfK6dhZc0Tx1KI/gviKL6qvvFs1+bWtaz58uUNnryq6kt5RzOCkPWlVqVX2a/EEBUdU1KrXLf40GoiiFXK///qpoiDXrOgqDR38JB0bw7SoL+ZB9o1RCkQjQ2CBYZKd/+VJxZRRZlqSkKiws0WFxUyCwsKiMy7hUVFhIaCrNQsKkTIsLivwKKigsj8XYlwt/WKi2N4d//uQRCSAAjURNIHpMZBGYiaQPSYyAAABLAAAAAAAACWAAAAApUF/Mg+0aohSIRobBAsMlO//Kk4soosy1JSFRYWaLC4qZBYWFRGZdwqKiwkNBVmoWFSJkWFxX4FFRQWR+LsS4W/rFRb/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////VEFHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAU291bmRib3kuZGUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMjAwNGh0dHA6Ly93d3cuc291bmRib3kuZGUAAAAAAAAAACU=", + ); + snd.play(); } export default beep; diff --git a/src/Components/Functions/changePosition.ts b/src/Components/Functions/changePosition.ts index b129449f..8c5801a1 100644 --- a/src/Components/Functions/changePosition.ts +++ b/src/Components/Functions/changePosition.ts @@ -1,10 +1,10 @@ -import Translate from '../I18n/i18n'; -import { changeSelectedAllStatus } from '../Shortcut/shortcut'; -import windowName from '../../Service/window'; -import Storage from '../../Service/storage'; -import basename from './path/basename'; -import { UpdateInfo } from '../Layout/infobar'; -import { GET_TAB_ELEMENT } from '../../Util/constants'; +import Storage from "../../Service/storage"; +import windowName from "../../Service/window"; +import { GET_TAB_ELEMENT } from "../../Util/constants"; +import Translate from "../I18n/i18n"; +import { UpdateInfo } from "../Layout/infobar"; +import { changeSelectedAllStatus } from "../Shortcut/shortcut"; +import basename from "./path/basename"; /** * Change current tab position * @param {string} newPath - the new position you want to open @@ -13,38 +13,38 @@ import { GET_TAB_ELEMENT } from '../../Util/constants'; * @returns {Promise} */ const changePosition = async (newPath: string, forceChange = false, writeHistory?: boolean): Promise => { - document.querySelector('.path-navigator').value = newPath; - GET_TAB_ELEMENT().dataset.path = encodeURI(newPath); - if (!writeHistory) return; + document.querySelector(".path-navigator").value = newPath; + GET_TAB_ELEMENT().dataset.path = encodeURI(newPath); + if (!writeHistory) return; - const tabs = await Storage.get(`tabs-${windowName}`); - const _focusingTab = tabs?.tabs[String(tabs?.focus)]; - _focusingTab.position = newPath; + const tabs = await Storage.get(`tabs-${windowName}`); + const _focusingTab = tabs?.tabs[String(tabs?.focus)]; + _focusingTab.position = newPath; - if (newPath === _focusingTab.history[_focusingTab.currentIndex] && !forceChange) { - return; - } else if (newPath === _focusingTab.history[_focusingTab.currentIndex + 1]) { - _focusingTab.currentIndex += 1; - } else if (newPath === _focusingTab.history[_focusingTab.currentIndex - 1]) { - _focusingTab.currentIndex -= 1; - } else { - _focusingTab.history = _focusingTab.history.slice(0, _focusingTab.currentIndex + 1); - _focusingTab.history.push(newPath); - _focusingTab.currentIndex += 1; - } - tabs.tabs[String(tabs.focus)] = _focusingTab; + if (newPath === _focusingTab.history[_focusingTab.currentIndex] && !forceChange) { + return; + } else if (newPath === _focusingTab.history[_focusingTab.currentIndex + 1]) { + _focusingTab.currentIndex += 1; + } else if (newPath === _focusingTab.history[_focusingTab.currentIndex - 1]) { + _focusingTab.currentIndex -= 1; + } else { + _focusingTab.history = _focusingTab.history.slice(0, _focusingTab.currentIndex + 1); + _focusingTab.history.push(newPath); + _focusingTab.currentIndex += 1; + } + tabs.tabs[String(tabs.focus)] = _focusingTab; - document.getElementById(`tab${tabs.focus}`).querySelector('#tab-position').innerText = await Translate( - document.querySelector('.path-navigator').value.startsWith('Search: ') - ? newPath - : basename(newPath) === '' - ? newPath - : basename(newPath) - ); - Storage.set(`tabs-${windowName}`, tabs); - UpdateInfo('selected-files', ''); - changeSelectedAllStatus(); - return; + document.getElementById(`tab${tabs.focus}`).querySelector("#tab-position").innerText = await Translate( + document.querySelector(".path-navigator").value.startsWith("Search: ") + ? newPath + : basename(newPath) === "" + ? newPath + : basename(newPath), + ); + Storage.set(`tabs-${windowName}`, tabs); + UpdateInfo("selected-files", ""); + changeSelectedAllStatus(); + return; }; export default changePosition; diff --git a/src/Components/Functions/dragElement.ts b/src/Components/Functions/dragElement.ts index 67d57faa..3d468bce 100644 --- a/src/Components/Functions/dragElement.ts +++ b/src/Components/Functions/dragElement.ts @@ -5,50 +5,44 @@ * @returns {void} */ function dragElement(elmnt: HTMLElement, parentElement: HTMLElement): void { - let pos1 = 0, - pos2 = 0, - pos3 = 0, - pos4 = 0; - elmnt.onmousedown = dragMouseDown; + let pos1 = 0, + pos2 = 0, + pos3 = 0, + pos4 = 0; + elmnt.onmousedown = dragMouseDown; - function dragMouseDown(e: MouseEvent) { - e = e || (window.event as MouseEvent); - e.preventDefault(); - // get the mouse cursor position at startup: - pos3 = e.clientX; - pos4 = e.clientY; - document.onmouseup = closeDragElement; - // call a function whenever the cursor moves: - document.onmousemove = elementDrag; - } + function dragMouseDown(e: MouseEvent) { + e = e || (window.event as MouseEvent); + e.preventDefault(); + // get the mouse cursor position at startup: + pos3 = e.clientX; + pos4 = e.clientY; + document.onmouseup = closeDragElement; + // call a function whenever the cursor moves: + document.onmousemove = elementDrag; + } - function elementDrag(e: MouseEvent) { - e = e || (window.event as MouseEvent); - e.preventDefault(); - // calculate the new cursor position: - pos1 = pos3 - e.clientX; - pos2 = pos4 - e.clientY; - pos3 = e.clientX; - pos4 = e.clientY; - const x = parentElement.offsetLeft - parentElement.offsetWidth / 2; - const y = parentElement.offsetTop - parentElement.offsetHeight / 2; - // set the element's new position: - if ( - y - pos2 >= 0 && - y + parentElement.offsetHeight - pos2 <= window.innerHeight - ) - parentElement.style.top = parentElement.offsetTop - pos2 + 'px'; - if ( - x - pos1 >= 0 && - x + parentElement.offsetWidth - pos1 <= window.innerWidth - ) - parentElement.style.left = parentElement.offsetLeft - pos1 + 'px'; - } + function elementDrag(e: MouseEvent) { + e = e || (window.event as MouseEvent); + e.preventDefault(); + // calculate the new cursor position: + pos1 = pos3 - e.clientX; + pos2 = pos4 - e.clientY; + pos3 = e.clientX; + pos4 = e.clientY; + const x = parentElement.offsetLeft - parentElement.offsetWidth / 2; + const y = parentElement.offsetTop - parentElement.offsetHeight / 2; + // set the element's new position: + if (y - pos2 >= 0 && y + parentElement.offsetHeight - pos2 <= window.innerHeight) + parentElement.style.top = parentElement.offsetTop - pos2 + "px"; + if (x - pos1 >= 0 && x + parentElement.offsetWidth - pos1 <= window.innerWidth) + parentElement.style.left = parentElement.offsetLeft - pos1 + "px"; + } - function closeDragElement() { - /* stop moving when mouse button is released:*/ - document.onmouseup = null; - document.onmousemove = null; - } + function closeDragElement() { + /* stop moving when mouse button is released:*/ + document.onmouseup = null; + document.onmousemove = null; + } } export default dragElement; diff --git a/src/Components/Functions/elementClassNameContains.ts b/src/Components/Functions/elementClassNameContains.ts index 3b06512f..c2f5a355 100644 --- a/src/Components/Functions/elementClassNameContains.ts +++ b/src/Components/Functions/elementClassNameContains.ts @@ -1,7 +1,3 @@ -export const elementClassNameContains = ( - element: Element | null, - match: RegExp -): boolean => { - return new RegExp(match).test(element?.className); +export const elementClassNameContains = (element: Element | null, match: RegExp): boolean => { + return new RegExp(match).test(element?.className); }; - diff --git a/src/Components/Functions/extractExeIcon.ts b/src/Components/Functions/extractExeIcon.ts index 276f0c2a..7478b296 100644 --- a/src/Components/Functions/extractExeIcon.ts +++ b/src/Components/Functions/extractExeIcon.ts @@ -1,33 +1,28 @@ const extractExeIcon = (filePath: string): string => { - const fs = require('fs'); - const path = require('path'); - const { extractIcon } = require('../../Lib/extracticon/bindings'); - const electron = require('electron'); - const basename = - filePath.split(/[\\/]/)[filePath.split(/[\\/]/).length - 1]; - const app = - electron.app || (electron.remote && electron.remote.app) || null; - const EXE_ICON_CACHE_DIR = path.join( - app.getPath('userData'), - 'Cache/Exe Icon' - ); + const fs = require("fs"); + const path = require("path"); + const { extractIcon } = require("../../Lib/extracticon/bindings"); + const electron = require("electron"); + const basename = filePath.split(/[\\/]/)[filePath.split(/[\\/]/).length - 1]; + const app = electron.app || (electron.remote && electron.remote.app) || null; + const EXE_ICON_CACHE_DIR = path.join(app.getPath("userData"), "Cache/Exe Icon"); - // Create cache directory if not exist - if (!fs.existsSync(EXE_ICON_CACHE_DIR)) { - if (!fs.existsSync(path.join(EXE_ICON_CACHE_DIR, '..'))) { - fs.mkdirSync(path.join(EXE_ICON_CACHE_DIR, '..')); - } - fs.mkdirSync(EXE_ICON_CACHE_DIR); - } - const ICON_FILE_NAME = path.join(EXE_ICON_CACHE_DIR, basename + '.ico'); + // Create cache directory if not exist + if (!fs.existsSync(EXE_ICON_CACHE_DIR)) { + if (!fs.existsSync(path.join(EXE_ICON_CACHE_DIR, ".."))) { + fs.mkdirSync(path.join(EXE_ICON_CACHE_DIR, "..")); + } + fs.mkdirSync(EXE_ICON_CACHE_DIR); + } + const ICON_FILE_NAME = path.join(EXE_ICON_CACHE_DIR, basename + ".ico"); - // Cache the icon parsed from the exe - if (fs.existsSync(ICON_FILE_NAME)) { - return ICON_FILE_NAME; - } else { - const buffer = extractIcon(filePath, 'large'); - fs.writeFileSync(ICON_FILE_NAME, buffer); - return ICON_FILE_NAME; - } + // Cache the icon parsed from the exe + if (fs.existsSync(ICON_FILE_NAME)) { + return ICON_FILE_NAME; + } else { + const buffer = extractIcon(filePath, "large"); + fs.writeFileSync(ICON_FILE_NAME, buffer); + return ICON_FILE_NAME; + } }; export default extractExeIcon; diff --git a/src/Components/Functions/filesize.test.ts b/src/Components/Functions/filesize.test.ts index b6efa9c7..ab1ddb0e 100644 --- a/src/Components/Functions/filesize.test.ts +++ b/src/Components/Functions/filesize.test.ts @@ -1,27 +1,27 @@ -import * as filesize from './filesize'; +import * as filesize from "./filesize"; // @ponicode -describe('filesize.default', () => { - test('0', () => { - const result = filesize.default(1024); - expect(result).toBe('1 KB'); - }); +describe("filesize.default", () => { + test("0", () => { + const result = filesize.default(1024); + expect(result).toBe("1 KB"); + }); - test('1', () => { - const result = filesize.default(102); - expect(result).toBe('102 Bytes'); - }); + test("1", () => { + const result = filesize.default(102); + expect(result).toBe("102 Bytes"); + }); - test('2', () => { - const result = filesize.default(2097052); - expect(result).toBe('2 MB'); - }); + test("2", () => { + const result = filesize.default(2097052); + expect(result).toBe("2 MB"); + }); - test('3', () => { - const result = filesize.default(1073741824); - expect(result).toBe('1 GB'); - }); - test('4', () => { - const result = filesize.default(6356551598); - expect(result).toBe('5.92 GB'); - }); + test("3", () => { + const result = filesize.default(1073741824); + expect(result).toBe("1 GB"); + }); + test("4", () => { + const result = filesize.default(6356551598); + expect(result).toBe("5.92 GB"); + }); }); diff --git a/src/Components/Functions/filesize.ts b/src/Components/Functions/filesize.ts index 0937bd18..517cca59 100644 --- a/src/Components/Functions/filesize.ts +++ b/src/Components/Functions/filesize.ts @@ -5,13 +5,13 @@ * @returns {string} Human readable file size */ const formatBytes = (bytes: number): string => { - // kBlockFormat = 1024-blocks format byte - if (bytes === 0) return '0 Bytes'; - const k = 1024; - const dm = 2; // Decimal digit - const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']; - const i = Math.floor(Math.log(bytes) / Math.log(k)); - return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i]; + // kBlockFormat = 1024-blocks format byte + if (bytes === 0) return "0 Bytes"; + const k = 1024; + const dm = 2; // Decimal digit + const sizes = ["Bytes", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"]; + const i = Math.floor(Math.log(bytes) / Math.log(k)); + return Number.parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + " " + sizes[i]; }; export default formatBytes; diff --git a/src/Components/Functions/focusingPath.ts b/src/Components/Functions/focusingPath.ts index e495af1a..a687d954 100644 --- a/src/Components/Functions/focusingPath.ts +++ b/src/Components/Functions/focusingPath.ts @@ -1,5 +1,5 @@ -import OS from '../../Service/platform'; -import FavoritesAPI from '../../Service/favorites'; +import FavoritesAPI from "../../Service/favorites"; +import OS from "../../Service/platform"; let favoriteData: FavoritesAPI; let platform: string; @@ -8,15 +8,15 @@ let platform: string; * @returns {Promise} */ const focusingPath = async (): Promise => { - const PathNavigator = document.querySelector('.path-navigator') as HTMLInputElement; - if (!favoriteData) { - favoriteData = new FavoritesAPI(); - await favoriteData.build(); - } - if (!platform) { - platform = await OS(); - } - return PathNavigator.value === 'xplorer://Home' && platform === 'linux' ? favoriteData.HOMEDIR_PATH : PathNavigator.value; + const PathNavigator = document.querySelector(".path-navigator") as HTMLInputElement; + if (!favoriteData) { + favoriteData = new FavoritesAPI(); + await favoriteData.build(); + } + if (!platform) { + platform = await OS(); + } + return PathNavigator.value === "xplorer://Home" && platform === "linux" ? favoriteData.HOMEDIR_PATH : PathNavigator.value; }; export default focusingPath; diff --git a/src/Components/Functions/lazyLoadingImage.ts b/src/Components/Functions/lazyLoadingImage.ts index 816cee38..940e33fd 100644 --- a/src/Components/Functions/lazyLoadingImage.ts +++ b/src/Components/Functions/lazyLoadingImage.ts @@ -1,4 +1,4 @@ -import FileAPI from '../../Service/files'; +import FileAPI from "../../Service/files"; const FETCHED_ICONS: string[] = []; // Array of fetch icons @@ -8,14 +8,14 @@ const FETCHED_ICONS: string[] = []; // Array of fetch icons * @returns {boolean} if element in viewport */ const isOnImageViewport = (el: HTMLElement): boolean => { - const rect = el.getBoundingClientRect(); - const windowHeight = window.innerHeight || document.documentElement.clientHeight; - return ( - rect.top >= 0 && - rect.left >= 0 && - rect.bottom - windowHeight <= windowHeight && - rect.right <= (window.innerWidth || document.documentElement.clientWidth) - ); + const rect = el.getBoundingClientRect(); + const windowHeight = window.innerHeight || document.documentElement.clientHeight; + return ( + rect.top >= 0 && + rect.left >= 0 && + rect.bottom - windowHeight <= windowHeight && + rect.right <= (window.innerWidth || document.documentElement.clientWidth) + ); }; /** @@ -23,18 +23,18 @@ const isOnImageViewport = (el: HTMLElement): boolean => { * @returns {void} */ export const LOAD_IMAGE = (): void => { - const images = document.querySelectorAll('img[data-src]'); - images.forEach((image: HTMLImageElement) => { - if (isOnImageViewport(image)) { - if (image.dataset.isImg === 'true') { - image.src = new FileAPI(image.dataset.src).readAsset(); - } else { - image.src = require(`../../Icon/${image.dataset.src}`); - } - if (FETCHED_ICONS.indexOf(image.dataset.src) === -1) FETCHED_ICONS.push(image.dataset.src); - image.removeAttribute('data-src'); - } - }); + const images = document.querySelectorAll("img[data-src]"); + images.forEach((image: HTMLImageElement) => { + if (isOnImageViewport(image)) { + if (image.dataset.isImg === "true") { + image.src = new FileAPI(image.dataset.src).readAsset(); + } else { + image.src = require(`../../Icon/${image.dataset.src}`); + } + if (FETCHED_ICONS.indexOf(image.dataset.src) === -1) FETCHED_ICONS.push(image.dataset.src); + image.removeAttribute("data-src"); + } + }); }; /** @@ -42,21 +42,21 @@ export const LOAD_IMAGE = (): void => { * @returns {void} */ const LAZY_LOAD_INIT = (): void => { - // Only show image when its visible in viewport to reduce latency - document.querySelector('.main-box').addEventListener('scroll', () => { - const images = document.querySelectorAll('img[data-src]'); - images.forEach((image: HTMLImageElement) => { - if (isOnImageViewport(image)) { - if (image.dataset.isImg === 'true') { - image.src = new FileAPI(image.dataset.src).readAsset(); - } else { - image.src = require(`../../Icon/${image.dataset.src}`); - } - if (FETCHED_ICONS.indexOf(image.dataset.src) === -1) FETCHED_ICONS.push(image.dataset.src); - image.removeAttribute('data-src'); - } - }); - }); + // Only show image when its visible in viewport to reduce latency + document.querySelector(".main-box").addEventListener("scroll", () => { + const images = document.querySelectorAll("img[data-src]"); + images.forEach((image: HTMLImageElement) => { + if (isOnImageViewport(image)) { + if (image.dataset.isImg === "true") { + image.src = new FileAPI(image.dataset.src).readAsset(); + } else { + image.src = require(`../../Icon/${image.dataset.src}`); + } + if (FETCHED_ICONS.indexOf(image.dataset.src) === -1) FETCHED_ICONS.push(image.dataset.src); + image.removeAttribute("data-src"); + } + }); + }); }; export default LAZY_LOAD_INIT; diff --git a/src/Components/Functions/log.ts b/src/Components/Functions/log.ts index d6c62882..40b2bb55 100644 --- a/src/Components/Functions/log.ts +++ b/src/Components/Functions/log.ts @@ -1,10 +1,10 @@ -import windowName from '../../Service/window'; -import Storage from '../../Service/storage'; -import isValid from './validChecker'; +import Storage from "../../Service/storage"; +import windowName from "../../Service/window"; +import isValid from "./validChecker"; interface OpenLogType { - path: string; - timestamp: Date; + path: string; + timestamp: Date; } /** * Write an error log @@ -12,10 +12,10 @@ interface OpenLogType { * @returns {Promise} */ const ErrorLog = async (err: any): Promise => { - const log = await Storage.get('log'); - let errorLog = log?.errors ?? []; - log.errors = [...errorLog, { err, timestamp: new Date() }]; - Storage.set('log', log); + const log = await Storage.get("log"); + const errorLog = log?.errors ?? []; + log.errors = [...errorLog, { err, timestamp: new Date() }]; + Storage.set("log", log); }; /** @@ -24,10 +24,10 @@ const ErrorLog = async (err: any): Promise => { * @returns {Promise} */ const InfoLog = async (info: any): Promise => { - const log = await Storage.get('log'); - let infoLog = log?.info ?? []; - log.info = [...infoLog, { info, timestamp: new Date() }]; - Storage.set('log', log); + const log = await Storage.get("log"); + const infoLog = log?.info ?? []; + log.info = [...infoLog, { info, timestamp: new Date() }]; + Storage.set("log", log); }; /** @@ -38,21 +38,21 @@ const InfoLog = async (info: any): Promise => { * @returns {Promise} */ const OperationLog = async ( - operationType: 'copy' | 'cut' | 'delete' | 'newfile' | 'newfolder' | 'rename', - sources?: string | string[], - destination?: string + operationType: "copy" | "cut" | "delete" | "newfile" | "newfolder" | "rename", + sources?: string | string[], + destination?: string, ): Promise => { - let operationLogs = await Storage.get(`operations-${windowName}`); - if (!isValid(operationLogs)) - operationLogs = { - operations: [], - currentIndex: -1, - }; - if (JSON.stringify(operationLogs.operations[operationLogs.currentIndex + 1]) !== JSON.stringify({ operationType, sources, destination })) - operationLogs.operations = operationLogs.operations.slice(0, operationLogs.currentIndex + 1); - operationLogs.currentIndex += 1; - operationLogs.operations.push({ operationType, sources, destination }); - Storage.set(`operations-${windowName}`, operationLogs); + let operationLogs = await Storage.get(`operations-${windowName}`); + if (!isValid(operationLogs)) + operationLogs = { + operations: [], + currentIndex: -1, + }; + if (JSON.stringify(operationLogs.operations[operationLogs.currentIndex + 1]) !== JSON.stringify({ operationType, sources, destination })) + operationLogs.operations = operationLogs.operations.slice(0, operationLogs.currentIndex + 1); + operationLogs.currentIndex += 1; + operationLogs.operations.push({ operationType, sources, destination }); + Storage.set(`operations-${windowName}`, operationLogs); }; /** @@ -60,11 +60,11 @@ const OperationLog = async ( * @param {String} path - File/Dir path * @returns {Promise} */ -const OpenLog = async (path: String): Promise => { - const log = await Storage.get('log'); - let openLog = log?.opens ?? []; - log.opens = [...openLog, { path, timestamp: new Date() }]; - Storage.set('log', log); +const OpenLog = async (path: string): Promise => { + const log = await Storage.get("log"); + const openLog = log?.opens ?? []; + log.opens = [...openLog, { path, timestamp: new Date() }]; + Storage.set("log", log); }; -export { ErrorLog, InfoLog, OperationLog, OpenLog, OpenLogType }; +export { ErrorLog, InfoLog, OperationLog, OpenLog, type OpenLogType }; diff --git a/src/Components/Functions/new.ts b/src/Components/Functions/new.ts index fe21acea..0d3c3c13 100644 --- a/src/Components/Functions/new.ts +++ b/src/Components/Functions/new.ts @@ -1,27 +1,23 @@ -import NewFile from '../Files/File Operation/new'; -import NewFolder from '../Folder/new'; -import Ask from '../Prompt/ask'; -import focusingPath from './focusingPath'; +import NewFile from "../Files/File Operation/new"; +import NewFolder from "../Folder/new"; +import Ask from "../Prompt/ask"; +import focusingPath from "./focusingPath"; /** * Create new file/folder with prompting asking file/folder name * @param {'file'|'folder'} type * @returns {Promise} */ -const New = async (type: 'file' | 'folder'): Promise => { - /** - * Don't react if the user is on non-directory page - */ - if ((await focusingPath()).startsWith('xplorer://')) return; - if (type === 'file') { - Ask('New File', 'File Name:').then(async (fileName: string) => - NewFile(fileName, await focusingPath()) - ); - } else if (type === 'folder') { - Ask('New Folder', 'Folder Name:').then(async (folderName: string) => - NewFolder(folderName, await focusingPath()) - ); - } +const New = async (type: "file" | "folder"): Promise => { + /** + * Don't react if the user is on non-directory page + */ + if ((await focusingPath()).startsWith("xplorer://")) return; + if (type === "file") { + Ask("New File", "File Name:").then(async (fileName: string) => NewFile(fileName, await focusingPath())); + } else if (type === "folder") { + Ask("New Folder", "Folder Name:").then(async (folderName: string) => NewFolder(folderName, await focusingPath())); + } }; export default New; diff --git a/src/Components/Functions/path/basename.test.ts b/src/Components/Functions/path/basename.test.ts index 97518894..ae50d25b 100644 --- a/src/Components/Functions/path/basename.test.ts +++ b/src/Components/Functions/path/basename.test.ts @@ -1,23 +1,23 @@ -import * as basename from './basename'; +import * as basename from "./basename"; // @ponicode -describe('basename.default', () => { - test('0', () => { - const result = basename.default('path/to/file.ext'); - expect(result).toBe('file.ext'); - }); +describe("basename.default", () => { + test("0", () => { + const result = basename.default("path/to/file.ext"); + expect(result).toBe("file.ext"); + }); - test('1', () => { - const result = basename.default('path/to/folder/'); - expect(result).toBe('folder'); - }); + test("1", () => { + const result = basename.default("path/to/folder/"); + expect(result).toBe("folder"); + }); - test('2', () => { - const result = basename.default('/path/to/file'); - expect(result).toBe('file'); - }); + test("2", () => { + const result = basename.default("/path/to/file"); + expect(result).toBe("file"); + }); - test('4', () => { - const result = basename.default('C:\\\\path\\to\\folder\\'); - expect(result).toBe('folder'); - }); + test("4", () => { + const result = basename.default("C:\\\\path\\to\\folder\\"); + expect(result).toBe("folder"); + }); }); diff --git a/src/Components/Functions/path/basename.ts b/src/Components/Functions/path/basename.ts index 71e85a4c..bd41b415 100644 --- a/src/Components/Functions/path/basename.ts +++ b/src/Components/Functions/path/basename.ts @@ -4,8 +4,8 @@ * @returns {string} */ const basename = (path: string): string => - path - .replace(/(\\|\/)$/g, '') - .split(/[\\/]/) - .pop(); + path + .replace(/(\\|\/)$/g, "") + .split(/[\\/]/) + .pop(); export default basename; diff --git a/src/Components/Functions/path/dirname.test.ts b/src/Components/Functions/path/dirname.test.ts index 5a00d3fe..957422cf 100644 --- a/src/Components/Functions/path/dirname.test.ts +++ b/src/Components/Functions/path/dirname.test.ts @@ -1,28 +1,28 @@ -import * as dirname from './dirname'; +import * as dirname from "./dirname"; // @ponicode -describe('dirname.default', () => { - test('0', () => { - const result = dirname.default('/path/to/file'); - expect(result).toBe('/path/to/'); - }); +describe("dirname.default", () => { + test("0", () => { + const result = dirname.default("/path/to/file"); + expect(result).toBe("/path/to/"); + }); - test('1', () => { - const result = dirname.default('path/to/file.ext'); - expect(result).toBe('path/to/'); - }); + test("1", () => { + const result = dirname.default("path/to/file.ext"); + expect(result).toBe("path/to/"); + }); - test('2', () => { - const result = dirname.default('path/to/folder/'); - expect(result).toBe('path/to/'); - }); + test("2", () => { + const result = dirname.default("path/to/folder/"); + expect(result).toBe("path/to/"); + }); - test('3', () => { - const result = dirname.default('./path/to/file'); - expect(result).toBe('./path/to/'); - }); + test("3", () => { + const result = dirname.default("./path/to/file"); + expect(result).toBe("./path/to/"); + }); - test('4', () => { - const result = dirname.default('C:\\\\path\\to\\folder\\'); - expect(result).toBe('C:\\\\path\\to/'); - }); + test("4", () => { + const result = dirname.default("C:\\\\path\\to\\folder\\"); + expect(result).toBe("C:\\\\path\\to/"); + }); }); diff --git a/src/Components/Functions/path/dirname.ts b/src/Components/Functions/path/dirname.ts index fd3f1d76..385b0bc2 100644 --- a/src/Components/Functions/path/dirname.ts +++ b/src/Components/Functions/path/dirname.ts @@ -4,26 +4,26 @@ * @returns {any} result of the evaluated path */ const getDirname = (path: string): string => { - if (path.length === 0) return '.'; - let code = path.charCodeAt(0); - const hasRoot = code === 47 || code === 92; /*/*/ - let end = -1; - let matchedSlash = true; - for (let i = path.length - 1; i >= 1; --i) { - code = path.charCodeAt(i); - if (code === 47 || code === 92) { - if (!matchedSlash) { - end = i; - break; - } - } else { - // We saw the first non-path separator - matchedSlash = false; - } - } - if (end === -1) return hasRoot ? '/' : '.'; - if (hasRoot && end === 1) return '//'; - const result = path.slice(0, end); - if (!(result.endsWith('/') || result.endsWith('\\'))) return result + '/'; + if (path.length === 0) return "."; + let code = path.charCodeAt(0); + const hasRoot = code === 47 || code === 92; /*/*/ + let end = -1; + let matchedSlash = true; + for (let i = path.length - 1; i >= 1; --i) { + code = path.charCodeAt(i); + if (code === 47 || code === 92) { + if (!matchedSlash) { + end = i; + break; + } + } else { + // We saw the first non-path separator + matchedSlash = false; + } + } + if (end === -1) return hasRoot ? "/" : "."; + if (hasRoot && end === 1) return "//"; + const result = path.slice(0, end); + if (!(result.endsWith("/") || result.endsWith("\\"))) return result + "/"; }; export default getDirname; diff --git a/src/Components/Functions/path/joinPath.test.ts b/src/Components/Functions/path/joinPath.test.ts index 6acb8aa8..49c94c96 100644 --- a/src/Components/Functions/path/joinPath.test.ts +++ b/src/Components/Functions/path/joinPath.test.ts @@ -1,24 +1,24 @@ -import * as joinPath from './joinPath'; +import * as joinPath from "./joinPath"; // @ponicode -describe('joinPath.default', () => { - test('0', () => { - const result = joinPath.default('path/to/', 'test'); - expect(result).toBe('path/to/test'); - }); +describe("joinPath.default", () => { + test("0", () => { + const result = joinPath.default("path/to/", "test"); + expect(result).toBe("path/to/test"); + }); - test('1', () => { - const result = joinPath.default('path/to/folder/', 'a'); - expect(result).toBe('path/to/folder/a'); - }); + test("1", () => { + const result = joinPath.default("path/to/folder/", "a"); + expect(result).toBe("path/to/folder/a"); + }); - test('2', () => { - const result = joinPath.default('/path/to/file', 'hello'); - expect(result).toBe('/path/to/file/hello'); - }); + test("2", () => { + const result = joinPath.default("/path/to/file", "hello"); + expect(result).toBe("/path/to/file/hello"); + }); - test('3', () => { - const result = joinPath.default('C:\\\\path\\to\\folder\\', 'myfile'); - expect(result).toBe('C:\\\\path\\to\\folder\\myfile'); - }); + test("3", () => { + const result = joinPath.default("C:\\\\path\\to\\folder\\", "myfile"); + expect(result).toBe("C:\\\\path\\to\\folder\\myfile"); + }); }); diff --git a/src/Components/Functions/path/joinPath.ts b/src/Components/Functions/path/joinPath.ts index f88c0033..3a7edd76 100644 --- a/src/Components/Functions/path/joinPath.ts +++ b/src/Components/Functions/path/joinPath.ts @@ -4,21 +4,20 @@ * @returns {string} */ const joinPath = (...args: string[]): string => { - if (args.length === 0) return '.'; - let joined; - for (let i = 0; i < args.length; i++) { - const arg = args[i]; - if (arg.length > 0) { - if (joined === undefined) joined = arg; - else { - if (!(joined?.endsWith('/') || joined?.endsWith('\\'))) - joined += '/'; - joined += arg; - } - } - } - if (joined === undefined) return '.'; - return joined; + if (args.length === 0) return "."; + let joined; + for (let i = 0; i < args.length; i++) { + const arg = args[i]; + if (arg.length > 0) { + if (joined === undefined) joined = arg; + else { + if (!(joined?.endsWith("/") || joined?.endsWith("\\"))) joined += "/"; + joined += arg; + } + } + } + if (joined === undefined) return "."; + return joined; }; export default joinPath; diff --git a/src/Components/Functions/path/normalizeSlash.test.ts b/src/Components/Functions/path/normalizeSlash.test.ts index 08873a45..11befbbc 100644 --- a/src/Components/Functions/path/normalizeSlash.test.ts +++ b/src/Components/Functions/path/normalizeSlash.test.ts @@ -1,20 +1,20 @@ -import * as normalizeSlash from './normalizeSlash'; +import * as normalizeSlash from "./normalizeSlash"; // @ponicode -describe('normalizeSlash.default', () => { - test('0', () => { - const result = normalizeSlash.default('path/to/folder/'); - expect(result).toBe('path/to/folder'); - }); - test('1', () => { - const result = normalizeSlash.default('path\\to\\folder\\'); - expect(result).toBe('path/to/folder'); - }); - test('2', () => { - const result = normalizeSlash.default('E:'); - expect(result).toBe('E:/'); - }); - test('3', () => { - const result = normalizeSlash.default('E:/'); - expect(result).toBe('E:/'); - }); +describe("normalizeSlash.default", () => { + test("0", () => { + const result = normalizeSlash.default("path/to/folder/"); + expect(result).toBe("path/to/folder"); + }); + test("1", () => { + const result = normalizeSlash.default("path\\to\\folder\\"); + expect(result).toBe("path/to/folder"); + }); + test("2", () => { + const result = normalizeSlash.default("E:"); + expect(result).toBe("E:/"); + }); + test("3", () => { + const result = normalizeSlash.default("E:/"); + expect(result).toBe("E:/"); + }); }); diff --git a/src/Components/Functions/path/normalizeSlash.ts b/src/Components/Functions/path/normalizeSlash.ts index 78ece963..fbf1d6ab 100644 --- a/src/Components/Functions/path/normalizeSlash.ts +++ b/src/Components/Functions/path/normalizeSlash.ts @@ -4,12 +4,11 @@ * @returns {string} */ const NormalizeSlash = (path: string): string => { - if (path === '\\' || path === '/') return '/'; - path = path.replace(/\\/g, '/'); + if (path === "\\" || path === "/") return "/"; + path = path.replace(/\\/g, "/"); - if (path.length === 2 && /.:/.test(path)) return path + '/'; - if (path.endsWith('/') && !(path.length === 3 && /.:\//.test(path))) - return path.slice(0, path.length - 1); - return path; + if (path.length === 2 && /.:/.test(path)) return path + "/"; + if (path.endsWith("/") && !(path.length === 3 && /.:\//.test(path))) return path.slice(0, path.length - 1); + return path; }; export default NormalizeSlash; diff --git a/src/Components/Functions/toggleHiddenFiles.ts b/src/Components/Functions/toggleHiddenFiles.ts index 1388e8a8..73216a78 100644 --- a/src/Components/Functions/toggleHiddenFiles.ts +++ b/src/Components/Functions/toggleHiddenFiles.ts @@ -1,10 +1,10 @@ -import { MAIN_BOX_ELEMENT } from '../../Util/constants'; -import Storage from '../../Service/storage'; +import Storage from "../../Service/storage"; +import { MAIN_BOX_ELEMENT } from "../../Util/constants"; const toggleHiddenFiles = async (): Promise => { - const _preference = await Storage.get('preference'); - const hideHiddenFiles = !_preference?.hideHiddenFiles; - _preference.hideHiddenFiles = hideHiddenFiles; - MAIN_BOX_ELEMENT().dataset.hideHiddenFiles = String(hideHiddenFiles); - Storage.set('preference', _preference); + const _preference = await Storage.get("preference"); + const hideHiddenFiles = !_preference?.hideHiddenFiles; + _preference.hideHiddenFiles = hideHiddenFiles; + MAIN_BOX_ELEMENT().dataset.hideHiddenFiles = String(hideHiddenFiles); + Storage.set("preference", _preference); }; export default toggleHiddenFiles; diff --git a/src/Components/Functions/urlify.ts b/src/Components/Functions/urlify.ts index cae99cfa..792a9560 100644 --- a/src/Components/Functions/urlify.ts +++ b/src/Components/Functions/urlify.ts @@ -4,11 +4,8 @@ * @returns {string} URLified HTML text. */ const URLify = (string: string): string => { - const regex = />((((ftp|https?):\/\/)|(w{3}\.))[-\w@:%_+.~#?,&//=]+)/g; - return string.replace( - regex, - '>$1' - ); + const regex = />((((ftp|https?):\/\/)|(w{3}\.))[-\w@:%_+.~#?,&//=]+)/g; + return string.replace(regex, '>$1'); }; /** @@ -17,14 +14,14 @@ const URLify = (string: string): string => { * @returns {string} eURLified HTML text. */ const eURLify = (string: string): string => { - const _el = document.createElement('div'); - _el.innerHTML = string; - _el.querySelectorAll('a').forEach((a) => { - if (a.getAttribute('target') !== '_blank') { - a.setAttribute('target', '_blank'); - } - }); - return _el.innerHTML; + const _el = document.createElement("div"); + _el.innerHTML = string; + _el.querySelectorAll("a").forEach((a) => { + if (a.getAttribute("target") !== "_blank") { + a.setAttribute("target", "_blank"); + } + }); + return _el.innerHTML; }; export { URLify, eURLify }; diff --git a/src/Components/Functions/validChecker.test.ts b/src/Components/Functions/validChecker.test.ts index 9a92ec53..9e44499c 100644 --- a/src/Components/Functions/validChecker.test.ts +++ b/src/Components/Functions/validChecker.test.ts @@ -1,49 +1,49 @@ -import * as validChecker from './validChecker'; +import * as validChecker from "./validChecker"; // @ponicode -describe('validChecker.default', () => { - test('0', () => { - const result = validChecker.default({ - key1: 'Foo bar', - key5: -5.48, - }); - expect(result).toBe(true); - }); +describe("validChecker.default", () => { + test("0", () => { + const result = validChecker.default({ + key1: "Foo bar", + key5: -5.48, + }); + expect(result).toBe(true); + }); - test('1', () => { - const result = validChecker.default({ key1: 'foo bar', key5: -100 }); - expect(result).toBe(true); - }); + test("1", () => { + const result = validChecker.default({ key1: "foo bar", key5: -100 }); + expect(result).toBe(true); + }); - test('2', () => { - const result = validChecker.default({ - key1: 'Hello, world!', - key5: 1, - }); - expect(result).toBe(true); - }); + test("2", () => { + const result = validChecker.default({ + key1: "Hello, world!", + key5: 1, + }); + expect(result).toBe(true); + }); - test('3', () => { - const result = validChecker.default({ - key1: 'Hello, world!', - key5: -100, - }); - expect(result).toBe(true); - }); + test("3", () => { + const result = validChecker.default({ + key1: "Hello, world!", + key5: -100, + }); + expect(result).toBe(true); + }); - test('4', () => { - const result = validChecker.default(undefined); - expect(result).toBe(false); - }); - test('5', () => { - const result = validChecker.default(null); - expect(result).toBe(false); - }); - test('5', () => { - const result = validChecker.default({}); - expect(result).toBe(false); - }); - test('6', () => { - const result = validChecker.default([]); - expect(result).toBe(false); - }); + test("4", () => { + const result = validChecker.default(undefined); + expect(result).toBe(false); + }); + test("5", () => { + const result = validChecker.default(null); + expect(result).toBe(false); + }); + test("5", () => { + const result = validChecker.default({}); + expect(result).toBe(false); + }); + test("6", () => { + const result = validChecker.default([]); + expect(result).toBe(false); + }); }); diff --git a/src/Components/Functions/validChecker.ts b/src/Components/Functions/validChecker.ts index 20983129..56d0dc71 100644 --- a/src/Components/Functions/validChecker.ts +++ b/src/Components/Functions/validChecker.ts @@ -6,14 +6,14 @@ * @returns {boolean} is it valid? */ const IsValid = (obj: any): boolean => { - if (obj === null || obj === undefined) return false; - else if (Array.isArray(obj)) { - if (obj.length === 0) return false; - else return true; - } else if (typeof obj === 'object') { - if (Object.keys(obj).length === 0) return false; - else return true; - } else if (obj) return true; - return false; + if (obj === null || obj === undefined) return false; + else if (Array.isArray(obj)) { + if (obj.length === 0) return false; + else return true; + } else if (typeof obj === "object") { + if (Object.keys(obj).length === 0) return false; + else return true; + } else if (obj) return true; + return false; }; export default IsValid; diff --git a/src/Components/Functions/viewport.ts b/src/Components/Functions/viewport.ts index 2add4dac..59045f3a 100644 --- a/src/Components/Functions/viewport.ts +++ b/src/Components/Functions/viewport.ts @@ -4,13 +4,13 @@ * @returns {boolean} if element in viewport */ const isElementInViewport = (el: HTMLElement): boolean => { - const rect = el.getBoundingClientRect(); - return ( - rect.top >= 0 && - rect.left >= 0 && - rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) && - rect.right <= (window.innerWidth || document.documentElement.clientWidth) - ); + const rect = el.getBoundingClientRect(); + return ( + rect.top >= 0 && + rect.left >= 0 && + rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) && + rect.right <= (window.innerWidth || document.documentElement.clientWidth) + ); }; /** @@ -19,7 +19,7 @@ const isElementInViewport = (el: HTMLElement): boolean => { * @returns {void} */ const ensureElementInViewPort = (element: HTMLElement): void => { - if (!isElementInViewport(element)) element.scrollIntoView({ block: 'center', behavior: 'smooth' }); + if (!isElementInViewport(element)) element.scrollIntoView({ block: "center", behavior: "smooth" }); }; export { ensureElementInViewPort }; diff --git a/src/Components/Header/SubHeader.tsx b/src/Components/Header/SubHeader.tsx index 8546619b..03626451 100644 --- a/src/Components/Header/SubHeader.tsx +++ b/src/Components/Header/SubHeader.tsx @@ -1,6 +1,6 @@ -import React, { FormEvent, useEffect, useState } from "react"; +import React, { type FormEvent, useEffect, useState } from "react"; -import { ITab } from "."; +import type { ITab } from "."; import { getParentDirectory } from "../../Helpers/paths"; import { ThemedButton, ThemedDiv, ThemedInput } from "../Theme"; @@ -52,7 +52,12 @@ const SubHeader = ({ activeTab, handleBack, handleForward, handlePathChange, han handlePathChange({ ...tempTab, path: getParentDirectory(tempTab.path) })} + onClick={() => + handlePathChange({ + ...tempTab, + path: getParentDirectory(tempTab.path), + }) + } // id="go-parent-dir" title="Parent Directory (Alt + Up Arrow)" > diff --git a/src/Components/Header/index.tsx b/src/Components/Header/index.tsx index 2a63fe26..064c235f 100644 --- a/src/Components/Header/index.tsx +++ b/src/Components/Header/index.tsx @@ -1,13 +1,13 @@ import React, { useEffect } from "react"; import { useDispatch, useSelector } from "react-redux"; -import SubHeader from "./SubHeader"; import { getStandardPath } from "../../Helpers/paths"; import { fetchFilesRequest, updateHistoryIdxRequest } from "../../Store/ActionCreators/DirectoryActionCreators"; import { createTab, deleteTab, setActiveTab } from "../../Store/ActionCreators/TabActionCreators"; -import { IAppState } from "../../Store/Reducers"; -import { ThemedButton, ThemedDiv, ThemedSpan } from "../Theme"; import { closeWindowRequest, maximizeWindowRequest, minimizeWindowRequest } from "../../Store/ActionCreators/WindowActionCreators"; +import type { IAppState } from "../../Store/Reducers"; +import { ThemedButton, ThemedDiv, ThemedSpan } from "../Theme"; +import SubHeader from "./SubHeader"; let tabId = 0; export interface ITab { name: string; diff --git a/src/Components/I18n/i18n.ts b/src/Components/I18n/i18n.ts index fad368ac..99848f2d 100644 --- a/src/Components/I18n/i18n.ts +++ b/src/Components/I18n/i18n.ts @@ -1,5 +1,5 @@ -import Storage from "../../Service/storage"; import LocalesAPI from "../../Service/locales"; +import Storage from "../../Service/storage"; let localesInformation: LocalesAPI; @@ -14,19 +14,15 @@ const Translate = async (source: string): Promise => { localesInformation = new LocalesAPI(); await localesInformation.build(); } - const lang = - (await Storage.get("preference"))?.language ?? navigator.language; + const lang = (await Storage.get("preference"))?.language ?? navigator.language; for (const locale of Object.values(localesInformation.AVAILABLE_LOCALES)) { // Check if the inputed lang available if (locale === lang) { if (localesInformation.LOCALES[locale]) { // Replace all text - Object.keys(localesInformation.LOCALES[locale]).forEach( - (key) => { - if (source === key) - source = localesInformation.LOCALES[locale][key]; - } - ); + Object.keys(localesInformation.LOCALES[locale]).forEach((key) => { + if (source === key) source = localesInformation.LOCALES[locale][key]; + }); } // Return translated text return source; diff --git a/src/Components/Layout/home.ts b/src/Components/Layout/home.ts index cdf425e5..0e66e251 100644 --- a/src/Components/Layout/home.ts +++ b/src/Components/Layout/home.ts @@ -1,16 +1,16 @@ -import { Drives } from '../Drives/drives'; -import Favorites from '../Favorites/favorites'; -import { updateTheme } from '../Theme/theme'; -import { startLoading, stopLoading } from '../Functions/Loading/loading'; -import OS from '../../Service/platform'; -import DirectoryAPI from '../../Service/directory'; -import FavoritesAPI from '../../Service/favorites'; -import displayFiles from '../Open/displayFiles'; -import { LOAD_IMAGE } from '../Functions/lazyLoadingImage'; -import { GET_TAB_ELEMENT } from '../../Util/constants'; +import DirectoryAPI from "../../Service/directory"; +import FavoritesAPI from "../../Service/favorites"; +import OS from "../../Service/platform"; +import { GET_TAB_ELEMENT } from "../../Util/constants"; +import { Drives } from "../Drives/drives"; +import Favorites from "../Favorites/favorites"; +import { startLoading, stopLoading } from "../Functions/Loading/loading"; +import { LOAD_IMAGE } from "../Functions/lazyLoadingImage"; +import displayFiles from "../Open/displayFiles"; +import { updateTheme } from "../Theme/theme"; let platform: string; (async () => { - platform = await OS(); + platform = await OS(); })(); let favoritesData: FavoritesAPI; @@ -20,37 +20,37 @@ let favoritesData: FavoritesAPI; * @returns {Promise} */ const Home = async (): Promise => { - startLoading(); - // Get the main element - const MAIN_ELEMENT = GET_TAB_ELEMENT(); - if (MAIN_ELEMENT.classList.contains('empty-dir-notification')) MAIN_ELEMENT.classList.remove('empty-dir-notification'); // Remove class if exist - const favorites = await Favorites(); - const drives = await Drives(); - MAIN_ELEMENT.innerHTML = favorites + drives; - if (platform !== 'win32') { - if (!favoritesData?.HOMEDIR_PATH) { - favoritesData = new FavoritesAPI(); - await favoritesData.build(); - } - const directoryInfo = new DirectoryAPI(favoritesData.HOMEDIR_PATH); - const homeElement = document.createElement('section'); - homeElement.classList.add('home-section'); - homeElement.innerHTML = '

Files

'; + startLoading(); + // Get the main element + const MAIN_ELEMENT = GET_TAB_ELEMENT(); + if (MAIN_ELEMENT.classList.contains("empty-dir-notification")) MAIN_ELEMENT.classList.remove("empty-dir-notification"); // Remove class if exist + const favorites = await Favorites(); + const drives = await Drives(); + MAIN_ELEMENT.innerHTML = favorites + drives; + if (platform !== "win32") { + if (!favoritesData?.HOMEDIR_PATH) { + favoritesData = new FavoritesAPI(); + await favoritesData.build(); + } + const directoryInfo = new DirectoryAPI(favoritesData.HOMEDIR_PATH); + const homeElement = document.createElement("section"); + homeElement.classList.add("home-section"); + homeElement.innerHTML = '

Files'; - const homeFiles = await directoryInfo.getFiles(); - const homeSection = await displayFiles(homeFiles.files, favoritesData.HOMEDIR_PATH, homeElement); - // Update the content in the main page ... - MAIN_ELEMENT.innerHTML = favorites + drives; - MAIN_ELEMENT.appendChild(homeSection); + const homeFiles = await directoryInfo.getFiles(); + const homeSection = await displayFiles(homeFiles.files, favoritesData.HOMEDIR_PATH, homeElement); + // Update the content in the main page ... + MAIN_ELEMENT.innerHTML = favorites + drives; + MAIN_ELEMENT.appendChild(homeSection); - // And also the theme :) - updateTheme('favorites'); - updateTheme('grid'); - stopLoading(); - } - updateTheme('favorites'); - stopLoading(); - LOAD_IMAGE(); + // And also the theme :) + updateTheme("favorites"); + updateTheme("grid"); + stopLoading(); + } + updateTheme("favorites"); + stopLoading(); + LOAD_IMAGE(); }; export default Home; diff --git a/src/Components/Layout/hover.ts b/src/Components/Layout/hover.ts index 54587daa..8c2288aa 100644 --- a/src/Components/Layout/hover.ts +++ b/src/Components/Layout/hover.ts @@ -1,83 +1,86 @@ -import FileAPI from '../../Service/files'; -import { IMAGE_TYPES } from '../../Config/file.config'; -import getBasename from '../Functions/path/basename'; -import Storage from '../../Service/storage'; -import { MAIN_BOX_ELEMENT } from '../../Util/constants'; -import focusingPath from '../Functions/focusingPath'; +import { IMAGE_TYPES } from "../../Config/file.config"; +import FileAPI from "../../Service/files"; +import Storage from "../../Service/storage"; +import { MAIN_BOX_ELEMENT } from "../../Util/constants"; +import focusingPath from "../Functions/focusingPath"; +import getBasename from "../Functions/path/basename"; const getExtension = (filename: string): string => { - const basename = getBasename(filename); - const index = basename.lastIndexOf('.'); - if (index === -1) { - return ''; - } - return basename.substr(index + 1); + const basename = getBasename(filename); + const index = basename.lastIndexOf("."); + if (index === -1) { + return ""; + } + return basename.substr(index + 1); }; /** * Listen to mouse hovering * @returns {void} */ const Hover = (): void => { - let timeOut: number; - let displayName: string; - let hoveringElement: HTMLElement; - const hoverPreviewElement = document.createElement('div'); + let timeOut: number; + let displayName: string; + let hoveringElement: HTMLElement; + const hoverPreviewElement = document.createElement("div"); - MAIN_BOX_ELEMENT().addEventListener('mousemove', (e) => { - let x = (e as MouseEvent).clientX; - let y = (e as MouseEvent).clientY; - window.clearTimeout(timeOut); - hoverPreviewElement?.parentNode?.removeChild(hoverPreviewElement); + MAIN_BOX_ELEMENT().addEventListener("mousemove", (e) => { + let x = (e as MouseEvent).clientX; + let y = (e as MouseEvent).clientY; + window.clearTimeout(timeOut); + hoverPreviewElement?.parentNode?.removeChild(hoverPreviewElement); - // Ignore workspace hovering - if ((e.target as HTMLElement).classList.contains('workspace-tab') || (e.target as HTMLElement).classList.contains('workspace')) { - if (hoveringElement?.dataset?.path && displayName) hoveringElement.querySelector('.file-grid-filename').innerHTML = displayName; - return; - } - const isOnSearch = document.querySelector('.path-navigator').value.startsWith('Search: '); + // Ignore workspace hovering + if ((e.target as HTMLElement).classList.contains("workspace-tab") || (e.target as HTMLElement).classList.contains("workspace")) { + if (hoveringElement?.dataset?.path && displayName) hoveringElement.querySelector(".file-grid-filename").innerHTML = displayName; + return; + } + const isOnSearch = document.querySelector(".path-navigator").value.startsWith("Search: "); - hoveringElement?.classList?.remove('hovering'); + hoveringElement?.classList?.remove("hovering"); - const target = (e.target as HTMLElement)?.dataset?.path ? (e.target as HTMLElement) : ((e.target as HTMLElement)?.parentNode as HTMLElement); + const target = (e.target as HTMLElement)?.dataset?.path ? (e.target as HTMLElement) : ((e.target as HTMLElement)?.parentNode as HTMLElement); - const filenameGrid = target.querySelector('.file-grid-filename'); + const filenameGrid = target.querySelector(".file-grid-filename"); - if (!filenameGrid) return; + if (!filenameGrid) return; - if (target !== hoveringElement) { - displayName = undefined; - } - hoveringElement = target; + if (target !== hoveringElement) { + displayName = undefined; + } + hoveringElement = target; - let openFromPreviewElementListener: { (): void; (this: HTMLDivElement, ev: MouseEvent): any; (this: HTMLDivElement, ev: MouseEvent): any } = - null; + let openFromPreviewElementListener: { + (): void; + (this: HTMLDivElement, ev: MouseEvent): any; + (this: HTMLDivElement, ev: MouseEvent): any; + } = null; - timeOut = window.setTimeout(async () => { - displayName = filenameGrid.innerHTML; - const path = decodeURI((await focusingPath()) === 'xplorer://Trash' ? target.dataset.realPath : target.dataset.path); - filenameGrid.innerHTML = isOnSearch ? path : getBasename(path); - target?.classList?.add('hovering'); + timeOut = window.setTimeout(async () => { + displayName = filenameGrid.innerHTML; + const path = decodeURI((await focusingPath()) === "xplorer://Trash" ? target.dataset.realPath : target.dataset.path); + filenameGrid.innerHTML = isOnSearch ? path : getBasename(path); + target?.classList?.add("hovering"); - const previewImageOnHover = (await Storage.get('appearance')).previewImageOnHover ?? true; - if (IMAGE_TYPES.indexOf(getExtension(filenameGrid.innerHTML)) !== -1 && previewImageOnHover) { - hoverPreviewElement.innerHTML = ``; - hoverPreviewElement.classList.add('hover-preview'); - openFromPreviewElementListener = () => { - new FileAPI(path).openFile(); - hoverPreviewElement.removeEventListener('click', openFromPreviewElementListener); //eslint-disable-line - }; - hoverPreviewElement.addEventListener('click', openFromPreviewElementListener); - document.body.appendChild(hoverPreviewElement); + const previewImageOnHover = (await Storage.get("appearance")).previewImageOnHover ?? true; + if (IMAGE_TYPES.indexOf(getExtension(filenameGrid.innerHTML)) !== -1 && previewImageOnHover) { + hoverPreviewElement.innerHTML = ``; + hoverPreviewElement.classList.add("hover-preview"); + openFromPreviewElementListener = () => { + new FileAPI(path).openFile(); + hoverPreviewElement.removeEventListener("click", openFromPreviewElementListener); //eslint-disable-line + }; + hoverPreviewElement.addEventListener("click", openFromPreviewElementListener); + document.body.appendChild(hoverPreviewElement); - if (hoverPreviewElement.clientWidth > window.innerWidth) hoverPreviewElement.style.width = `${0.5 * window.innerWidth}px`; - if (x + 300 > document.body.offsetWidth) x -= hoverPreviewElement.offsetWidth; - if (y + hoverPreviewElement.clientHeight > document.body.offsetHeight) y -= hoverPreviewElement.offsetHeight; - hoverPreviewElement.style.top = y + 'px'; - hoverPreviewElement.style.left = x + 'px'; - hoverPreviewElement.dataset.path = target.dataset.path; - } - }, 500); - }); + if (hoverPreviewElement.clientWidth > window.innerWidth) hoverPreviewElement.style.width = `${0.5 * window.innerWidth}px`; + if (x + 300 > document.body.offsetWidth) x -= hoverPreviewElement.offsetWidth; + if (y + hoverPreviewElement.clientHeight > document.body.offsetHeight) y -= hoverPreviewElement.offsetHeight; + hoverPreviewElement.style.top = y + "px"; + hoverPreviewElement.style.left = x + "px"; + hoverPreviewElement.dataset.path = target.dataset.path; + } + }, 500); + }); }; export default Hover; diff --git a/src/Components/Layout/infobar.ts b/src/Components/Layout/infobar.ts index cb7f76ed..1472de76 100644 --- a/src/Components/Layout/infobar.ts +++ b/src/Components/Layout/infobar.ts @@ -1,10 +1,10 @@ -import Storage from '../../Service/storage'; +import Storage from "../../Service/storage"; let infoBarElement: HTMLElement; const UpdateInfo = (key: string, value: string): void => { - const el = document.querySelector(`.infobar-item#${key}`); - if (!el) return; - el.innerHTML = value; + const el = document.querySelector(`.infobar-item#${key}`); + if (!el) return; + el.innerHTML = value; }; /** @@ -12,17 +12,17 @@ const UpdateInfo = (key: string, value: string): void => { * @returns {any} */ const Infobar = async (): Promise => { - const appearance = await Storage.get('appearance'); - document.body.dataset.infobarEnabled = appearance?.showInfoBar ?? true; - if (!(appearance?.showInfoBar ?? true)) return; - infoBarElement = document.createElement('div'); - infoBarElement.classList.add('infobar'); - infoBarElement.id = 'infobar'; - infoBarElement.innerHTML = ` + const appearance = await Storage.get("appearance"); + document.body.dataset.infobarEnabled = appearance?.showInfoBar ?? true; + if (!(appearance?.showInfoBar ?? true)) return; + infoBarElement = document.createElement("div"); + infoBarElement.classList.add("infobar"); + infoBarElement.id = "infobar"; + infoBarElement.innerHTML = `
`; - document.querySelector('.main').appendChild(infoBarElement); + document.querySelector(".main").appendChild(infoBarElement); }; export default Infobar; export { UpdateInfo }; diff --git a/src/Components/Layout/resizer.ts b/src/Components/Layout/resizer.ts index 336e2723..b1055fed 100644 --- a/src/Components/Layout/resizer.ts +++ b/src/Components/Layout/resizer.ts @@ -1,5 +1,5 @@ -import IStorageData from '../../Typings/storageData'; -import Storage from '../../Service/storage'; +import Storage from "../../Service/storage"; +import type IStorageData from "../../Typings/storageData"; const sidebarEdgeSensor = 10; const windowMinSize = 800; @@ -13,110 +13,110 @@ let settingsSidebar: HTMLElement; let appearance: IStorageData; export const updateSidebarParameters = (updateSidebar = false) => { - const fontSize = parseInt(document.documentElement.style.fontSize || '18'); - const sidebarDefaultExpandedSizeOld = sidebarDefaultExpandedSize; - const sidebarMinSizeOld = sidebarMinSize; - sidebarMinSize = fontSize * 4; - sidebarMinSnap = 180 + fontSize * 4; - sidebarDefaultExpandedSize = 200 + fontSize * 4; - if (!updateSidebar) return; + const fontSize = Number.parseInt(document.documentElement.style.fontSize || "18"); + const sidebarDefaultExpandedSizeOld = sidebarDefaultExpandedSize; + const sidebarMinSizeOld = sidebarMinSize; + sidebarMinSize = fontSize * 4; + sidebarMinSnap = 180 + fontSize * 4; + sidebarDefaultExpandedSize = 200 + fontSize * 4; + if (!updateSidebar) return; - let size = parseInt(appearance.expandedSidebarWidth); - if (sidebar.offsetWidth !== sidebarMinSizeOld) size = sidebar.offsetWidth; - else size ||= sidebarDefaultExpandedSizeOld; - size = (size / sidebarDefaultExpandedSizeOld) * sidebarDefaultExpandedSize; + let size = Number.parseInt(appearance.expandedSidebarWidth); + if (sidebar.offsetWidth !== sidebarMinSizeOld) size = sidebar.offsetWidth; + else size ||= sidebarDefaultExpandedSizeOld; + size = (size / sidebarDefaultExpandedSizeOld) * sidebarDefaultExpandedSize; - const minimized = size < sidebarMinSnap || appearance.preferMinimizedSidebar; - resizeSidebar((minimized ? sidebarMinSize : size) + 'px'); - appearance.expandedSidebarWidth = Math.max(size, sidebarMinSnap) + 'px'; - Storage.set('appearance', appearance); + const minimized = size < sidebarMinSnap || appearance.preferMinimizedSidebar; + resizeSidebar((minimized ? sidebarMinSize : size) + "px"); + appearance.expandedSidebarWidth = Math.max(size, sidebarMinSnap) + "px"; + Storage.set("appearance", appearance); }; -export const resizeSidebar = function (size?: string) { - if (!size) { - if (sidebar.offsetWidth === sidebarMinSize) { - const defaultSidebarWidth = sidebarDefaultExpandedSize + 'px'; - size = appearance.expandedSidebarWidth || defaultSidebarWidth; - appearance.preferMinimizedSidebar = false; - } else { - size = sidebarMinSize + 'px'; - appearance.preferMinimizedSidebar = true; - } - Storage.set('appearance', appearance); - } - const root = document.documentElement; - if (size === sidebarMinSize + 'px') { - sidebar.classList.add('sidebar-minimized'); - settingsSidebar.classList.add('sidebar-minimized'); - root.style.setProperty('--sidebar-minimized-width', size); - } else { - sidebar.classList.remove('sidebar-minimized'); - settingsSidebar.classList.remove('sidebar-minimized'); - root.style.setProperty('--sidebar-minimized-width', '0px'); - } - appearance.sidebarWidth = size; - if (sidebar.animate && !matchMedia('(prefers-reduced-motion)').matches) { - const animateOptions = { duration: 100, fill: 'forwards' } as const; - sidebar.animate({ width: size }, animateOptions); - settingsSidebar.animate({ width: size }, animateOptions); - } else sidebar.style.width = settingsSidebar.style.width = size; +export const resizeSidebar = (size?: string) => { + if (!size) { + if (sidebar.offsetWidth === sidebarMinSize) { + const defaultSidebarWidth = sidebarDefaultExpandedSize + "px"; + size = appearance.expandedSidebarWidth || defaultSidebarWidth; + appearance.preferMinimizedSidebar = false; + } else { + size = sidebarMinSize + "px"; + appearance.preferMinimizedSidebar = true; + } + Storage.set("appearance", appearance); + } + const root = document.documentElement; + if (size === sidebarMinSize + "px") { + sidebar.classList.add("sidebar-minimized"); + settingsSidebar.classList.add("sidebar-minimized"); + root.style.setProperty("--sidebar-minimized-width", size); + } else { + sidebar.classList.remove("sidebar-minimized"); + settingsSidebar.classList.remove("sidebar-minimized"); + root.style.setProperty("--sidebar-minimized-width", "0px"); + } + appearance.sidebarWidth = size; + if (sidebar.animate && !matchMedia("(prefers-reduced-motion)").matches) { + const animateOptions = { duration: 100, fill: "forwards" } as const; + sidebar.animate({ width: size }, animateOptions); + settingsSidebar.animate({ width: size }, animateOptions); + } else sidebar.style.width = settingsSidebar.style.width = size; }; export const Resizer = async (): Promise => { - sidebar = document.querySelector('.sidebar'); - settingsSidebar = document.querySelector('.settings-sidebar'); - appearance = (await Storage.get('appearance')) || {}; - updateSidebarParameters(); - const defaultSidebarWidth = sidebarDefaultExpandedSize + 'px'; - resizeSidebar(appearance.sidebarWidth || defaultSidebarWidth); + sidebar = document.querySelector(".sidebar"); + settingsSidebar = document.querySelector(".settings-sidebar"); + appearance = (await Storage.get("appearance")) || {}; + updateSidebarParameters(); + const defaultSidebarWidth = sidebarDefaultExpandedSize + "px"; + resizeSidebar(appearance.sidebarWidth || defaultSidebarWidth); - const resizeWindow = () => { - if (window.innerWidth < windowMinSize) resizeSidebar(sidebarMinSize + 'px'); - else if (!appearance.preferMinimizedSidebar) { - resizeSidebar(appearance.expandedSidebarWidth || defaultSidebarWidth); - } - }; - resizeWindow(); - window.addEventListener('resize', resizeWindow); + const resizeWindow = () => { + if (window.innerWidth < windowMinSize) resizeSidebar(sidebarMinSize + "px"); + else if (!appearance.preferMinimizedSidebar) { + resizeSidebar(appearance.expandedSidebarWidth || defaultSidebarWidth); + } + }; + resizeWindow(); + window.addEventListener("resize", resizeWindow); - let resizing = false; + let resizing = false; - document.addEventListener('mouseup', () => (resizing = false)); + document.addEventListener("mouseup", () => (resizing = false)); - document.addEventListener('mousedown', ({ clientX: mx }) => { - const { offsetWidth: w } = sidebar; - resizing = Math.abs(w - mx) < sidebarEdgeSensor; - }); + document.addEventListener("mousedown", ({ clientX: mx }) => { + const { offsetWidth: w } = sidebar; + resizing = Math.abs(w - mx) < sidebarEdgeSensor; + }); - document.addEventListener('mousemove', (event) => { - type MouseMoveEvent = MouseEvent & { target: HTMLElement }; - const { clientX: mx, clientY: my, target } = event as MouseMoveEvent; - if (resizing) { - let width = mx + 'px'; - if (mx < sidebarMinSnap) { - width = sidebarMinSize + 'px'; - appearance.preferMinimizedSidebar = true; - } else { - appearance.expandedSidebarWidth = width; - appearance.preferMinimizedSidebar = false; - } - resizeSidebar(width); - Storage.set('appearance', appearance); - } - if (sidebar.classList.contains('sidebar-minimized')) { - const itemClasses = ['favorite-item', 'drive-item']; - if (itemClasses.some((c) => target.classList.contains(c))) { - const sidebarText = target.querySelector('.sidebar-text'); - const { offsetTop: y, offsetHeight: h } = sidebarText; - const root = document.documentElement; - root.style.setProperty('--sidebar-text-y', my - y - h / 2 + 'px'); - } - } - const { offsetWidth: w } = sidebar; - if (Math.abs(w - mx) < sidebarEdgeSensor || resizing) { - document.body.classList.add('resize-horizontal'); - } else { - document.body.classList.remove('resize-horizontal'); - } - }); + document.addEventListener("mousemove", (event) => { + type MouseMoveEvent = MouseEvent & { target: HTMLElement }; + const { clientX: mx, clientY: my, target } = event as MouseMoveEvent; + if (resizing) { + let width = mx + "px"; + if (mx < sidebarMinSnap) { + width = sidebarMinSize + "px"; + appearance.preferMinimizedSidebar = true; + } else { + appearance.expandedSidebarWidth = width; + appearance.preferMinimizedSidebar = false; + } + resizeSidebar(width); + Storage.set("appearance", appearance); + } + if (sidebar.classList.contains("sidebar-minimized")) { + const itemClasses = ["favorite-item", "drive-item"]; + if (itemClasses.some((c) => target.classList.contains(c))) { + const sidebarText = target.querySelector(".sidebar-text"); + const { offsetTop: y, offsetHeight: h } = sidebarText; + const root = document.documentElement; + root.style.setProperty("--sidebar-text-y", my - y - h / 2 + "px"); + } + } + const { offsetWidth: w } = sidebar; + if (Math.abs(w - mx) < sidebarEdgeSensor || resizing) { + document.body.classList.add("resize-horizontal"); + } else { + document.body.classList.remove("resize-horizontal"); + } + }); }; diff --git a/src/Components/Layout/sidebar.ts b/src/Components/Layout/sidebar.ts index b271952e..9229ec9c 100644 --- a/src/Components/Layout/sidebar.ts +++ b/src/Components/Layout/sidebar.ts @@ -1,24 +1,24 @@ -import { writeSidebarDriveItems as writeDriveItems } from '../Drives/drives'; -import { updateTheme } from '../Theme/theme'; -import fileThumbnail from '../Thumbnail/thumbnail'; -import Translate from '../I18n/i18n'; -import FavoritesAPI from '../../Service/favorites'; -import DirectoryAPI from '../../Service/directory'; -import Storage from '../../Service/storage'; -import IsValid from '../Functions/validChecker'; -import defaultFavorites from '../Favorites/defaultFavorites'; -import FileAPI from '../../Service/files'; +import DirectoryAPI from "../../Service/directory"; +import FavoritesAPI from "../../Service/favorites"; +import FileAPI from "../../Service/files"; +import Storage from "../../Service/storage"; +import { writeSidebarDriveItems as writeDriveItems } from "../Drives/drives"; +import defaultFavorites from "../Favorites/defaultFavorites"; +import IsValid from "../Functions/validChecker"; +import Translate from "../I18n/i18n"; +import { updateTheme } from "../Theme/theme"; +import fileThumbnail from "../Thumbnail/thumbnail"; interface Favorites { - name: string; - path: string; + name: string; + path: string; } let FavoritesData: FavoritesAPI; let _defaultFavorites: Favorites[] = []; const isDefaultFavorite = async (filePath: string) => { - if (!IsValid(_defaultFavorites)) _defaultFavorites = await defaultFavorites(); - return _defaultFavorites.some((favorite) => favorite.path === filePath); + if (!IsValid(_defaultFavorites)) _defaultFavorites = await defaultFavorites(); + return _defaultFavorites.some((favorite) => favorite.path === filePath); }; /** @@ -27,37 +27,37 @@ const isDefaultFavorite = async (filePath: string) => { * @returns {Promise} */ const writeFavoriteItems = async (favorites: Favorites[]): Promise => { - const sidebarCollapseClass = 'sidebar-nav-dropdown-collapsed'; - const sidebar = await Storage.get('sidebar'); - let content = ''; - for (const favorite of favorites) { - if (!favorite.path) continue; - const exists = await new FileAPI(favorite.path).exists(); - const isDefault = await isDefaultFavorite(favorite.path); - const isPseudo = favorite.path.startsWith('xplorer://'); - if (!exists && !isDefault && !isPseudo) continue; - const isdir = isPseudo || (await new DirectoryAPI(favorite.path).isDir()); - const iconPath = exists && !isDefault ? favorite.path : favorite.name; - let iconCategory = 'sidebar'; - if (!isDefault && favorite.path !== 'xplorer://Home') { - iconCategory = isdir ? 'folder' : 'file'; - } - content += - `\n` + - ` \n` + - ` ${await Translate(favorite.name)}\n` + - `\n`; - } - const favoriteElement = document.querySelector('#sidebar-favorites'); - const favoriteBtnText = favoriteElement.querySelector('.sidebar-text'); - const favoriteList = favoriteElement.querySelector('.sidebar-nav-list'); - favoriteBtnText.textContent = await Translate('Favorites'); - favoriteList.innerHTML = content; - if (sidebar?.hideSection?.favorites) { - favoriteElement.classList.add(sidebarCollapseClass); - } + const sidebarCollapseClass = "sidebar-nav-dropdown-collapsed"; + const sidebar = await Storage.get("sidebar"); + let content = ""; + for (const favorite of favorites) { + if (!favorite.path) continue; + const exists = await new FileAPI(favorite.path).exists(); + const isDefault = await isDefaultFavorite(favorite.path); + const isPseudo = favorite.path.startsWith("xplorer://"); + if (!exists && !isDefault && !isPseudo) continue; + const isdir = isPseudo || (await new DirectoryAPI(favorite.path).isDir()); + const iconPath = exists && !isDefault ? favorite.path : favorite.name; + let iconCategory = "sidebar"; + if (!isDefault && favorite.path !== "xplorer://Home") { + iconCategory = isdir ? "folder" : "file"; + } + content += + `\n` + + ` \n` + + ` ${await Translate(favorite.name)}\n` + + `\n`; + } + const favoriteElement = document.querySelector("#sidebar-favorites"); + const favoriteBtnText = favoriteElement.querySelector(".sidebar-text"); + const favoriteList = favoriteElement.querySelector(".sidebar-nav-list"); + favoriteBtnText.textContent = await Translate("Favorites"); + favoriteList.innerHTML = content; + if (sidebar?.hideSection?.favorites) { + favoriteElement.classList.add(sidebarCollapseClass); + } }; /** @@ -65,44 +65,44 @@ const writeFavoriteItems = async (favorites: Favorites[]): Promise => { * @returns {Promise} */ const createSidebar = async (): Promise => { - if (!FavoritesData) { - FavoritesData = new FavoritesAPI(); - await FavoritesData.build(); - } + if (!FavoritesData) { + FavoritesData = new FavoritesAPI(); + await FavoritesData.build(); + } - const favorites = await Storage.get('favorites'); - const _favorites = IsValid(favorites?.favorites) - ? favorites.favorites - : [ - { name: 'Home', path: 'xplorer://Home' }, - { name: 'Recent', path: 'xplorer://Recent' }, - { name: 'Desktop', path: FavoritesData.DESKTOP_PATH }, - { name: 'Documents', path: FavoritesData.DOCUMENT_PATH }, - { name: 'Downloads', path: FavoritesData.DOWNLOAD_PATH }, - { name: 'Pictures', path: FavoritesData.PICTURE_PATH }, - { name: 'Music', path: FavoritesData.MUSIC_PATH }, - { name: 'Videos', path: FavoritesData.VIDEO_PATH }, - { name: 'Trash', path: 'xplorer://Trash' }, // eslint-disable-next-line no-mixed-spaces-and-tabs - ]; - await Promise.all([writeFavoriteItems(_favorites), writeDriveItems()]); - updateTheme('root'); + const favorites = await Storage.get("favorites"); + const _favorites = IsValid(favorites?.favorites) + ? favorites.favorites + : [ + { name: "Home", path: "xplorer://Home" }, + { name: "Recent", path: "xplorer://Recent" }, + { name: "Desktop", path: FavoritesData.DESKTOP_PATH }, + { name: "Documents", path: FavoritesData.DOCUMENT_PATH }, + { name: "Downloads", path: FavoritesData.DOWNLOAD_PATH }, + { name: "Pictures", path: FavoritesData.PICTURE_PATH }, + { name: "Music", path: FavoritesData.MUSIC_PATH }, + { name: "Videos", path: FavoritesData.VIDEO_PATH }, + { name: "Trash", path: "xplorer://Trash" }, // eslint-disable-next-line no-mixed-spaces-and-tabs + ]; + await Promise.all([writeFavoriteItems(_favorites), writeDriveItems()]); + updateTheme("root"); - const settingBtnText = document.querySelector('#sidebar-setting-btn span'); - settingBtnText.textContent = await Translate('Settings'); + const settingBtnText = document.querySelector("#sidebar-setting-btn span"); + settingBtnText.textContent = await Translate("Settings"); - // Collapse section - const sidebarElement = document.querySelector('.sidebar'); - sidebarElement.querySelectorAll('.sidebar-nav-toggle').forEach((btn) => { - btn.addEventListener('click', async ({ target }) => { - const sidebarCollapseClass = 'sidebar-nav-dropdown-collapsed'; - const sidebarNavItem = (target as HTMLElement).parentElement; - sidebarNavItem.classList.toggle(sidebarCollapseClass); - const sidebar = (await Storage.get('sidebar')) || {}; - const collapsed = sidebarNavItem.classList.contains(sidebarCollapseClass); - (sidebar.hideSection ||= {})[sidebarNavItem.dataset.section] = collapsed; - Storage.set('sidebar', sidebar); - }); - }); + // Collapse section + const sidebarElement = document.querySelector(".sidebar"); + sidebarElement.querySelectorAll(".sidebar-nav-toggle").forEach((btn) => { + btn.addEventListener("click", async ({ target }) => { + const sidebarCollapseClass = "sidebar-nav-dropdown-collapsed"; + const sidebarNavItem = (target as HTMLElement).parentElement; + sidebarNavItem.classList.toggle(sidebarCollapseClass); + const sidebar = (await Storage.get("sidebar")) || {}; + const collapsed = sidebarNavItem.classList.contains(sidebarCollapseClass); + (sidebar.hideSection ||= {})[sidebarNavItem.dataset.section] = collapsed; + Storage.set("sidebar", sidebar); + }); + }); }; export default createSidebar; diff --git a/src/Components/Layout/tab.ts b/src/Components/Layout/tab.ts index efcaea2c..3106d131 100644 --- a/src/Components/Layout/tab.ts +++ b/src/Components/Layout/tab.ts @@ -1,17 +1,17 @@ -import { updateTheme } from '../Theme/theme'; -import Storage from '../../Service/storage'; -import Translate from '../I18n/i18n'; -import windowName from '../../Service/window'; -import { OpenDir } from '../Open/open'; -import { close } from './windowManager'; -import basename from '../Functions/path/basename'; -import Home from './home'; -import { GET_WORKSPACE_ELEMENT } from '../../Util/constants'; -import changePosition from '../Functions/changePosition'; +import Storage from "../../Service/storage"; +import windowName from "../../Service/window"; +import { GET_WORKSPACE_ELEMENT } from "../../Util/constants"; +import changePosition from "../Functions/changePosition"; +import basename from "../Functions/path/basename"; +import Translate from "../I18n/i18n"; +import { OpenDir } from "../Open/open"; +import { updateTheme } from "../Theme/theme"; +import Home from "./home"; +import { close } from "./windowManager"; let tabsManager: HTMLElement; -document.addEventListener('DOMContentLoaded', () => { - tabsManager = document.querySelector('.tabs-manager'); +document.addEventListener("DOMContentLoaded", () => { + tabsManager = document.querySelector(".tabs-manager"); }); /** * Function to create new tab @@ -20,54 +20,54 @@ document.addEventListener('DOMContentLoaded', () => { */ const createNewTab = async (path?: string): Promise => { - const createNewTabElement = document.querySelector('.create-new-tab'); - const tabsInfo = await Storage.get(`tabs-${windowName}`); // Fetch latest tabs information - - const newTab = document.createElement('div'); - newTab.classList.add('tab'); - newTab.classList.add('tab-hover-effect'); - newTab.innerHTML = `${await Translate('Home')}×`; - tabsInfo.latestIndex += 1; - newTab.dataset.tabIndex = tabsInfo.latestIndex; - newTab.id = `tab${tabsInfo.latestIndex}`; - - updateTheme('tabbing'); // Update the theme - createNewTabElement.parentElement.insertBefore(newTab, createNewTabElement); // Insert the new tab - (newTab.parentNode as HTMLElement).scrollLeft = window.pageXOffset + newTab.getBoundingClientRect().left + newTab.offsetWidth; // Scroll the tabs scrollbar - - // Scroll the tab to the right end - (newTab.parentNode as HTMLElement).scrollLeft = (newTab.parentNode as HTMLElement).scrollWidth; - - // Edit tabs information - tabsInfo.tabs[String(tabsInfo.latestIndex)] = { - position: path || 'xplorer://Home', - history: ['xplorer://Home'], - currentIndex: -1, - }; - tabsInfo.focus = String(tabsInfo.latestIndex); - tabsInfo.focusHistory.push(tabsInfo.latestIndex); - Storage.set(`tabs-${windowName}`, tabsInfo); - - const newWorkspaceTabElement = document.createElement('div'); - newWorkspaceTabElement.classList.add('workspace-tab'); - newWorkspaceTabElement.id = `tab-1-${tabsInfo.latestIndex}`; - newWorkspaceTabElement.dataset.path = path || 'xplorer://Home'; - GET_WORKSPACE_ELEMENT(1).appendChild(newWorkspaceTabElement); - - document.querySelectorAll('.workspace-tab').forEach((tab: HTMLElement) => { - tab.classList.remove('workspace-tab-active'); - }); - newWorkspaceTabElement.classList.add('workspace-tab-active'); - - OpenDir(path || 'xplorer://Home'); - - newTab.addEventListener('click', (e) => { - if ((e.target as HTMLElement).classList.contains('close-tab-btn')) return; - SwitchTab(newTab.dataset.tabIndex); - }); - if (tabsManager.scrollWidth > tabsManager.clientWidth) tabsManager.removeAttribute('data-tauri-drag-region'); - else tabsManager.setAttribute('data-tauri-drag-region', ''); - return; + const createNewTabElement = document.querySelector(".create-new-tab"); + const tabsInfo = await Storage.get(`tabs-${windowName}`); // Fetch latest tabs information + + const newTab = document.createElement("div"); + newTab.classList.add("tab"); + newTab.classList.add("tab-hover-effect"); + newTab.innerHTML = `${await Translate("Home")}×`; + tabsInfo.latestIndex += 1; + newTab.dataset.tabIndex = tabsInfo.latestIndex; + newTab.id = `tab${tabsInfo.latestIndex}`; + + updateTheme("tabbing"); // Update the theme + createNewTabElement.parentElement.insertBefore(newTab, createNewTabElement); // Insert the new tab + (newTab.parentNode as HTMLElement).scrollLeft = window.pageXOffset + newTab.getBoundingClientRect().left + newTab.offsetWidth; // Scroll the tabs scrollbar + + // Scroll the tab to the right end + (newTab.parentNode as HTMLElement).scrollLeft = (newTab.parentNode as HTMLElement).scrollWidth; + + // Edit tabs information + tabsInfo.tabs[String(tabsInfo.latestIndex)] = { + position: path || "xplorer://Home", + history: ["xplorer://Home"], + currentIndex: -1, + }; + tabsInfo.focus = String(tabsInfo.latestIndex); + tabsInfo.focusHistory.push(tabsInfo.latestIndex); + Storage.set(`tabs-${windowName}`, tabsInfo); + + const newWorkspaceTabElement = document.createElement("div"); + newWorkspaceTabElement.classList.add("workspace-tab"); + newWorkspaceTabElement.id = `tab-1-${tabsInfo.latestIndex}`; + newWorkspaceTabElement.dataset.path = path || "xplorer://Home"; + GET_WORKSPACE_ELEMENT(1).appendChild(newWorkspaceTabElement); + + document.querySelectorAll(".workspace-tab").forEach((tab: HTMLElement) => { + tab.classList.remove("workspace-tab-active"); + }); + newWorkspaceTabElement.classList.add("workspace-tab-active"); + + OpenDir(path || "xplorer://Home"); + + newTab.addEventListener("click", (e) => { + if ((e.target as HTMLElement).classList.contains("close-tab-btn")) return; + SwitchTab(newTab.dataset.tabIndex); + }); + if (tabsManager.scrollWidth > tabsManager.clientWidth) tabsManager.removeAttribute("data-tauri-drag-region"); + else tabsManager.setAttribute("data-tauri-drag-region", ""); + return; }; /** @@ -76,16 +76,16 @@ const createNewTab = async (path?: string): Promise => { * @returns {Promise} */ const SwitchTab = async (tabIndex: number | string): Promise => { - const tabs = await Storage.get(`tabs-${windowName}`); - tabs.focus = String(tabIndex); - tabs.focusHistory.push(parseInt(String(tabIndex))); - tabs.tabs[tabs.focus].currentIndex -= 1; - Storage.set(`tabs-${windowName}`, tabs); - document.querySelectorAll('.workspace-tab').forEach((tab: HTMLElement) => { - tab.classList.remove('workspace-tab-active'); - }); - document.getElementById(`tab-1-${tabIndex}`).classList.add('workspace-tab-active'); - changePosition(tabs.tabs[tabs.focus].position); + const tabs = await Storage.get(`tabs-${windowName}`); + tabs.focus = String(tabIndex); + tabs.focusHistory.push(Number.parseInt(String(tabIndex))); + tabs.tabs[tabs.focus].currentIndex -= 1; + Storage.set(`tabs-${windowName}`, tabs); + document.querySelectorAll(".workspace-tab").forEach((tab: HTMLElement) => { + tab.classList.remove("workspace-tab-active"); + }); + document.getElementById(`tab-1-${tabIndex}`).classList.add("workspace-tab-active"); + changePosition(tabs.tabs[tabs.focus].position); }; /** @@ -93,11 +93,11 @@ const SwitchTab = async (tabIndex: number | string): Promise => { * @returns {Promise} */ const goBack = async (): Promise => { - const tabs = await Storage.get(`tabs-${windowName}`); - const _focusingTab = tabs.tabs[tabs.focus]; - if (_focusingTab.currentIndex > 0) { - OpenDir(_focusingTab.history[_focusingTab.currentIndex - 1]); - } + const tabs = await Storage.get(`tabs-${windowName}`); + const _focusingTab = tabs.tabs[tabs.focus]; + if (_focusingTab.currentIndex > 0) { + OpenDir(_focusingTab.history[_focusingTab.currentIndex - 1]); + } }; /** @@ -105,11 +105,11 @@ const goBack = async (): Promise => { * @returns {Promise} */ const goForward = async (): Promise => { - const tabs = await Storage.get(`tabs-${windowName}`); - const _focusingTab = tabs.tabs[tabs.focus]; - if (_focusingTab.currentIndex >= 0 && _focusingTab.history?.[_focusingTab.currentIndex + 1]) { - OpenDir(_focusingTab.history[_focusingTab.currentIndex + 1]); - } + const tabs = await Storage.get(`tabs-${windowName}`); + const _focusingTab = tabs.tabs[tabs.focus]; + if (_focusingTab.currentIndex >= 0 && _focusingTab.history?.[_focusingTab.currentIndex + 1]) { + OpenDir(_focusingTab.history[_focusingTab.currentIndex + 1]); + } }; /** * Tab initiliazer function @@ -117,135 +117,135 @@ const goForward = async (): Promise => { * @returns {Promise} */ const Tab = async (reveal = false): Promise => { - const _preference = await Storage.get('preference'); - const defaultTabsInfo = { - focus: '1', - tabs: { - 1: { - position: 'xplorer://Home', - history: ['xplorer://Home'], - currentIndex: 0, - }, - }, - focusHistory: [1], - latestIndex: 1, - }; // default tabs information - if ((_preference?.on_startup ?? 'new') === 'new') { - // Store default tabs information into local storage - Storage.set(`tabs-${windowName}`, defaultTabsInfo); - tabsManager.setAttribute('data-tauri-drag-region', ''); - } else { - const tabsInfo = await Storage.get(`tabs-${windowName}`); - if (!tabsInfo.tabs || reveal) { - Storage.set(`tabs-${windowName}`, defaultTabsInfo); - tabsManager.setAttribute('data-tauri-drag-region', ''); - Home(); - } else { - let _first = true; - const createNewTabElement = document.querySelector('.create-new-tab'); - for (const index in Object.keys(tabsInfo.tabs)) { - if (_first) { - const tabIndex = Object.keys(tabsInfo.tabs)[index]; - const tabPosition = tabsInfo.tabs[tabIndex].position; - if (Object.keys(tabsInfo.tabs).length > 1) { - document.querySelector('#tab1').id = `tab${tabIndex}`; - document.querySelector('#tab-1-1').id = `tab-1-${Object.keys(tabsInfo.tabs)[index]}`; - } else { - document.querySelector('#tab1').id = `tab${Object.keys(tabsInfo.tabs)[index]}`; - document.querySelector('#tab-1-1').id = `tab-1-${Object.keys(tabsInfo.tabs)[index]}`; - } - document.getElementById(`tab${tabIndex}`).querySelector('#tab-position').innerText = await Translate( - basename(tabPosition) === '' ? tabPosition : basename(tabPosition) - ); - await OpenDir(tabsInfo.tabs[Object.keys(tabsInfo.tabs)[index]].position, false, true, false); - _first = false; - } else { - const tabIndex = Object.keys(tabsInfo.tabs)[index]; - const tabPosition = tabsInfo.tabs[tabIndex].position; - const newTab = document.createElement('div'); - newTab.classList.add('tab'); - newTab.classList.add('tab-hover-effect'); - newTab.innerHTML = `${await Translate('Home')}×`; - newTab.dataset.tabIndex = tabIndex; - newTab.id = `tab${tabIndex}`; - - createNewTabElement.parentElement.insertBefore(newTab, createNewTabElement); // Insert the new tab - document.getElementById(`tab${tabIndex}`).querySelector('#tab-position').innerText = await Translate( - basename(tabPosition) === '' ? tabPosition : basename(tabPosition) - ); - const newWorkspaceTabElement = document.createElement('div'); - newWorkspaceTabElement.classList.add('workspace-tab'); - newWorkspaceTabElement.id = `tab-1-${tabIndex}`; - newWorkspaceTabElement.dataset.path = tabPosition || 'xplorer://Home'; - GET_WORKSPACE_ELEMENT(1).appendChild(newWorkspaceTabElement); - - document.querySelectorAll('.workspace-tab').forEach((tab: HTMLElement) => { - tab.classList.remove('workspace-tab-active'); - }); - newWorkspaceTabElement.classList.add('workspace-tab-active'); - await OpenDir(tabPosition || 'xplorer://Home', false, true, false); - } - } - } - } - updateTheme('tabbing'); // Update the theme - - const arrayOfTabs = document.querySelectorAll('.tab'); - // Add close tab button - for (let index = 0; index < arrayOfTabs.length; index++) { - const tab = arrayOfTabs[index]; - const closeTab = document.createElement('span'); - closeTab.innerHTML = '×'; - closeTab.title = await Translate('Close Tab'); - tab.dataset.tabIndex = String(parseInt(tab.id.replace('tab', ''))) || '1'; - closeTab.classList.add('close-tab-btn'); - tab.appendChild(closeTab); - - tab.querySelector('#tab-position').innerText = await Translate(tab.querySelector('#tab-position').innerText); - - tab.addEventListener('click', (e) => { - if ((e.target as HTMLElement).classList.contains('close-tab-btn')) return; - SwitchTab(String(parseInt(tab.id.replace('tab', ''))) || '1'); - }); - } - - document.addEventListener('click', async (e) => { - if ((e.target as HTMLElement).classList.contains('close-tab-btn')) { - e.stopPropagation(); - // Close the window if user close the only tab - if (document.querySelectorAll('.tab').length === 1) { - Storage.remove(`tabs-${windowName}`); - close(); - } else { - const tab = (e.target as HTMLElement).parentNode as HTMLElement; - const index = parseInt(tab.dataset.tabIndex); - tab.parentElement.removeChild(tab); - const tabs = await Storage.get(`tabs-${windowName}`); - tabs.focusHistory = tabs.focusHistory.filter((tabIndex: number) => tabIndex !== index); - tabs.focus = String(tabs.focusHistory[tabs.focusHistory.length - 1]); - delete tabs.tabs[index]; - Storage.set(`tabs-${windowName}`, tabs); - OpenDir(tabs.tabs[tabs.focus].position); - if (tabsManager.scrollWidth > tabsManager.clientWidth) tabsManager.removeAttribute('data-tauri-drag-region'); - else tabsManager.setAttribute('data-tauri-drag-region', ''); - } - } - }); - - const createNewTabElement = document.querySelector('.create-new-tab'); - - // Create a new tab event - createNewTabElement.addEventListener('click', () => createNewTab()); - - // Scroll the tabs - document.querySelector('.tabs-manager').addEventListener('wheel', (e) => { - (e as WheelEvent).deltaY > 0 - ? (document.querySelector('.tabs-manager').scrollLeft += 25) - : (document.querySelector('.tabs-manager').scrollLeft -= 25); - }); - - document.getElementById('go-back').addEventListener('click', () => goBack()); - document.getElementById('go-forward').addEventListener('click', () => goForward()); + const _preference = await Storage.get("preference"); + const defaultTabsInfo = { + focus: "1", + tabs: { + 1: { + position: "xplorer://Home", + history: ["xplorer://Home"], + currentIndex: 0, + }, + }, + focusHistory: [1], + latestIndex: 1, + }; // default tabs information + if ((_preference?.on_startup ?? "new") === "new") { + // Store default tabs information into local storage + Storage.set(`tabs-${windowName}`, defaultTabsInfo); + tabsManager.setAttribute("data-tauri-drag-region", ""); + } else { + const tabsInfo = await Storage.get(`tabs-${windowName}`); + if (!tabsInfo.tabs || reveal) { + Storage.set(`tabs-${windowName}`, defaultTabsInfo); + tabsManager.setAttribute("data-tauri-drag-region", ""); + Home(); + } else { + let _first = true; + const createNewTabElement = document.querySelector(".create-new-tab"); + for (const index in Object.keys(tabsInfo.tabs)) { + if (_first) { + const tabIndex = Object.keys(tabsInfo.tabs)[index]; + const tabPosition = tabsInfo.tabs[tabIndex].position; + if (Object.keys(tabsInfo.tabs).length > 1) { + document.querySelector("#tab1").id = `tab${tabIndex}`; + document.querySelector("#tab-1-1").id = `tab-1-${Object.keys(tabsInfo.tabs)[index]}`; + } else { + document.querySelector("#tab1").id = `tab${Object.keys(tabsInfo.tabs)[index]}`; + document.querySelector("#tab-1-1").id = `tab-1-${Object.keys(tabsInfo.tabs)[index]}`; + } + document.getElementById(`tab${tabIndex}`).querySelector("#tab-position").innerText = await Translate( + basename(tabPosition) === "" ? tabPosition : basename(tabPosition), + ); + await OpenDir(tabsInfo.tabs[Object.keys(tabsInfo.tabs)[index]].position, false, true, false); + _first = false; + } else { + const tabIndex = Object.keys(tabsInfo.tabs)[index]; + const tabPosition = tabsInfo.tabs[tabIndex].position; + const newTab = document.createElement("div"); + newTab.classList.add("tab"); + newTab.classList.add("tab-hover-effect"); + newTab.innerHTML = `${await Translate("Home")}×`; + newTab.dataset.tabIndex = tabIndex; + newTab.id = `tab${tabIndex}`; + + createNewTabElement.parentElement.insertBefore(newTab, createNewTabElement); // Insert the new tab + document.getElementById(`tab${tabIndex}`).querySelector("#tab-position").innerText = await Translate( + basename(tabPosition) === "" ? tabPosition : basename(tabPosition), + ); + const newWorkspaceTabElement = document.createElement("div"); + newWorkspaceTabElement.classList.add("workspace-tab"); + newWorkspaceTabElement.id = `tab-1-${tabIndex}`; + newWorkspaceTabElement.dataset.path = tabPosition || "xplorer://Home"; + GET_WORKSPACE_ELEMENT(1).appendChild(newWorkspaceTabElement); + + document.querySelectorAll(".workspace-tab").forEach((tab: HTMLElement) => { + tab.classList.remove("workspace-tab-active"); + }); + newWorkspaceTabElement.classList.add("workspace-tab-active"); + await OpenDir(tabPosition || "xplorer://Home", false, true, false); + } + } + } + } + updateTheme("tabbing"); // Update the theme + + const arrayOfTabs = document.querySelectorAll(".tab"); + // Add close tab button + for (let index = 0; index < arrayOfTabs.length; index++) { + const tab = arrayOfTabs[index]; + const closeTab = document.createElement("span"); + closeTab.innerHTML = "×"; + closeTab.title = await Translate("Close Tab"); + tab.dataset.tabIndex = String(Number.parseInt(tab.id.replace("tab", ""))) || "1"; + closeTab.classList.add("close-tab-btn"); + tab.appendChild(closeTab); + + tab.querySelector("#tab-position").innerText = await Translate(tab.querySelector("#tab-position").innerText); + + tab.addEventListener("click", (e) => { + if ((e.target as HTMLElement).classList.contains("close-tab-btn")) return; + SwitchTab(String(Number.parseInt(tab.id.replace("tab", ""))) || "1"); + }); + } + + document.addEventListener("click", async (e) => { + if ((e.target as HTMLElement).classList.contains("close-tab-btn")) { + e.stopPropagation(); + // Close the window if user close the only tab + if (document.querySelectorAll(".tab").length === 1) { + Storage.remove(`tabs-${windowName}`); + close(); + } else { + const tab = (e.target as HTMLElement).parentNode as HTMLElement; + const index = Number.parseInt(tab.dataset.tabIndex); + tab.parentElement.removeChild(tab); + const tabs = await Storage.get(`tabs-${windowName}`); + tabs.focusHistory = tabs.focusHistory.filter((tabIndex: number) => tabIndex !== index); + tabs.focus = String(tabs.focusHistory[tabs.focusHistory.length - 1]); + delete tabs.tabs[index]; + Storage.set(`tabs-${windowName}`, tabs); + OpenDir(tabs.tabs[tabs.focus].position); + if (tabsManager.scrollWidth > tabsManager.clientWidth) tabsManager.removeAttribute("data-tauri-drag-region"); + else tabsManager.setAttribute("data-tauri-drag-region", ""); + } + } + }); + + const createNewTabElement = document.querySelector(".create-new-tab"); + + // Create a new tab event + createNewTabElement.addEventListener("click", () => createNewTab()); + + // Scroll the tabs + document.querySelector(".tabs-manager").addEventListener("wheel", (e) => { + (e as WheelEvent).deltaY > 0 + ? (document.querySelector(".tabs-manager").scrollLeft += 25) + : (document.querySelector(".tabs-manager").scrollLeft -= 25); + }); + + document.getElementById("go-back").addEventListener("click", () => goBack()); + document.getElementById("go-forward").addEventListener("click", () => goForward()); }; export { Tab, createNewTab, goBack, goForward }; diff --git a/src/Components/Layout/windowManager.ts b/src/Components/Layout/windowManager.ts index 44c555ed..effdca9a 100644 --- a/src/Components/Layout/windowManager.ts +++ b/src/Components/Layout/windowManager.ts @@ -1,21 +1,21 @@ -import Translate from '../I18n/i18n'; -import Storage from '../../Service/storage'; -import windowName, { listenWindowClose, setDecorations } from '../../Service/window'; -import { OpenDir } from '../Open/open'; -import focusingPath from '../Functions/focusingPath'; -import getDirname from '../Functions/path/dirname'; -import createSidebar from './sidebar'; -import isTauri from '../../Util/is-tauri'; +import Storage from "../../Service/storage"; +import windowName, { listenWindowClose, setDecorations } from "../../Service/window"; +import isTauri from "../../Util/is-tauri"; +import focusingPath from "../Functions/focusingPath"; +import getDirname from "../Functions/path/dirname"; +import Translate from "../I18n/i18n"; +import { OpenDir } from "../Open/open"; +import createSidebar from "./sidebar"; /** * Reload the page * @returns {Promise} */ const reload = async (): Promise => { - const tabs = await Storage.get(`tabs-${windowName}`); - OpenDir(tabs.tabs[tabs.focus].position); - //closePreviewFile(); - document.querySelector('.properties').style.animation = 'close-properties 1s forwards'; - createSidebar(); + const tabs = await Storage.get(`tabs-${windowName}`); + OpenDir(tabs.tabs[tabs.focus].position); + //closePreviewFile(); + document.querySelector(".properties").style.animation = "close-properties 1s forwards"; + createSidebar(); }; /** @@ -23,10 +23,10 @@ const reload = async (): Promise => { * @returns {void} */ const minimize = (): void => { - if (isTauri) { - const { appWindow } = require('@tauri-apps/api/window'); - appWindow.minimize(); - } + if (isTauri) { + const { appWindow } = require("@tauri-apps/api/window"); + appWindow.minimize(); + } }; /** @@ -34,11 +34,11 @@ const minimize = (): void => { * @returns {Promise} */ const maximize = async (): Promise => { - if (isTauri) { - const { appWindow } = require('@tauri-apps/api/window'); - if (await appWindow.isMaximized()) appWindow.unmaximize(); - else appWindow.maximize(); - } + if (isTauri) { + const { appWindow } = require("@tauri-apps/api/window"); + if (await appWindow.isMaximized()) appWindow.unmaximize(); + else appWindow.maximize(); + } }; /** @@ -46,10 +46,10 @@ const maximize = async (): Promise => { * @returns {any} */ const close = (): void => { - if (isTauri) { - const { appWindow } = require('@tauri-apps/api/window'); - appWindow.close(); - } + if (isTauri) { + const { appWindow } = require("@tauri-apps/api/window"); + appWindow.close(); + } }; /** @@ -57,9 +57,9 @@ const close = (): void => { * @returns {Promise} */ const goParentDir = async (): Promise => { - const dirName = getDirname(await focusingPath()); - if (dirName && !dirName.startsWith('xplorer://')) OpenDir(getDirname(await focusingPath())); - else OpenDir('xplorer://Home'); + const dirName = getDirname(await focusingPath()); + if (dirName && !dirName.startsWith("xplorer://")) OpenDir(getDirname(await focusingPath())); + else OpenDir("xplorer://Home"); }; /** @@ -67,39 +67,39 @@ const goParentDir = async (): Promise => { * @returns {Promise} */ const windowManager = async (): Promise => { - const appearance = await Storage.get('appearance'); - if (appearance?.frameStyle === 'os' || !isTauri) { - document.querySelector('.window-manager').parentNode.removeChild(document.querySelector('.window-manager')); - } - setDecorations(appearance?.frameStyle !== 'default'); - // Minimize the screen - document.querySelector('#minimize')?.addEventListener('click', minimize); - document.querySelector('#minimize')?.setAttribute('title', await Translate('Minimize')); - // Maximize the screen - document.querySelector('#maximize')?.addEventListener('click', maximize); - document.querySelector('#maximize')?.setAttribute('title', await Translate('Maximize')); - // Exit window - document.querySelector('#exit')?.addEventListener('click', close); - document.querySelector('#exit')?.setAttribute('title', await Translate('Exit (Ctrl + w)')); + const appearance = await Storage.get("appearance"); + if (appearance?.frameStyle === "os" || !isTauri) { + document.querySelector(".window-manager").parentNode.removeChild(document.querySelector(".window-manager")); + } + setDecorations(appearance?.frameStyle !== "default"); + // Minimize the screen + document.querySelector("#minimize")?.addEventListener("click", minimize); + document.querySelector("#minimize")?.setAttribute("title", await Translate("Minimize")); + // Maximize the screen + document.querySelector("#maximize")?.addEventListener("click", maximize); + document.querySelector("#maximize")?.setAttribute("title", await Translate("Maximize")); + // Exit window + document.querySelector("#exit")?.addEventListener("click", close); + document.querySelector("#exit")?.setAttribute("title", await Translate("Exit (Ctrl + w)")); - // Refresh the page - document.querySelector('#refresh').addEventListener('click', reload); - document.querySelector('#refresh')?.setAttribute('title', await Translate('Reload (f5)')); + // Refresh the page + document.querySelector("#refresh").addEventListener("click", reload); + document.querySelector("#refresh")?.setAttribute("title", await Translate("Reload (f5)")); - document.querySelector('#go-parent-dir').addEventListener('click', goParentDir); - document.querySelector('#go-parent-dir')?.setAttribute('title', await Translate('Parent Directory (Alt + Up Arrow)')); - document.querySelector('#go-back')?.setAttribute('title', await Translate('Go Back (Alt + Left Arrow)')); - document.querySelector('#go-forward')?.setAttribute('title', await Translate('Go Forward (Alt + Right Arrow)')); + document.querySelector("#go-parent-dir").addEventListener("click", goParentDir); + document.querySelector("#go-parent-dir")?.setAttribute("title", await Translate("Parent Directory (Alt + Up Arrow)")); + document.querySelector("#go-back")?.setAttribute("title", await Translate("Go Back (Alt + Left Arrow)")); + document.querySelector("#go-forward")?.setAttribute("title", await Translate("Go Forward (Alt + Right Arrow)")); - document.querySelector('.path-navigator').addEventListener('change', (event: Event & { target: HTMLInputElement }) => { - OpenDir(event.target.value); - }); - const _preference = await Storage.get('preference'); - listenWindowClose().then(() => { - if (_preference?.on_startup === 'new') Storage.remove(`tabs-${windowName}`); - Storage.remove(`operations-${windowName}`); - Storage.remove('clipboard'); - }); + document.querySelector(".path-navigator").addEventListener("change", (event: Event & { target: HTMLInputElement }) => { + OpenDir(event.target.value); + }); + const _preference = await Storage.get("preference"); + listenWindowClose().then(() => { + if (_preference?.on_startup === "new") Storage.remove(`tabs-${windowName}`); + Storage.remove(`operations-${windowName}`); + Storage.remove("clipboard"); + }); }; export { windowManager, reload, minimize, maximize, close }; diff --git a/src/Components/LoadingBar/index.tsx b/src/Components/LoadingBar/index.tsx index 02441445..cb24124a 100644 --- a/src/Components/LoadingBar/index.tsx +++ b/src/Components/LoadingBar/index.tsx @@ -1,13 +1,13 @@ -import React from 'react'; +import React from "react"; export interface ILoadingBarProps { - isLoading: boolean + isLoading: boolean; } const LoadingBar = ({ isLoading }: ILoadingBarProps) => ( -
- -
+
+ +
); export default LoadingBar; diff --git a/src/Components/MainView/index.tsx b/src/Components/MainView/index.tsx index a0ee31b6..2b6009fa 100644 --- a/src/Components/MainView/index.tsx +++ b/src/Components/MainView/index.tsx @@ -4,8 +4,8 @@ import { useSelector } from "react-redux"; import File from "../File"; import Preview from "../Preview"; -import { IAppState } from "../../Store/Reducers"; -import { IFile } from "../../Typings/Store/files"; +import type { IAppState } from "../../Store/Reducers"; +import type { IFile } from "../../Typings/Store/files"; import { ThemedDiv } from "../Theme"; export interface IMainViewProps { diff --git a/src/Components/Open/defaultSort.ts b/src/Components/Open/defaultSort.ts index 96a2b336..215e3aee 100644 --- a/src/Components/Open/defaultSort.ts +++ b/src/Components/Open/defaultSort.ts @@ -1,31 +1,31 @@ -import FavoritesAPI from '../../Service/favorites'; +import FavoritesAPI from "../../Service/favorites"; let favoritesData: FavoritesAPI; /** * Check for default sort algorithm for a given directory * @param {string} dir - directory to check * @returns {Promise<'A'|'Z'|'L'|'F'|'S'|'T'>} */ -const getDefaultSort = async (dir: string): Promise<'A' | 'Z' | 'L' | 'F' | 'S' | 'T'> => { - if (!favoritesData) { - favoritesData = new FavoritesAPI(); - await favoritesData.build(); - } - switch (dir) { - case favoritesData.DOCUMENT_PATH: - return 'L'; - case favoritesData.PICTURE_PATH: - return 'L'; - case favoritesData.VIDEO_PATH: - return 'L'; - case favoritesData.DESKTOP_PATH: - return 'A'; - case favoritesData.DOWNLOAD_PATH: - return 'L'; - case favoritesData.MUSIC_PATH: - return 'A'; - default: - return null; - } +const getDefaultSort = async (dir: string): Promise<"A" | "Z" | "L" | "F" | "S" | "T"> => { + if (!favoritesData) { + favoritesData = new FavoritesAPI(); + await favoritesData.build(); + } + switch (dir) { + case favoritesData.DOCUMENT_PATH: + return "L"; + case favoritesData.PICTURE_PATH: + return "L"; + case favoritesData.VIDEO_PATH: + return "L"; + case favoritesData.DESKTOP_PATH: + return "A"; + case favoritesData.DOWNLOAD_PATH: + return "L"; + case favoritesData.MUSIC_PATH: + return "A"; + default: + return null; + } }; export default getDefaultSort; diff --git a/src/Components/Open/displayFiles.ts b/src/Components/Open/displayFiles.ts index cf86ad62..ede2eb0a 100644 --- a/src/Components/Open/displayFiles.ts +++ b/src/Components/Open/displayFiles.ts @@ -1,12 +1,12 @@ -import Storage from '../../Service/storage'; -import fileThumbnail from '../Thumbnail/thumbnail'; -import formatBytes from '../Functions/filesize'; -import type FileMetaData from '../../Typings/fileMetaData'; -import { Select } from '../Files/File Operation/select'; -import normalizeSlash from '../Functions/path/normalizeSlash'; -import joinPath from '../Functions/path/joinPath'; -import getDefaultSort from './defaultSort'; -import { LnkData } from '../../Typings/fileMetaData'; +import Storage from "../../Service/storage"; +import type FileMetaData from "../../Typings/fileMetaData"; +import type { LnkData } from "../../Typings/fileMetaData"; +import { Select } from "../Files/File Operation/select"; +import formatBytes from "../Functions/filesize"; +import joinPath from "../Functions/path/joinPath"; +import normalizeSlash from "../Functions/path/normalizeSlash"; +import fileThumbnail from "../Thumbnail/thumbnail"; +import getDefaultSort from "./defaultSort"; /** * Display files into Xplorer main section * @param {fileData[]} files - array of files of a directory @@ -19,145 +19,144 @@ import { LnkData } from '../../Typings/fileMetaData'; * @returns {Promise} */ const displayFiles = async ( - files: FileMetaData[], - dir: string, - onElement?: HTMLElement, - options?: { reveal: boolean; revealDir: string }, - isSearch?: boolean, - lnk_files?: LnkData[] + files: FileMetaData[], + dir: string, + onElement?: HTMLElement, + options?: { reveal: boolean; revealDir: string }, + isSearch?: boolean, + lnk_files?: LnkData[], ): Promise => { - const FilesElement = onElement ?? document.createElement('div'); - const preference = await Storage.get('preference'); - const appearance = await Storage.get('appearance'); - const dirAlongsideFiles = preference?.dirAlongsideFiles ?? false; - const layout = (await Storage.get('layout'))?.[dir] ?? appearance?.layout ?? 'd'; - const sort = (await Storage.get('sort'))?.[dir] ?? (await getDefaultSort(dir)); - switch (sort) { - case 'L': // Last Modified - files.sort((a, b) => { - return new Date(a.last_modified?.secs_since_epoch ?? a.time_deleted) < new Date(b.last_modified?.secs_since_epoch ?? b.time_deleted) - ? 1 - : -1; - }); - break; - case 'F': // First Modified - files.sort((a, b) => { - return new Date(a.last_modified?.secs_since_epoch ?? a.time_deleted) > new Date(b.last_modified?.secs_since_epoch ?? b.time_deleted) - ? 1 - : -1; - }); - break; - case 'S': // Size - files.sort((a, b) => a.size - b.size); - break; - case 'T': // Filetype - files.sort((a, b) => (a.file_type > b.file_type ? 1 : -1)); - break; + const FilesElement = onElement ?? document.createElement("div"); + const preference = await Storage.get("preference"); + const appearance = await Storage.get("appearance"); + const dirAlongsideFiles = preference?.dirAlongsideFiles ?? false; + const layout = (await Storage.get("layout"))?.[dir] ?? appearance?.layout ?? "d"; + const sort = (await Storage.get("sort"))?.[dir] ?? (await getDefaultSort(dir)); + switch (sort) { + case "L": // Last Modified + files.sort((a, b) => { + return new Date(a.last_modified?.secs_since_epoch ?? a.time_deleted) < new Date(b.last_modified?.secs_since_epoch ?? b.time_deleted) + ? 1 + : -1; + }); + break; + case "F": // First Modified + files.sort((a, b) => { + return new Date(a.last_modified?.secs_since_epoch ?? a.time_deleted) > new Date(b.last_modified?.secs_since_epoch ?? b.time_deleted) + ? 1 + : -1; + }); + break; + case "S": // Size + files.sort((a, b) => a.size - b.size); + break; + case "T": // Filetype + files.sort((a, b) => (a.file_type > b.file_type ? 1 : -1)); + break; - case 'A': // A-Z - case 'Z': // Z-A - default: { - const compator = new Intl.Collator(undefined, { - numeric: true, - sensitivity: 'base', - }).compare; - if (sort === 'Z') { - files.sort((a, b) => { - return compator(b.basename.toLowerCase(), a.basename.toLowerCase()); - }); - } else { - files.sort((a, b) => { - return compator(a.basename.toLowerCase(), b.basename.toLowerCase()); - }); - } - } - } - if (!dirAlongsideFiles) { - files = files.sort((a, b) => -(Number(a.is_dir) - Number(b.is_dir))); - } + case "A": // A-Z + case "Z": // Z-A + default: { + const compator = new Intl.Collator(undefined, { + numeric: true, + sensitivity: "base", + }).compare; + if (sort === "Z") { + files.sort((a, b) => { + return compator(b.basename.toLowerCase(), a.basename.toLowerCase()); + }); + } else { + files.sort((a, b) => { + return compator(a.basename.toLowerCase(), b.basename.toLowerCase()); + }); + } + } + } + if (!dirAlongsideFiles) { + files = files.sort((a, b) => -(Number(a.is_dir) - Number(b.is_dir))); + } - const imageAsThumbnail = - (appearance?.imageAsThumbnail ?? 'smalldir') === 'smalldir' ? files.length < 100 : appearance?.imageAsThumbnail === 'yes'; - for (const file of files) { - const fileGrid = document.createElement('div'); - fileGrid.className = 'file-grid grid-hover-effect file'; - let displayName: string; - switch (layout) { - case 'm': - fileGrid.classList.add('medium-grid-view'); - displayName = file.basename.length > 30 ? file.basename.substring(0, 30) + '...' : file.basename; - break; - case 'l': - fileGrid.classList.add('large-grid-view'); - displayName = file.basename.length > 40 ? file.basename.substring(0, 40) + '...' : file.basename; - break; - case 'd': - fileGrid.classList.add('detail-view'); - displayName = file.basename; - break; - default: - fileGrid.classList.add('small-grid-view'); - displayName = file.basename.length > 20 ? file.basename.substring(0, 20) + '...' : file.basename; - break; - } - if (isSearch) displayName = file.file_path; + const imageAsThumbnail = + (appearance?.imageAsThumbnail ?? "smalldir") === "smalldir" ? files.length < 100 : appearance?.imageAsThumbnail === "yes"; + for (const file of files) { + const fileGrid = document.createElement("div"); + fileGrid.className = "file-grid grid-hover-effect file"; + let displayName: string; + switch (layout) { + case "m": + fileGrid.classList.add("medium-grid-view"); + displayName = file.basename.length > 30 ? file.basename.substring(0, 30) + "..." : file.basename; + break; + case "l": + fileGrid.classList.add("large-grid-view"); + displayName = file.basename.length > 40 ? file.basename.substring(0, 40) + "..." : file.basename; + break; + case "d": + fileGrid.classList.add("detail-view"); + displayName = file.basename; + break; + default: + fileGrid.classList.add("small-grid-view"); + displayName = file.basename.length > 20 ? file.basename.substring(0, 20) + "..." : file.basename; + break; + } + if (isSearch) displayName = file.file_path; - fileGrid.setAttribute('draggable', 'true'); - if (!file.is_trash) { - fileGrid.dataset.modifiedAt = String( - new Date(file.last_modified.secs_since_epoch * 1000).toLocaleString(navigator.language, { hour12: false }) - ); - fileGrid.dataset.createdAt = String(new Date(file.created.secs_since_epoch * 1000).toLocaleString(navigator.language, { hour12: false })); - fileGrid.dataset.accessedAt = String( - new Date(file.last_accessed.secs_since_epoch * 1000).toLocaleString(navigator.language, { hour12: false }) - ); - } - fileGrid.dataset.isdir = String(file.is_dir); - if (file.time_deleted) fileGrid.dataset.trashDeletionDate = String(file.time_deleted); - if (file.is_trash) fileGrid.dataset.realPath = encodeURI(joinPath(file.original_parent, file.basename)); - let preview: string; - if (file.file_type === 'Windows Shortcut') { - fileGrid.dataset.isLnk = 'true'; - for (const lnk of lnk_files) { - if (file.file_path === lnk.file_path) { - preview = await fileThumbnail(lnk.icon, 'file', true, true); - break; - } - } - } else { - preview = await fileThumbnail(file.file_path, file.is_dir ? 'folder' : 'file', true, imageAsThumbnail); - } + fileGrid.setAttribute("draggable", "true"); + if (!file.is_trash) { + fileGrid.dataset.modifiedAt = String( + new Date(file.last_modified.secs_since_epoch * 1000).toLocaleString(navigator.language, { hour12: false }), + ); + fileGrid.dataset.createdAt = String(new Date(file.created.secs_since_epoch * 1000).toLocaleString(navigator.language, { hour12: false })); + fileGrid.dataset.accessedAt = String( + new Date(file.last_accessed.secs_since_epoch * 1000).toLocaleString(navigator.language, { hour12: false }), + ); + } + fileGrid.dataset.isdir = String(file.is_dir); + if (file.time_deleted) fileGrid.dataset.trashDeletionDate = String(file.time_deleted); + if (file.is_trash) fileGrid.dataset.realPath = encodeURI(joinPath(file.original_parent, file.basename)); + let preview: string; + if (file.file_type === "Windows Shortcut") { + fileGrid.dataset.isLnk = "true"; + for (const lnk of lnk_files) { + if (file.file_path === lnk.file_path) { + preview = await fileThumbnail(lnk.icon, "file", true, true); + break; + } + } + } else { + preview = await fileThumbnail(file.file_path, file.is_dir ? "folder" : "file", true, imageAsThumbnail); + } - fileGrid.dataset.path = encodeURI(normalizeSlash(file.file_path)); - fileGrid.dataset.isSystem = String(file.is_system); - fileGrid.dataset.isTrash = String(file.is_trash); - fileGrid.dataset.isDir = String(file.is_dir); - fileGrid.dataset.isHidden = String(file.is_hidden); - fileGrid.dataset.isReadOnly = String(file.readonly); - fileGrid.innerHTML = ` + fileGrid.dataset.path = encodeURI(normalizeSlash(file.file_path)); + fileGrid.dataset.isSystem = String(file.is_system); + fileGrid.dataset.isTrash = String(file.is_trash); + fileGrid.dataset.isDir = String(file.is_dir); + fileGrid.dataset.isHidden = String(file.is_hidden); + fileGrid.dataset.isReadOnly = String(file.readonly); + fileGrid.innerHTML = ` ${preview} ${displayName} - ${file.original_parent ? `${file.original_parent}` : ''} - ${new Date((file.last_modified?.secs_since_epoch ?? file.time_deleted) * 1000).toLocaleString( - navigator.language, - { hour12: false } - )} + ${file.original_parent ? `${file.original_parent}` : ""} + ${new Date( + (file.last_modified?.secs_since_epoch ?? file.time_deleted) * 1000, + ).toLocaleString(navigator.language, { hour12: false })} ${ - file.size > 0 - ? `${formatBytes( - file.size // eslint-disable-next-line no-mixed-spaces-and-tabs - )}` - : `` - } + file.size > 0 + ? `${formatBytes( + file.size, // eslint-disable-next-line no-mixed-spaces-and-tabs + )}` + : `` + } ${file.file_type} `; - FilesElement.appendChild(fileGrid); - } - if (options?.reveal) { - Select(document.querySelector(`.file[data-path="${encodeURI(options?.revealDir)}"]`), false, false); - } + FilesElement.appendChild(fileGrid); + } + if (options?.reveal) { + Select(document.querySelector(`.file[data-path="${encodeURI(options?.revealDir)}"]`), false, false); + } - return FilesElement; + return FilesElement; }; export default displayFiles; diff --git a/src/Components/Open/open.ts b/src/Components/Open/open.ts index 680222b5..925fb117 100644 --- a/src/Components/Open/open.ts +++ b/src/Components/Open/open.ts @@ -1,27 +1,27 @@ -import DirectoryAPI from '../../Service/directory'; -import { startLoading, stopLoading, isLoading } from '../Functions/Loading/loading'; -import { updateTheme } from '../Theme/theme'; -import FileAPI from '../../Service/files'; -import changePosition from '../Functions/changePosition'; -import Recent from './recent'; -import Home from '../Layout/home'; -import displayFiles from './displayFiles'; -import { InfoLog, OpenLog } from '../Functions/log'; -import getDirname from '../Functions/path/dirname'; -import normalizeSlash from '../Functions/path/normalizeSlash'; -import { changeWindowTitle } from '../../Service/window'; -import getBasename from '../Functions/path/basename'; -import { getTrashedFiles } from '../../Service/trash'; -import OS from '../../Service/platform'; -import { reload } from '../Layout/windowManager'; -import focusingPath from '../Functions/focusingPath'; -import { LOAD_IMAGE } from '../Functions/lazyLoadingImage'; -import PromptError from '../Prompt/error'; -import { UpdateInfo } from '../Layout/infobar'; -import { processSearch, stopSearchingProcess } from '../Files/File Operation/search'; -import Storage from '../../Service/storage'; -import { GET_TAB_ELEMENT, MAIN_BOX_ELEMENT } from '../../Util/constants'; -import Error from '../Prompt/error'; +import DirectoryAPI from "../../Service/directory"; +import FileAPI from "../../Service/files"; +import OS from "../../Service/platform"; +import Storage from "../../Service/storage"; +import { getTrashedFiles } from "../../Service/trash"; +import { changeWindowTitle } from "../../Service/window"; +import { GET_TAB_ELEMENT, MAIN_BOX_ELEMENT } from "../../Util/constants"; +import { processSearch, stopSearchingProcess } from "../Files/File Operation/search"; +import { isLoading, startLoading, stopLoading } from "../Functions/Loading/loading"; +import changePosition from "../Functions/changePosition"; +import focusingPath from "../Functions/focusingPath"; +import { LOAD_IMAGE } from "../Functions/lazyLoadingImage"; +import { InfoLog, OpenLog } from "../Functions/log"; +import getBasename from "../Functions/path/basename"; +import getDirname from "../Functions/path/dirname"; +import normalizeSlash from "../Functions/path/normalizeSlash"; +import Home from "../Layout/home"; +import { UpdateInfo } from "../Layout/infobar"; +import { reload } from "../Layout/windowManager"; +import PromptError from "../Prompt/error"; +import Error from "../Prompt/error"; +import { updateTheme } from "../Theme/theme"; +import displayFiles from "./displayFiles"; +import Recent from "./recent"; let platform: string; let directoryInfo: DirectoryAPI; /** @@ -33,150 +33,150 @@ let directoryInfo: DirectoryAPI; * @returns {Promise} */ const OpenDir = async (dir: string, reveal?: boolean, forceOpen = false, writeHistory = true): Promise => { - await stopSearchingProcess(); - if (isLoading() && !forceOpen) { - InfoLog(`Something is still loading, refusing to open dir ${dir}`); - return; - } - // Check if the user is just want to reload the current directory - const isReload = (await focusingPath()) === dir && !forceOpen; - if (!isReload) directoryInfo?.unlisten?.(); - startLoading(); - changePosition(dir, forceOpen, writeHistory); - const MAIN_ELEMENT = GET_TAB_ELEMENT(); - MAIN_ELEMENT.innerHTML = ''; - if (MAIN_ELEMENT.classList.contains('error-reading-files')) MAIN_ELEMENT.classList.remove('error-reading-files'); // Remove class if exist - if (dir === 'xplorer://Home') { - Home(); - UpdateInfo('number-of-files', ''); - OpenLog(dir); - } else if (dir === 'xplorer://Trash') { - if (!platform) platform = await OS(); - if (platform === 'darwin') { - MAIN_ELEMENT.classList.add('error-reading-files'); - MAIN_ELEMENT.innerText = 'Xploring trash folder is not supported for macOS yet.'; - stopLoading(); - } else { - getTrashedFiles().then(async (trashedFiles) => { - UpdateInfo('number-of-files', `${trashedFiles.files.length} files`); - if (!trashedFiles.files.length) { - MAIN_ELEMENT.classList.add('error-reading-files'); - MAIN_ELEMENT.innerText = 'This folder is empty.'; - stopLoading(); - } else { - await displayFiles(trashedFiles.files, dir, MAIN_ELEMENT); - stopLoading(); - updateTheme('grid'); - LOAD_IMAGE(); - changeWindowTitle(getBasename(dir)); - } - }); - } - OpenLog(dir); - } else if (dir === 'xplorer://Recent') { - Recent(); - UpdateInfo('number-of-files', ''); - OpenLog(dir); - } else if (dir.startsWith('Search')) { - // Search path pattern: Search: [[search-query]] inside [[search-path]] - const splitBySearchKeyword = dir.split('Search: '); - splitBySearchKeyword.shift(); - const query = splitBySearchKeyword.join('Search: '); - const splitByInsideKeyword = query.split(' inside '); - if (splitByInsideKeyword.length === 2) { - const searchQuery = splitByInsideKeyword[0].slice(2, -2); - const searchPath = splitByInsideKeyword[1].slice(2, -2); - processSearch(searchQuery, searchPath); - } else { - for (let i = 0; i < splitByInsideKeyword.length; i++) { - if (splitByInsideKeyword[i]?.endsWith(']]') && splitByInsideKeyword[i + 1]?.startsWith('[[')) { - const searchQuery = splitByInsideKeyword - .slice(0, i + 1) - .join(' inside ') - .slice(2, -2); - const searchPath = splitByInsideKeyword - .slice(i + 1) - .join(' inside ') - .slice(2, -2); - processSearch(searchQuery, searchPath); - } - } - } - } else { - if (reveal) { - directoryInfo = new DirectoryAPI(getDirname(dir)); - if (!(await directoryInfo.exists())) { - PromptError('Directory not exists', "Directory you're looking for does not exist."); - stopLoading(); - return; - } - await directoryInfo - .getFiles() - .then(async (files) => { - UpdateInfo('number-of-files', `${files.number_of_files - files.skipped_files.length} files`); - if (!files.files.length) { - MAIN_ELEMENT.classList.add('error-reading-files'); - MAIN_ELEMENT.innerText = 'This folder is empty.'; - stopLoading(); - } else { - await displayFiles( - files.files, - dir, - MAIN_ELEMENT, - { - reveal, - revealDir: normalizeSlash(dir), - }, - null, - files.lnk_files - ); - stopLoading(); - updateTheme('grid'); - LOAD_IMAGE(); - changeWindowTitle(getBasename(getDirname(dir))); - console.timeEnd(dir); - if (!isReload) directoryInfo.listen(() => reload()); - } - }) - .catch((err) => { - MAIN_ELEMENT.classList.add('error-reading-files'); - MAIN_ELEMENT.innerText = err; - stopLoading(); - }); - } else { - directoryInfo = new DirectoryAPI(dir); - if (!(await directoryInfo.exists())) { - PromptError('Directory not exists', "Directory you're looking for does not exist."); - stopLoading(); - return; - } - await directoryInfo - .getFiles() - .then(async (files) => { - UpdateInfo('number-of-files', `${files.number_of_files - files.skipped_files.length} files`); - if (!files.files.length) { - MAIN_ELEMENT.classList.add('error-reading-files'); - MAIN_ELEMENT.innerText = 'This folder is empty.'; - stopLoading(); - } else { - await displayFiles(files.files, dir, MAIN_ELEMENT, null, null, files.lnk_files); - stopLoading(); - updateTheme('grid'); - LOAD_IMAGE(); - changeWindowTitle(getBasename(dir)); - if (!isReload) directoryInfo.listen(() => reload()); - console.timeEnd(dir); - return; - } - }) - .catch((err) => { - MAIN_ELEMENT.classList.add('error-reading-files'); - MAIN_ELEMENT.innerText = err; - stopLoading(); - }); - } - OpenLog(dir); - } + await stopSearchingProcess(); + if (isLoading() && !forceOpen) { + InfoLog(`Something is still loading, refusing to open dir ${dir}`); + return; + } + // Check if the user is just want to reload the current directory + const isReload = (await focusingPath()) === dir && !forceOpen; + if (!isReload) directoryInfo?.unlisten?.(); + startLoading(); + changePosition(dir, forceOpen, writeHistory); + const MAIN_ELEMENT = GET_TAB_ELEMENT(); + MAIN_ELEMENT.innerHTML = ""; + if (MAIN_ELEMENT.classList.contains("error-reading-files")) MAIN_ELEMENT.classList.remove("error-reading-files"); // Remove class if exist + if (dir === "xplorer://Home") { + Home(); + UpdateInfo("number-of-files", ""); + OpenLog(dir); + } else if (dir === "xplorer://Trash") { + if (!platform) platform = await OS(); + if (platform === "darwin") { + MAIN_ELEMENT.classList.add("error-reading-files"); + MAIN_ELEMENT.innerText = "Xploring trash folder is not supported for macOS yet."; + stopLoading(); + } else { + getTrashedFiles().then(async (trashedFiles) => { + UpdateInfo("number-of-files", `${trashedFiles.files.length} files`); + if (!trashedFiles.files.length) { + MAIN_ELEMENT.classList.add("error-reading-files"); + MAIN_ELEMENT.innerText = "This folder is empty."; + stopLoading(); + } else { + await displayFiles(trashedFiles.files, dir, MAIN_ELEMENT); + stopLoading(); + updateTheme("grid"); + LOAD_IMAGE(); + changeWindowTitle(getBasename(dir)); + } + }); + } + OpenLog(dir); + } else if (dir === "xplorer://Recent") { + Recent(); + UpdateInfo("number-of-files", ""); + OpenLog(dir); + } else if (dir.startsWith("Search")) { + // Search path pattern: Search: [[search-query]] inside [[search-path]] + const splitBySearchKeyword = dir.split("Search: "); + splitBySearchKeyword.shift(); + const query = splitBySearchKeyword.join("Search: "); + const splitByInsideKeyword = query.split(" inside "); + if (splitByInsideKeyword.length === 2) { + const searchQuery = splitByInsideKeyword[0].slice(2, -2); + const searchPath = splitByInsideKeyword[1].slice(2, -2); + processSearch(searchQuery, searchPath); + } else { + for (let i = 0; i < splitByInsideKeyword.length; i++) { + if (splitByInsideKeyword[i]?.endsWith("]]") && splitByInsideKeyword[i + 1]?.startsWith("[[")) { + const searchQuery = splitByInsideKeyword + .slice(0, i + 1) + .join(" inside ") + .slice(2, -2); + const searchPath = splitByInsideKeyword + .slice(i + 1) + .join(" inside ") + .slice(2, -2); + processSearch(searchQuery, searchPath); + } + } + } + } else { + if (reveal) { + directoryInfo = new DirectoryAPI(getDirname(dir)); + if (!(await directoryInfo.exists())) { + PromptError("Directory not exists", "Directory you're looking for does not exist."); + stopLoading(); + return; + } + await directoryInfo + .getFiles() + .then(async (files) => { + UpdateInfo("number-of-files", `${files.number_of_files - files.skipped_files.length} files`); + if (!files.files.length) { + MAIN_ELEMENT.classList.add("error-reading-files"); + MAIN_ELEMENT.innerText = "This folder is empty."; + stopLoading(); + } else { + await displayFiles( + files.files, + dir, + MAIN_ELEMENT, + { + reveal, + revealDir: normalizeSlash(dir), + }, + null, + files.lnk_files, + ); + stopLoading(); + updateTheme("grid"); + LOAD_IMAGE(); + changeWindowTitle(getBasename(getDirname(dir))); + console.timeEnd(dir); + if (!isReload) directoryInfo.listen(() => reload()); + } + }) + .catch((err) => { + MAIN_ELEMENT.classList.add("error-reading-files"); + MAIN_ELEMENT.innerText = err; + stopLoading(); + }); + } else { + directoryInfo = new DirectoryAPI(dir); + if (!(await directoryInfo.exists())) { + PromptError("Directory not exists", "Directory you're looking for does not exist."); + stopLoading(); + return; + } + await directoryInfo + .getFiles() + .then(async (files) => { + UpdateInfo("number-of-files", `${files.number_of_files - files.skipped_files.length} files`); + if (!files.files.length) { + MAIN_ELEMENT.classList.add("error-reading-files"); + MAIN_ELEMENT.innerText = "This folder is empty."; + stopLoading(); + } else { + await displayFiles(files.files, dir, MAIN_ELEMENT, null, null, files.lnk_files); + stopLoading(); + updateTheme("grid"); + LOAD_IMAGE(); + changeWindowTitle(getBasename(dir)); + if (!isReload) directoryInfo.listen(() => reload()); + console.timeEnd(dir); + return; + } + }) + .catch((err) => { + MAIN_ELEMENT.classList.add("error-reading-files"); + MAIN_ELEMENT.innerText = err; + stopLoading(); + }); + } + OpenLog(dir); + } }; /** * Open file/folder handler @@ -184,41 +184,41 @@ const OpenDir = async (dir: string, reveal?: boolean, forceOpen = false, writeHi * @returns {Promise} */ const OpenHandler = async (e: MouseEvent): Promise => { - const preference = await Storage.get('preference'); - if (document.querySelector('#sidebar-nav').contains(e.target as HTMLElement)) { - if (e.detail === 1 && preference?.clickToOpenSidebar && preference?.clickToOpenSidebar !== 'single') return; - } else if ((await focusingPath()) === 'xplorer://Home') { - if (e.detail === 1 && preference?.clickToOpenHome !== 'single') return; - } else { - if (e.detail === 1 && preference?.clickToOpenHome !== 'single') return; - } - let element = e.target as HTMLElement; - while (element?.dataset && !element.dataset.path) { - element = element.parentNode as HTMLElement; - } - if (!element?.dataset?.path) return; - if (element.classList.contains('workspace-tab')) return; + const preference = await Storage.get("preference"); + if (document.querySelector("#sidebar-nav").contains(e.target as HTMLElement)) { + if (e.detail === 1 && preference?.clickToOpenSidebar && preference?.clickToOpenSidebar !== "single") return; + } else if ((await focusingPath()) === "xplorer://Home") { + if (e.detail === 1 && preference?.clickToOpenHome !== "single") return; + } else { + if (e.detail === 1 && preference?.clickToOpenHome !== "single") return; + } + let element = e.target as HTMLElement; + while (element?.dataset && !element.dataset.path) { + element = element.parentNode as HTMLElement; + } + if (!element?.dataset?.path) return; + if (element.classList.contains("workspace-tab")) return; - const filePath = decodeURI(element.dataset.path); + const filePath = decodeURI(element.dataset.path); - if ((await focusingPath()) === 'xplorer://Trash' && element.dataset.isdir !== 'true') { - Error('Error opening trashed file', 'Please restore the file first in order to open it.'); - } + if ((await focusingPath()) === "xplorer://Trash" && element.dataset.isdir !== "true") { + Error("Error opening trashed file", "Please restore the file first in order to open it."); + } - // Open the file if it's not directory - if (element.dataset.isdir !== 'true') { - OpenLog(filePath); - await new FileAPI(filePath).openFile(); - } else { - OpenDir(filePath); - } + // Open the file if it's not directory + if (element.dataset.isdir !== "true") { + OpenLog(filePath); + await new FileAPI(filePath).openFile(); + } else { + OpenDir(filePath); + } }; /** * Open directory/file listener initializer * @returns {Promise} */ const OpenInit = async (): Promise => { - document.querySelector('#sidebar-nav').addEventListener('click', OpenHandler); - MAIN_BOX_ELEMENT().addEventListener('click', OpenHandler); + document.querySelector("#sidebar-nav").addEventListener("click", OpenHandler); + MAIN_BOX_ELEMENT().addEventListener("click", OpenHandler); }; export { OpenInit, OpenDir }; diff --git a/src/Components/Open/recent.ts b/src/Components/Open/recent.ts index 8ce21afe..38a28a49 100644 --- a/src/Components/Open/recent.ts +++ b/src/Components/Open/recent.ts @@ -1,137 +1,137 @@ -import { startLoading, stopLoading } from '../Functions/Loading/loading'; -import Storage from '../../Service/storage'; -import fileThumbnail from '../Thumbnail/thumbnail'; -import { updateTheme } from '../Theme/theme'; -import type { OpenLogType } from '../Functions/log'; -import FileAPI from '../../Service/files'; -import FileMetaData from '../../Typings/fileMetaData'; -import NormalizeSlash from '../Functions/path/normalizeSlash'; -import formatBytes from '../Functions/filesize'; -import { LOAD_IMAGE } from '../Functions/lazyLoadingImage'; -import { GET_TAB_ELEMENT } from '../../Util/constants'; +import FileAPI from "../../Service/files"; +import Storage from "../../Service/storage"; +import type FileMetaData from "../../Typings/fileMetaData"; +import { GET_TAB_ELEMENT } from "../../Util/constants"; +import { startLoading, stopLoading } from "../Functions/Loading/loading"; +import formatBytes from "../Functions/filesize"; +import { LOAD_IMAGE } from "../Functions/lazyLoadingImage"; +import type { OpenLogType } from "../Functions/log"; +import NormalizeSlash from "../Functions/path/normalizeSlash"; +import { updateTheme } from "../Theme/theme"; +import fileThumbnail from "../Thumbnail/thumbnail"; interface RecentType { - path: string; - timestamp: Date; - properties: FileMetaData; + path: string; + timestamp: Date; + properties: FileMetaData; } /** * Recent files handler * @returns {Promise} */ const Recent = async (): Promise => { - startLoading(); - // Preference data - const layout = (await Storage.get('layout'))?.['Recent'] ?? (await Storage.get('appearance'))?.layout ?? 's'; - const sort = (await Storage.get('sort'))?.['Recent'] ?? 'F'; - // Get the main element - const MAIN_ELEMENT = GET_TAB_ELEMENT(); - MAIN_ELEMENT.innerHTML = ''; - if (MAIN_ELEMENT.classList.contains('empty-dir-notification')) MAIN_ELEMENT.classList.remove('empty-dir-notification'); // Remove class if exist - // Get recent files list - const _recents: OpenLogType[] = (await Storage.get('log'))?.opens ?? []; - let recents = await Promise.all( - _recents.map(async (_recent) => { - const FileData = new FileAPI(_recent.path); - if (!(await FileData.exists())) return null; - const properties = await FileData.properties(); - return { path: _recent.path, timestamp: _recent.timestamp, properties }; - }) - ); - recents = recents.filter((recent) => recent !== null); - if (!recents) { - MAIN_ELEMENT.classList.add('empty-dir-notification'); - MAIN_ELEMENT.innerText = 'This folder is empty.'; - stopLoading(); - return; - } - recents = recents.sort((a, b) => { - switch (sort) { - case 'A': // A-Z - return a.path.split('\\').pop().split('/').pop().toLowerCase() > b.path.split('\\').pop().split('/').pop().toLowerCase() ? 1 : -1; - case 'Z': // Z-A - return a.path.split('\\').pop().split('/').pop().toLowerCase() < b.path.split('\\').pop().split('/').pop().toLowerCase() ? 1 : -1; - case 'L': // Last Modified - return new Date(a.timestamp) < new Date(b.timestamp) ? -1 : 1; - case 'F': // First Modified - return new Date(a.timestamp) > new Date(b.timestamp) ? -1 : 1; - case 'S': // Size - return a.properties.size > b.properties.size ? 1 : -1; - case 'T': - return a.properties.file_type > b.properties.file_type ? 1 : -1; - } - }); - const __filterDuplicate = (arr: RecentType[]) => { - const seen: string[] = []; - const out = []; - for (let i = 0; i < arr.length; i++) { - const item = arr[i]; - if (seen.indexOf(NormalizeSlash(item.path)) === -1) { - seen.push(NormalizeSlash(item.path)); - out.push(arr[i]); - } - } - return out; - }; - recents = __filterDuplicate(recents); - if (!recents.length) { - MAIN_ELEMENT.classList.add('empty-dir-notification'); - MAIN_ELEMENT.innerText = 'This folder is empty.'; - } else { - for (const recent of recents) { - const preview = await fileThumbnail(recent.path, recent.properties.is_dir ? 'folder' : 'file'); - const fileGrid = document.createElement('div'); - fileGrid.className = 'file-grid file grid-hover-effect'; - let displayName: string; - switch (layout) { - case 'm': - fileGrid.classList.add('medium-grid-view'); - displayName = - recent.properties.basename.length > 30 ? recent.properties.basename.substring(0, 30) + '...' : recent.properties.basename; - break; - case 'l': - fileGrid.classList.add('large-grid-view'); - displayName = - recent.properties.basename.length > 40 ? recent.properties.basename.substring(0, 40) + '...' : recent.properties.basename; - break; - case 'd': - fileGrid.classList.add('detail-view'); - displayName = recent.properties.basename; - break; - default: - fileGrid.classList.add('small-grid-view'); - displayName = - recent.properties.basename.length > 20 ? recent.properties.basename.substring(0, 20) + '...' : recent.properties.basename; - break; - } - fileGrid.setAttribute('draggable', 'true'); - fileGrid.dataset.isdir = String(recent.properties.is_dir); - fileGrid.dataset.path = encodeURI(NormalizeSlash(recent.path)); - fileGrid.dataset.isSystem = String(recent.properties.is_system); - fileGrid.dataset.isReadOnly = String(recent.properties.readonly); - fileGrid.dataset.isHidden = String(recent.properties.is_hidden); - fileGrid.innerHTML = ` + startLoading(); + // Preference data + const layout = (await Storage.get("layout"))?.["Recent"] ?? (await Storage.get("appearance"))?.layout ?? "s"; + const sort = (await Storage.get("sort"))?.["Recent"] ?? "F"; + // Get the main element + const MAIN_ELEMENT = GET_TAB_ELEMENT(); + MAIN_ELEMENT.innerHTML = ""; + if (MAIN_ELEMENT.classList.contains("empty-dir-notification")) MAIN_ELEMENT.classList.remove("empty-dir-notification"); // Remove class if exist + // Get recent files list + const _recents: OpenLogType[] = (await Storage.get("log"))?.opens ?? []; + let recents = await Promise.all( + _recents.map(async (_recent) => { + const FileData = new FileAPI(_recent.path); + if (!(await FileData.exists())) return null; + const properties = await FileData.properties(); + return { path: _recent.path, timestamp: _recent.timestamp, properties }; + }), + ); + recents = recents.filter((recent) => recent !== null); + if (!recents) { + MAIN_ELEMENT.classList.add("empty-dir-notification"); + MAIN_ELEMENT.innerText = "This folder is empty."; + stopLoading(); + return; + } + recents = recents.sort((a, b) => { + switch (sort) { + case "A": // A-Z + return a.path.split("\\").pop().split("/").pop().toLowerCase() > b.path.split("\\").pop().split("/").pop().toLowerCase() ? 1 : -1; + case "Z": // Z-A + return a.path.split("\\").pop().split("/").pop().toLowerCase() < b.path.split("\\").pop().split("/").pop().toLowerCase() ? 1 : -1; + case "L": // Last Modified + return new Date(a.timestamp) < new Date(b.timestamp) ? -1 : 1; + case "F": // First Modified + return new Date(a.timestamp) > new Date(b.timestamp) ? -1 : 1; + case "S": // Size + return a.properties.size > b.properties.size ? 1 : -1; + case "T": + return a.properties.file_type > b.properties.file_type ? 1 : -1; + } + }); + const __filterDuplicate = (arr: RecentType[]) => { + const seen: string[] = []; + const out = []; + for (let i = 0; i < arr.length; i++) { + const item = arr[i]; + if (seen.indexOf(NormalizeSlash(item.path)) === -1) { + seen.push(NormalizeSlash(item.path)); + out.push(arr[i]); + } + } + return out; + }; + recents = __filterDuplicate(recents); + if (!recents.length) { + MAIN_ELEMENT.classList.add("empty-dir-notification"); + MAIN_ELEMENT.innerText = "This folder is empty."; + } else { + for (const recent of recents) { + const preview = await fileThumbnail(recent.path, recent.properties.is_dir ? "folder" : "file"); + const fileGrid = document.createElement("div"); + fileGrid.className = "file-grid file grid-hover-effect"; + let displayName: string; + switch (layout) { + case "m": + fileGrid.classList.add("medium-grid-view"); + displayName = + recent.properties.basename.length > 30 ? recent.properties.basename.substring(0, 30) + "..." : recent.properties.basename; + break; + case "l": + fileGrid.classList.add("large-grid-view"); + displayName = + recent.properties.basename.length > 40 ? recent.properties.basename.substring(0, 40) + "..." : recent.properties.basename; + break; + case "d": + fileGrid.classList.add("detail-view"); + displayName = recent.properties.basename; + break; + default: + fileGrid.classList.add("small-grid-view"); + displayName = + recent.properties.basename.length > 20 ? recent.properties.basename.substring(0, 20) + "..." : recent.properties.basename; + break; + } + fileGrid.setAttribute("draggable", "true"); + fileGrid.dataset.isdir = String(recent.properties.is_dir); + fileGrid.dataset.path = encodeURI(NormalizeSlash(recent.path)); + fileGrid.dataset.isSystem = String(recent.properties.is_system); + fileGrid.dataset.isReadOnly = String(recent.properties.readonly); + fileGrid.dataset.isHidden = String(recent.properties.is_hidden); + fileGrid.innerHTML = ` ${preview} ${displayName} ${new Date(recent.properties.last_modified?.secs_since_epoch * 1000).toLocaleString( - navigator.language, - { hour12: false } - )} + navigator.language, + { hour12: false }, + )} ${ - recent.properties.size > 0 && !recent.properties.is_dir - ? `${formatBytes( - recent.properties.size // eslint-disable-next-line no-mixed-spaces-and-tabs - )}` - : `` - } + recent.properties.size > 0 && !recent.properties.is_dir + ? `${formatBytes( + recent.properties.size, // eslint-disable-next-line no-mixed-spaces-and-tabs + )}` + : `` + } ${recent.properties.file_type} `; - MAIN_ELEMENT.appendChild(fileGrid); - } - updateTheme('grid'); - LOAD_IMAGE(); - } - stopLoading(); + MAIN_ELEMENT.appendChild(fileGrid); + } + updateTheme("grid"); + LOAD_IMAGE(); + } + stopLoading(); }; export default Recent; diff --git a/src/Components/Preview/DocxViewer.tsx b/src/Components/Preview/DocxViewer.tsx index 6266b9ee..705b9f92 100644 --- a/src/Components/Preview/DocxViewer.tsx +++ b/src/Components/Preview/DocxViewer.tsx @@ -1,11 +1,11 @@ -import React from 'react'; +import React from "react"; export interface IDocxViewerProps { - filePath: string + filePath: string; } const DocxViewer = ({ filePath }: IDocxViewerProps): JSX.Element => { - return (
Docx viewer: {filePath}
); -} + return
Docx viewer: {filePath}
; +}; export default DocxViewer; diff --git a/src/Components/Preview/HtmlViewer.tsx b/src/Components/Preview/HtmlViewer.tsx index 4fd6e83e..c38d3ba5 100644 --- a/src/Components/Preview/HtmlViewer.tsx +++ b/src/Components/Preview/HtmlViewer.tsx @@ -1,11 +1,11 @@ -import React from 'react'; +import React from "react"; export interface IHtmlViewerProps { - filePath: string + filePath: string; } const HtmlViewer = ({ filePath }: IHtmlViewerProps): JSX.Element => { - return (
pdf viewer: {filePath}
); -} + return
pdf viewer: {filePath}
; +}; export default HtmlViewer; diff --git a/src/Components/Preview/ImageViewer.tsx b/src/Components/Preview/ImageViewer.tsx index f2317bfb..3b1d5972 100644 --- a/src/Components/Preview/ImageViewer.tsx +++ b/src/Components/Preview/ImageViewer.tsx @@ -1,11 +1,11 @@ -import React from 'react'; +import React from "react"; export interface IImageViewerProps { - filePath: string + filePath: string; } const ImageViewer = ({ filePath }: IImageViewerProps): JSX.Element => { - return (
Image viewer: {filePath}
); -} + return
Image viewer: {filePath}
; +}; export default ImageViewer; diff --git a/src/Components/Preview/MarkdownViewer.tsx b/src/Components/Preview/MarkdownViewer.tsx index df38a672..06bc12fa 100644 --- a/src/Components/Preview/MarkdownViewer.tsx +++ b/src/Components/Preview/MarkdownViewer.tsx @@ -1,11 +1,11 @@ -import React from 'react'; +import React from "react"; export interface IMarkdownViewerProps { - filePath: string + filePath: string; } const MarkdownViewer = ({ filePath }: IMarkdownViewerProps): JSX.Element => { - return (
Markdown viewer: {filePath}
); -} + return
Markdown viewer: {filePath}
; +}; export default MarkdownViewer; diff --git a/src/Components/Preview/PdfViewer.tsx b/src/Components/Preview/PdfViewer.tsx index 254d4c34..611611bc 100644 --- a/src/Components/Preview/PdfViewer.tsx +++ b/src/Components/Preview/PdfViewer.tsx @@ -1,36 +1,30 @@ -import React, { useEffect } from 'react'; -import { useDispatch, useSelector } from 'react-redux'; +import React, { useEffect } from "react"; +import { useDispatch, useSelector } from "react-redux"; -import { readAssetRequest } from '../../Store/ActionCreators/FilesActionCreators'; -import { IAppState } from '../../Store/Reducers'; +import { readAssetRequest } from "../../Store/ActionCreators/FilesActionCreators"; +import type { IAppState } from "../../Store/Reducers"; export interface IPdfViewerProps { - filePath: string + filePath: string; } const PdfViewer = ({ filePath }: IPdfViewerProps): JSX.Element => { - const dispatch = useDispatch(); - const content = useSelector(state => state.files.files?.[filePath]?.content); + const dispatch = useDispatch(); + const content = useSelector((state) => state.files.files?.[filePath]?.content); - useEffect(() => { - dispatch(readAssetRequest(filePath)); - }, [filePath]); + useEffect(() => { + dispatch(readAssetRequest(filePath)); + }, [filePath]); - if (!content) return
Loading...
; + if (!content) return
Loading...
; - return ( -
- - - -
- ); -} + return ( +
+ + + +
+ ); +}; export default PdfViewer; diff --git a/src/Components/Preview/PlaintextViewer.tsx b/src/Components/Preview/PlaintextViewer.tsx index ce0e3701..993ba9aa 100644 --- a/src/Components/Preview/PlaintextViewer.tsx +++ b/src/Components/Preview/PlaintextViewer.tsx @@ -1,11 +1,11 @@ -import React from 'react'; +import React from "react"; export interface IPlaintextViewerProps { - filePath: string + filePath: string; } const PlaintextViewer = ({ filePath }: IPlaintextViewerProps): JSX.Element => { - return (
Plaintext viewer: {filePath}
); -} + return
Plaintext viewer: {filePath}
; +}; export default PlaintextViewer; diff --git a/src/Components/Preview/VideoViewer.tsx b/src/Components/Preview/VideoViewer.tsx index 95878106..5b15f0ce 100644 --- a/src/Components/Preview/VideoViewer.tsx +++ b/src/Components/Preview/VideoViewer.tsx @@ -1,11 +1,11 @@ -import React from 'react'; +import React from "react"; export interface IVideoViewerProps { - filePath: string + filePath: string; } const VideoViewer = ({ filePath }: IVideoViewerProps): JSX.Element => { - return (
Video viewer: {filePath}
); -} + return
Video viewer: {filePath}
; +}; export default VideoViewer; diff --git a/src/Components/Preview/XlsxViewer.tsx b/src/Components/Preview/XlsxViewer.tsx index 0f06596b..2e1d8bf0 100644 --- a/src/Components/Preview/XlsxViewer.tsx +++ b/src/Components/Preview/XlsxViewer.tsx @@ -1,11 +1,11 @@ -import React from 'react'; +import React from "react"; export interface IXlsxViewerProps { - filePath: string + filePath: string; } const XlsxViewer = ({ filePath }: IXlsxViewerProps): JSX.Element => { - return (
Xlsx viewer: {filePath}
); -} + return
Xlsx viewer: {filePath}
; +}; export default XlsxViewer; diff --git a/src/Components/Preview/index.tsx b/src/Components/Preview/index.tsx index f6913830..78d10e40 100644 --- a/src/Components/Preview/index.tsx +++ b/src/Components/Preview/index.tsx @@ -1,67 +1,67 @@ -import React from 'react'; -import { useDispatch, useSelector } from 'react-redux'; +import React from "react"; +import { useDispatch, useSelector } from "react-redux"; // import xlsx from 'xlsx'; // import hljs from 'highlight.js'; // import { marked } from 'marked'; -import PdfViewer from './PdfViewer'; -import HtmlViewer from './HtmlViewer'; -import DocxViewer from './DocxViewer'; -import XlsxViewer from './XlsxViewer'; -import ImageViewer from './ImageViewer'; -import VideoViewer from './VideoViewer'; -import PlaintextViewer from './PlaintextViewer'; -import MarkdownViewer from './MarkdownViewer'; +import DocxViewer from "./DocxViewer"; +import HtmlViewer from "./HtmlViewer"; +import ImageViewer from "./ImageViewer"; +import MarkdownViewer from "./MarkdownViewer"; +import PdfViewer from "./PdfViewer"; +import PlaintextViewer from "./PlaintextViewer"; +import VideoViewer from "./VideoViewer"; +import XlsxViewer from "./XlsxViewer"; // import { readFileRequest, readAssetRequest, readBufferRequest } from '../../Store/ActionCreators/FilesActionCreators'; -import { IAppState } from '../../Store/Reducers'; -import { IFile } from '../../Typings/Store/files'; +import type { IAppState } from "../../Store/Reducers"; +import type { IFile } from "../../Typings/Store/files"; import { - IMAGE_TYPES, - VIDEO_TYPES, - PLAINTEXT_TYPES, - HTML_TYPES, - MARKDOWN_TYPES, - XLSX_TYPES, - DOCX_TYPES, - PDF_TYPES, - extensionMatches, -} from '../../Config/file.config'; + DOCX_TYPES, + HTML_TYPES, + IMAGE_TYPES, + MARKDOWN_TYPES, + PDF_TYPES, + PLAINTEXT_TYPES, + VIDEO_TYPES, + XLSX_TYPES, + extensionMatches, +} from "../../Config/file.config"; export interface IPreviewProps { - filePath: string; + filePath: string; } const Preview = ({ filePath }: IPreviewProps): JSX.Element => { - // const dispatch = useDispatch(); - const file = useSelector((state) => state.files.files?.[filePath]); + // const dispatch = useDispatch(); + const file = useSelector((state) => state.files.files?.[filePath]); - console.log(filePath.split('.')[filePath.split('.').length - 1]); + console.log(filePath.split(".")[filePath.split(".").length - 1]); - const filePathSplit = filePath.split('.'); - const extension = filePathSplit[filePathSplit.length - 1].toLowerCase(); + const filePathSplit = filePath.split("."); + const extension = filePathSplit[filePathSplit.length - 1].toLowerCase(); - if (extensionMatches(PDF_TYPES, extension)) { - return ; - } else if (extensionMatches(HTML_TYPES, extension)) { - return ; - } else if (extensionMatches(DOCX_TYPES, extension)) { - return ; - } else if (extensionMatches(XLSX_TYPES, extension)) { - return ; - } else if (extensionMatches(IMAGE_TYPES, extension)) { - return ; - } else if (extensionMatches(VIDEO_TYPES, extension)) { - return ; - } else if (extensionMatches(PLAINTEXT_TYPES, extension)) { - return ; - } else if (extensionMatches(MARKDOWN_TYPES, extension)) { - return ; - } else { - return
{JSON.stringify(file)}
; - } + if (extensionMatches(PDF_TYPES, extension)) { + return ; + } else if (extensionMatches(HTML_TYPES, extension)) { + return ; + } else if (extensionMatches(DOCX_TYPES, extension)) { + return ; + } else if (extensionMatches(XLSX_TYPES, extension)) { + return ; + } else if (extensionMatches(IMAGE_TYPES, extension)) { + return ; + } else if (extensionMatches(VIDEO_TYPES, extension)) { + return ; + } else if (extensionMatches(PLAINTEXT_TYPES, extension)) { + return ; + } else if (extensionMatches(MARKDOWN_TYPES, extension)) { + return ; + } else { + return
{JSON.stringify(file)}
; + } }; export default Preview; diff --git a/src/Components/Prompt/ask.ts b/src/Components/Prompt/ask.ts index 1912cb93..61237533 100644 --- a/src/Components/Prompt/ask.ts +++ b/src/Components/Prompt/ask.ts @@ -1,8 +1,8 @@ -import dragElement from '../Functions/dragElement'; +import dragElement from "../Functions/dragElement"; interface AskOptions { - value: string; - selectFileName?: boolean; + value: string; + selectFileName?: boolean; } /** * Prompt a dialog to ask something @@ -12,41 +12,41 @@ interface AskOptions { * @returns {any} */ const Ask = async (title: string, message: string, options?: AskOptions): Promise => { - document.querySelectorAll('.prompt').forEach((el) => el.parentNode.removeChild(el)); - const promptElement = document.createElement('div'); - promptElement.className = 'prompt'; - promptElement.innerHTML = `
+ document.querySelectorAll(".prompt").forEach((el) => el.parentNode.removeChild(el)); + const promptElement = document.createElement("div"); + promptElement.className = "prompt"; + promptElement.innerHTML = `
${title}
- ${message ? `
${message}
` : ''} - + ${message ? `
${message}
` : ""} +
`; - promptElement.querySelector('.prompt-exit-btn').addEventListener('click', () => promptElement.parentNode.removeChild(promptElement)); - promptElement.querySelector('.prompt-cancel').addEventListener('click', () => promptElement.parentNode.removeChild(promptElement)); + promptElement.querySelector(".prompt-exit-btn").addEventListener("click", () => promptElement.parentNode.removeChild(promptElement)); + promptElement.querySelector(".prompt-cancel").addEventListener("click", () => promptElement.parentNode.removeChild(promptElement)); - dragElement(promptElement.querySelector('.prompt-frame'), promptElement); - document.body.appendChild(promptElement); + dragElement(promptElement.querySelector(".prompt-frame"), promptElement); + document.body.appendChild(promptElement); - const promptInput = promptElement.querySelector('.prompt-input'); - if (options?.selectFileName ?? true) promptInput.setSelectionRange(0, promptInput.value.lastIndexOf('.')); - else promptInput.setSelectionRange(promptInput.value.length, promptInput.value.length); - promptInput.focus(); - return new Promise((resolve) => { - promptElement.querySelector('.prompt-ok').addEventListener('click', () => { - promptElement.parentNode.removeChild(promptElement); - resolve(promptInput.value); - }); - promptInput.onkeydown = (event: KeyboardEvent) => { - if (event.key === 'Enter') { - promptElement.parentNode.removeChild(promptElement); - resolve(promptInput.value); - } - }; - }); + const promptInput = promptElement.querySelector(".prompt-input"); + if (options?.selectFileName ?? true) promptInput.setSelectionRange(0, promptInput.value.lastIndexOf(".")); + else promptInput.setSelectionRange(promptInput.value.length, promptInput.value.length); + promptInput.focus(); + return new Promise((resolve) => { + promptElement.querySelector(".prompt-ok").addEventListener("click", () => { + promptElement.parentNode.removeChild(promptElement); + resolve(promptInput.value); + }); + promptInput.onkeydown = (event: KeyboardEvent) => { + if (event.key === "Enter") { + promptElement.parentNode.removeChild(promptElement); + resolve(promptInput.value); + } + }; + }); }; export default Ask; diff --git a/src/Components/Prompt/confirm.ts b/src/Components/Prompt/confirm.ts index c8f47684..04031f43 100644 --- a/src/Components/Prompt/confirm.ts +++ b/src/Components/Prompt/confirm.ts @@ -1,44 +1,44 @@ -import dragElement from '../Functions/dragElement'; -import { pauseEnter } from '../Shortcut/shortcut'; +import dragElement from "../Functions/dragElement"; +import { pauseEnter } from "../Shortcut/shortcut"; -const ConfirmDialog = (title: string, message: string, defaultValue?: 'Yes' | 'No'): Promise => { - return new Promise((resolve) => { - document.querySelectorAll('.prompt').forEach((el) => el.parentNode.removeChild(el)); - const promptElement = document.createElement('div'); - promptElement.className = 'prompt'; - promptElement.innerHTML = `
+const ConfirmDialog = (title: string, message: string, defaultValue?: "Yes" | "No"): Promise => { + return new Promise((resolve) => { + document.querySelectorAll(".prompt").forEach((el) => el.parentNode.removeChild(el)); + const promptElement = document.createElement("div"); + promptElement.className = "prompt"; + promptElement.innerHTML = `
${title}
- ${message ? `
${message}
` : ''} + ${message ? `
${message}
` : ""}
`; - promptElement.querySelector('.prompt-exit-btn').addEventListener('click', () => { - promptElement.parentNode.removeChild(promptElement); - resolve(false); - }); - promptElement.querySelector('.prompt-cancel').addEventListener('click', () => { - promptElement.parentNode.removeChild(promptElement); - resolve(false); - }); - promptElement.querySelector('.prompt-ok').addEventListener('click', () => { - promptElement.parentNode.removeChild(promptElement); - resolve(true); - }); - dragElement(promptElement.querySelector('.prompt-frame'), promptElement); - const keydownhandler = (event: KeyboardEvent) => { - if (event.key === 'Enter') { - pauseEnter(); - promptElement.parentNode.removeChild(promptElement); - document.removeEventListener('keydown', keydownhandler); - resolve(defaultValue === 'Yes'); - } - }; - document.addEventListener('keydown', keydownhandler); - document.body.appendChild(promptElement); - }); + promptElement.querySelector(".prompt-exit-btn").addEventListener("click", () => { + promptElement.parentNode.removeChild(promptElement); + resolve(false); + }); + promptElement.querySelector(".prompt-cancel").addEventListener("click", () => { + promptElement.parentNode.removeChild(promptElement); + resolve(false); + }); + promptElement.querySelector(".prompt-ok").addEventListener("click", () => { + promptElement.parentNode.removeChild(promptElement); + resolve(true); + }); + dragElement(promptElement.querySelector(".prompt-frame"), promptElement); + const keydownhandler = (event: KeyboardEvent) => { + if (event.key === "Enter") { + pauseEnter(); + promptElement.parentNode.removeChild(promptElement); + document.removeEventListener("keydown", keydownhandler); + resolve(defaultValue === "Yes"); + } + }; + document.addEventListener("keydown", keydownhandler); + document.body.appendChild(promptElement); + }); }; export default ConfirmDialog; diff --git a/src/Components/Prompt/error.ts b/src/Components/Prompt/error.ts index 6a7dfec7..f95fc0a5 100644 --- a/src/Components/Prompt/error.ts +++ b/src/Components/Prompt/error.ts @@ -1,28 +1,28 @@ -import beep from '../Functions/beep'; -import dragElement from '../Functions/dragElement'; -import { ErrorLog } from '../Functions/log'; +import beep from "../Functions/beep"; +import dragElement from "../Functions/dragElement"; +import { ErrorLog } from "../Functions/log"; const PromptError = (title: string, message: string): void => { - document.querySelectorAll('.prompt').forEach((el) => el.parentNode.removeChild(el)); - const promptElement = document.createElement('div'); - promptElement.className = 'prompt'; - promptElement.innerHTML = `
+ document.querySelectorAll(".prompt").forEach((el) => el.parentNode.removeChild(el)); + const promptElement = document.createElement("div"); + promptElement.className = "prompt"; + promptElement.innerHTML = `
${title}
- ${message ? `
${message}
` : ''} + ${message ? `
${message}
` : ""}
`; - promptElement.querySelector('.prompt-ok').addEventListener('click', () => promptElement.parentNode.removeChild(promptElement)); - document.body.appendChild(promptElement); - beep(); - dragElement(promptElement.querySelector('.prompt-frame'), promptElement); - ErrorLog(`[${title}] ${message}`); - document.addEventListener('keydown', (e) => { - if (e.key === 'Enter') { - promptElement.parentNode.removeChild(promptElement); - } - }); + promptElement.querySelector(".prompt-ok").addEventListener("click", () => promptElement.parentNode.removeChild(promptElement)); + document.body.appendChild(promptElement); + beep(); + dragElement(promptElement.querySelector(".prompt-frame"), promptElement); + ErrorLog(`[${title}] ${message}`); + document.addEventListener("keydown", (e) => { + if (e.key === "Enter") { + promptElement.parentNode.removeChild(promptElement); + } + }); }; export default PromptError; diff --git a/src/Components/Properties/index.tsx b/src/Components/Properties/index.tsx index 3abf6147..3b50e36f 100644 --- a/src/Components/Properties/index.tsx +++ b/src/Components/Properties/index.tsx @@ -1,13 +1,13 @@ -import React from 'react'; +import React from "react"; const Properties = () => ( -
-
- Properties - × +
+
+ Properties + × +
+
-
-
); export default Properties; diff --git a/src/Components/Properties/properties.ts b/src/Components/Properties/properties.ts index 09dfafb8..79b10468 100644 --- a/src/Components/Properties/properties.ts +++ b/src/Components/Properties/properties.ts @@ -1,31 +1,31 @@ -import formatBytes from '../Functions/filesize'; -import DirectoryAPI from '../../Service/directory'; -import FileAPI from '../../Service/files'; +import DirectoryAPI from "../../Service/directory"; +import FileAPI from "../../Service/files"; +import formatBytes from "../Functions/filesize"; /** * Render file/folder properties into HTML * @param {Record} options - File/folder's properties */ const RenderProperties = (options: Record) => { - const PROPERTIES_ELEMENT = document.querySelector('.properties'); - const PROPERTIES_BODY = PROPERTIES_ELEMENT.querySelector('.properties-body'); - PROPERTIES_ELEMENT.querySelector('.properties-heading-exit').addEventListener('click', () => { - PROPERTIES_ELEMENT.style.animation = 'close-properties 1s forwards'; - }); - PROPERTIES_ELEMENT.style.animation = 'properties 1s forwards'; + const PROPERTIES_ELEMENT = document.querySelector(".properties"); + const PROPERTIES_BODY = PROPERTIES_ELEMENT.querySelector(".properties-body"); + PROPERTIES_ELEMENT.querySelector(".properties-heading-exit").addEventListener("click", () => { + PROPERTIES_ELEMENT.style.animation = "close-properties 1s forwards"; + }); + PROPERTIES_ELEMENT.style.animation = "properties 1s forwards"; - let table: string; - table = ''; - Object.keys(options).forEach((key) => { - if (options[key] !== '') { - const value = - options[key] === 'calculating' - ? `` - : ``; - table += `${value}`; - } - }); - table += ''; - PROPERTIES_BODY.innerHTML = table; + let table: string; + table = '
Calculating...${options[key]}
${key}:
'; + Object.keys(options).forEach((key) => { + if (options[key] !== "") { + const value = + options[key] === "calculating" + ? `` + : ``; + table += `${value}`; + } + }); + table += ""; + PROPERTIES_BODY.innerHTML = table; }; /** * Show properties of a file @@ -33,52 +33,52 @@ const RenderProperties = (options: Record) => { * @returns {void} */ const Properties = async (filePath: string): Promise => { - const fileElement = document.querySelector(`[data-path="${encodeURI(filePath)}"]`); + const fileElement = document.querySelector(`[data-path="${encodeURI(filePath)}"]`); - let size, createdAt, modifiedAt, accessedAt, fileType, isHidden, isSystem, isReadonly; + let size, createdAt, modifiedAt, accessedAt, fileType, isHidden, isSystem, isReadonly; - if (fileElement.classList.contains('file')) { - size = fileElement.querySelector('.file-size').innerHTML; - if (fileElement.dataset.realPath) filePath = fileElement.dataset.realPath; - createdAt = fileElement.dataset.createdAt; - modifiedAt = fileElement.dataset.modifiedAt; - accessedAt = fileElement.dataset.accessedAt; - fileType = fileElement.querySelector('.file-type').innerHTML; - isHidden = fileElement.dataset.isHidden === 'true'; - isSystem = fileElement.dataset.isSystem === 'true'; - isReadonly = fileElement.dataset.isReadonly === 'true'; - } else { - const fileInfo = await new FileAPI(filePath).properties(); - size = formatBytes(fileInfo.size); - createdAt = String(new Date(fileInfo.created.secs_since_epoch * 1000).toLocaleString(navigator.language, { hour12: false })); - modifiedAt = String(new Date(fileInfo.last_modified.secs_since_epoch * 1000).toLocaleString(navigator.language, { hour12: false })); - accessedAt = String(new Date(fileInfo.last_accessed.secs_since_epoch * 1000).toLocaleString(navigator.language, { hour12: false })); - isHidden = fileInfo.is_hidden; - isSystem = fileInfo.is_system; - isReadonly = fileInfo.readonly; - fileType = 'File Folder'; - } - const file_attrs = []; - if (isHidden) file_attrs.push('Hidden'); - if (isSystem) file_attrs.push('System file'); - if (isReadonly) file_attrs.push('Read only'); - const isDirectory = fileElement.dataset.isDir === 'true'; - const file_attr = file_attrs.join(', '); - if (isDirectory) { - new DirectoryAPI(filePath).getSize().then((size) => { - document.querySelector(`[data-calculating="size"]`).innerHTML = formatBytes(size); - }); - } + if (fileElement.classList.contains("file")) { + size = fileElement.querySelector(".file-size").innerHTML; + if (fileElement.dataset.realPath) filePath = fileElement.dataset.realPath; + createdAt = fileElement.dataset.createdAt; + modifiedAt = fileElement.dataset.modifiedAt; + accessedAt = fileElement.dataset.accessedAt; + fileType = fileElement.querySelector(".file-type").innerHTML; + isHidden = fileElement.dataset.isHidden === "true"; + isSystem = fileElement.dataset.isSystem === "true"; + isReadonly = fileElement.dataset.isReadonly === "true"; + } else { + const fileInfo = await new FileAPI(filePath).properties(); + size = formatBytes(fileInfo.size); + createdAt = String(new Date(fileInfo.created.secs_since_epoch * 1000).toLocaleString(navigator.language, { hour12: false })); + modifiedAt = String(new Date(fileInfo.last_modified.secs_since_epoch * 1000).toLocaleString(navigator.language, { hour12: false })); + accessedAt = String(new Date(fileInfo.last_accessed.secs_since_epoch * 1000).toLocaleString(navigator.language, { hour12: false })); + isHidden = fileInfo.is_hidden; + isSystem = fileInfo.is_system; + isReadonly = fileInfo.readonly; + fileType = "File Folder"; + } + const file_attrs = []; + if (isHidden) file_attrs.push("Hidden"); + if (isSystem) file_attrs.push("System file"); + if (isReadonly) file_attrs.push("Read only"); + const isDirectory = fileElement.dataset.isDir === "true"; + const file_attr = file_attrs.join(", "); + if (isDirectory) { + new DirectoryAPI(filePath).getSize().then((size) => { + document.querySelector(`[data-calculating="size"]`).innerHTML = formatBytes(size); + }); + } - RenderProperties({ - Size: size ? size : 'calculating', - 'File Path': filePath, - 'File Type': fileType, - 'Created At': createdAt, - 'Modified At': modifiedAt, - 'Accessed At': accessedAt, - 'File Attribute': file_attr, - }); + RenderProperties({ + Size: size ? size : "calculating", + "File Path": filePath, + "File Type": fileType, + "Created At": createdAt, + "Modified At": modifiedAt, + "Accessed At": accessedAt, + "File Attribute": file_attr, + }); }; export default Properties; diff --git a/src/Components/Setting/About/about.ts b/src/Components/Setting/About/about.ts index 968a5865..43414383 100644 --- a/src/Components/Setting/About/about.ts +++ b/src/Components/Setting/About/about.ts @@ -1,25 +1,25 @@ -import { getTauriVersion } from '@tauri-apps/api/app'; -import { version, description } from '../../../../package.json'; -import { os } from '@tauri-apps/api'; +import { os } from "@tauri-apps/api"; +import { getTauriVersion } from "@tauri-apps/api/app"; +import { description, version } from "../../../../package.json"; // Copy text into clipboard const copyToClipboard = (text: string) => { - return `navigator.clipboard.writeText('${text}')`; + return `navigator.clipboard.writeText('${text}')`; }; /** * Create about section * @returns {Promise} */ const About = async (): Promise => { - const settingsMain = document.querySelector('.settings-main'); - const tauriVersion = await getTauriVersion(); - const platform = await os.platform(); - const arch = await os.arch(); - const osVersion = await os.version(); - const aboutPage = ` + const settingsMain = document.querySelector(".settings-main"); + const tauriVersion = await getTauriVersion(); + const platform = await os.platform(); + const arch = await os.arch(); + const osVersion = await os.version(); + const aboutPage = `
- +

Xplorer

${description}
@@ -29,7 +29,7 @@ const About = async (): Promise => { Version: ${version} @@ -37,7 +37,7 @@ const About = async (): Promise => { Tauri version: ${tauriVersion} @@ -45,7 +45,7 @@ const About = async (): Promise => { OS: ${platform} ${arch} ${osVersion} @@ -79,6 +79,6 @@ const About = async (): Promise => {
`; - settingsMain.innerHTML = aboutPage; + settingsMain.innerHTML = aboutPage; }; export default About; diff --git a/src/Components/Setting/Appearance/Appearance.ts b/src/Components/Setting/Appearance/Appearance.ts index 72f4cfcd..d29c223d 100644 --- a/src/Components/Setting/Appearance/Appearance.ts +++ b/src/Components/Setting/Appearance/Appearance.ts @@ -1,111 +1,111 @@ -import { reload, minimize, maximize, close } from '../../Layout/windowManager'; -import Translate from '../../I18n/i18n'; -import Storage from '../../../Service/storage'; -import OS, { isWin11 } from '../../../Service/platform'; -import { changeTransparentEffect, getAvailableFonts, enableShadowEffect } from '../../../Service/app'; -import { getElementStyle, getInstalledThemes, updateTheme } from '../../Theme/theme'; -import { setDecorations } from '../../../Service/window'; -import Infobar from '../../Layout/infobar'; -import isTauri from '../../../Util/is-tauri'; +import { changeTransparentEffect, enableShadowEffect, getAvailableFonts } from "../../../Service/app"; +import OS, { isWin11 } from "../../../Service/platform"; +import Storage from "../../../Service/storage"; +import { setDecorations } from "../../../Service/window"; +import isTauri from "../../../Util/is-tauri"; +import Translate from "../../I18n/i18n"; +import Infobar from "../../Layout/infobar"; +import { close, maximize, minimize, reload } from "../../Layout/windowManager"; +import { getElementStyle, getInstalledThemes, updateTheme } from "../../Theme/theme"; let platform: string; /** * Create appearence section * @returns {Promise} */ const Appearance = async (): Promise => { - if (!platform) { - platform = await OS(); - } - const developingTheme = document.body.dataset.usingCustomTheme === 'true'; - const _theme = await Storage.get('theme'); - const _appearance = await Storage.get('appearance'); - const theme = _theme?.theme; - const shadowEffect = _appearance?.shadowEffect ?? true; - const layout = _appearance?.layout ?? 's'; - const videoAsThumbnail = _appearance?.videoAsThumbnail ?? false; - const imageAsThumbnail = _appearance?.imageAsThumbnail ?? 'smalldir'; - const extractExeIcon = _appearance?.extractExeIcon ?? false; - const previewImageOnHover = _appearance?.previewImageOnHover ?? true; - const settingsMain = document.querySelector('.settings-main'); - const fontFamily = _appearance?.fontFamily ?? getElementStyle('fontFamily'); - const fontSize = parseInt(_appearance?.fontSize ?? 16); - const windowTransparency = parseInt(_appearance?.windowTransparency ?? 80); - const transparentEffect = _appearance?.transparentEffect ?? 'none'; - const transparentSidebar = _appearance?.transparentSidebar ?? true; - const transparentTopbar = _appearance?.transparentTopbar ?? false; - const transparentWorkspace = _appearance?.transparentWorkspace ?? false; - const frameStyle = _appearance?.frameStyle ?? 'default'; - const showInfoBar = _appearance?.showInfoBar ?? true; + if (!platform) { + platform = await OS(); + } + const developingTheme = document.body.dataset.usingCustomTheme === "true"; + const _theme = await Storage.get("theme"); + const _appearance = await Storage.get("appearance"); + const theme = _theme?.theme; + const shadowEffect = _appearance?.shadowEffect ?? true; + const layout = _appearance?.layout ?? "s"; + const videoAsThumbnail = _appearance?.videoAsThumbnail ?? false; + const imageAsThumbnail = _appearance?.imageAsThumbnail ?? "smalldir"; + const extractExeIcon = _appearance?.extractExeIcon ?? false; + const previewImageOnHover = _appearance?.previewImageOnHover ?? true; + const settingsMain = document.querySelector(".settings-main"); + const fontFamily = _appearance?.fontFamily ?? getElementStyle("fontFamily"); + const fontSize = Number.parseInt(_appearance?.fontSize ?? 16); + const windowTransparency = Number.parseInt(_appearance?.windowTransparency ?? 80); + const transparentEffect = _appearance?.transparentEffect ?? "none"; + const transparentSidebar = _appearance?.transparentSidebar ?? true; + const transparentTopbar = _appearance?.transparentTopbar ?? false; + const transparentWorkspace = _appearance?.transparentWorkspace ?? false; + const frameStyle = _appearance?.frameStyle ?? "default"; + const showInfoBar = _appearance?.showInfoBar ?? true; - const installedThemes = await getInstalledThemes(); - const availableThemes = [ - { name: 'Light', identifier: 'light' }, - { name: 'Dark', identifier: 'dark' }, - { name: 'Light+', identifier: 'light+' }, - { name: 'Dark+', identifier: 'dark+' }, - ].concat(...installedThemes.map((theme) => [{ name: theme.name, identifier: theme.identifier }])); - const availableFonts = await getAvailableFonts(); - const default_i18n = await Translate('Default'); - const appTheme_i18n = await Translate('App Theme'); - const shadowEffect_i18n = await Translate('Apply Shadow Effect'); - const filePreview_i18n = await Translate('File Preview'); - const defaultFileLayout_i18n = await Translate('Default File Layout'); - const gridViewSmall_i18n = await Translate('Grid View (Small)'); - const gridViewMedium_i18n = await Translate('Grid View (Medium)'); - const gridViewLarge_i18n = await Translate('Grid View (Large)'); - const detailView_i18n = await Translate('Detail View'); - const systemDefault_i18n = await Translate('System Default'); - const imageAsThumbnail_i18n = await Translate('Show image as thumbnail'); - const disabled_i18n = await Translate('Disabled'); - const forSmallDirectory_i18n = await Translate('For small directory (recommended)'); - const enableForAllDirectory_i18n = await Translate('Enable for all directory'); - const videoAsThumbnail_i18n = await Translate('Automatically play video file as thumbnail (May consume high amount of RAM)'); - const extractExeIcon_i18n = await Translate('Extract exe file icon and make it as the thumbnail (Turning it on might crashes Xplorer)'); - const previewImageOnHover_i18n = await Translate('Preview image on hover'); - const fontFamily_i18n = await Translate('Font Family'); - const fontSize_i18n = await Translate('Font Size'); - const windowTransparency_i18n = await Translate('Window Transparency'); - const transparentEffect_i18n = await Translate('Transparent Effect'); - const blur_i18n = await Translate('Blur'); - const acrylic_i18n = await Translate('Acrylic'); - const mica_i18n = await Translate('Mica'); - const vibrancy_i18n = await Translate('Vibrancy'); - const none_i18n = await Translate('None'); - const transparentSidebar_i18n = await Translate('Transparent Sidebar'); - const transparentTopbar_i18n = await Translate('Transparent Topbar'); - const transparentWorkspace_i18n = await Translate('Transparent Workspace'); - const frameStyle_i18n = await Translate('Frame Style'); - const workspace_i18n = await Translate('Workspace'); - const showInfoBar_i18n = await Translate('Show Info Bar'); - const disabledForWeb = !isTauri ? 'disabled' : ''; - const appearancePage = `

${appTheme_i18n}

+ const installedThemes = await getInstalledThemes(); + const availableThemes = [ + { name: "Light", identifier: "light" }, + { name: "Dark", identifier: "dark" }, + { name: "Light+", identifier: "light+" }, + { name: "Dark+", identifier: "dark+" }, + ].concat(...installedThemes.map((theme) => [{ name: theme.name, identifier: theme.identifier }])); + const availableFonts = await getAvailableFonts(); + const default_i18n = await Translate("Default"); + const appTheme_i18n = await Translate("App Theme"); + const shadowEffect_i18n = await Translate("Apply Shadow Effect"); + const filePreview_i18n = await Translate("File Preview"); + const defaultFileLayout_i18n = await Translate("Default File Layout"); + const gridViewSmall_i18n = await Translate("Grid View (Small)"); + const gridViewMedium_i18n = await Translate("Grid View (Medium)"); + const gridViewLarge_i18n = await Translate("Grid View (Large)"); + const detailView_i18n = await Translate("Detail View"); + const systemDefault_i18n = await Translate("System Default"); + const imageAsThumbnail_i18n = await Translate("Show image as thumbnail"); + const disabled_i18n = await Translate("Disabled"); + const forSmallDirectory_i18n = await Translate("For small directory (recommended)"); + const enableForAllDirectory_i18n = await Translate("Enable for all directory"); + const videoAsThumbnail_i18n = await Translate("Automatically play video file as thumbnail (May consume high amount of RAM)"); + const extractExeIcon_i18n = await Translate("Extract exe file icon and make it as the thumbnail (Turning it on might crashes Xplorer)"); + const previewImageOnHover_i18n = await Translate("Preview image on hover"); + const fontFamily_i18n = await Translate("Font Family"); + const fontSize_i18n = await Translate("Font Size"); + const windowTransparency_i18n = await Translate("Window Transparency"); + const transparentEffect_i18n = await Translate("Transparent Effect"); + const blur_i18n = await Translate("Blur"); + const acrylic_i18n = await Translate("Acrylic"); + const mica_i18n = await Translate("Mica"); + const vibrancy_i18n = await Translate("Vibrancy"); + const none_i18n = await Translate("None"); + const transparentSidebar_i18n = await Translate("Transparent Sidebar"); + const transparentTopbar_i18n = await Translate("Transparent Topbar"); + const transparentWorkspace_i18n = await Translate("Transparent Workspace"); + const frameStyle_i18n = await Translate("Frame Style"); + const workspace_i18n = await Translate("Workspace"); + const showInfoBar_i18n = await Translate("Show Info Bar"); + const disabledForWeb = !isTauri ? "disabled" : ""; + const appearancePage = `

${appTheme_i18n}

${ - platform !== 'linux' - ? `
+ platform !== "linux" + ? `
` - : '' - } + : "" + }

${fontFamily_i18n}

${fontSize_i18n}

@@ -118,254 +118,259 @@ const Appearance = async (): Promise => {

${transparentEffect_i18n}

${frameStyle_i18n}

${filePreview_i18n}

${ - platform === 'win32' - ? ` + platform === "win32" + ? `
` - : '' - } + : "" + }

${imageAsThumbnail_i18n}

${defaultFileLayout_i18n}

${workspace_i18n}

`; - settingsMain.innerHTML = appearancePage; - settingsMain.querySelector('[name="shadow-effect"]')?.addEventListener('change', (event: Event & { target: HTMLInputElement }) => { - const shadowEffect = event.target.checked; - const appearance = _appearance ?? {}; - appearance.shadowEffect = shadowEffect; - enableShadowEffect(shadowEffect); - Storage.set('appearance', appearance); - }); - settingsMain.querySelectorAll('.number-ctrl').forEach((ctrl) => { - const number = ctrl.querySelector('.number-ctrl-input'); - ctrl.querySelector('.number-ctrl-minus').addEventListener('click', () => { - number.value = +number.value - 1 + ''; - const appearance = _appearance ?? {}; - appearance.fontSize = `${number.value}px`; - document.body.style.fontSize = `${number.value}px`; - document.documentElement.style.fontSize = `${number.value}px`; - Storage.set('appearance', appearance); - }); - ctrl.querySelector('.number-ctrl-plus').addEventListener('click', () => { - number.value = +number.value + 1 + ''; - const appearance = _appearance ?? {}; - appearance.fontSize = `${number.value}px`; - document.body.style.fontSize = `${number.value}px`; - document.documentElement.style.fontSize = `${number.value}px`; - Storage.set('appearance', appearance); - }); - }); + settingsMain.innerHTML = appearancePage; + settingsMain.querySelector('[name="shadow-effect"]')?.addEventListener("change", (event: Event & { target: HTMLInputElement }) => { + const shadowEffect = event.target.checked; + const appearance = _appearance ?? {}; + appearance.shadowEffect = shadowEffect; + enableShadowEffect(shadowEffect); + Storage.set("appearance", appearance); + }); + settingsMain.querySelectorAll(".number-ctrl").forEach((ctrl) => { + const number = ctrl.querySelector(".number-ctrl-input"); + ctrl.querySelector(".number-ctrl-minus").addEventListener("click", () => { + number.value = +number.value - 1 + ""; + const appearance = _appearance ?? {}; + appearance.fontSize = `${number.value}px`; + document.body.style.fontSize = `${number.value}px`; + document.documentElement.style.fontSize = `${number.value}px`; + Storage.set("appearance", appearance); + }); + ctrl.querySelector(".number-ctrl-plus").addEventListener("click", () => { + number.value = +number.value + 1 + ""; + const appearance = _appearance ?? {}; + appearance.fontSize = `${number.value}px`; + document.body.style.fontSize = `${number.value}px`; + document.documentElement.style.fontSize = `${number.value}px`; + Storage.set("appearance", appearance); + }); + }); - settingsMain.querySelector('.transparency-slider').addEventListener('input', (event: Event & { target: HTMLInputElement }) => { - const value = parseInt(event.target.value); - const appearance = _appearance ?? {}; - appearance.windowTransparency = `${value}%`; - document.getElementById('transparency-label').innerHTML = String(value); - if (appearance?.transparentSidebar ?? true) - document.body.style.setProperty('--sidebar-transparency', appearance?.windowTransparency ?? '0.8'); - if (appearance?.transparentWorkspace ?? false) - document.body.style.setProperty('--workspace-transparency', appearance?.windowTransparency ?? '0.8'); - if (appearance?.transparentTopbar ?? false) document.body.style.setProperty('--topbar-transparency', appearance?.windowTransparency ?? '0.8'); - Storage.set('appearance', appearance); - }); - settingsMain.querySelector('[name="transparent-sidebar"]').addEventListener('change', (event: Event & { target: HTMLInputElement }) => { - const value = event.target.checked; - const appearance = _appearance ?? {}; - appearance.transparentSidebar = value; - if (value) { - document.body.style.setProperty('--sidebar-transparency', appearance?.windowTransparency ?? '0.8'); - } else { - document.body.style.setProperty('--sidebar-transparency', '1'); - } - Storage.set('appearance', appearance); - }); - settingsMain.querySelector('[name="transparent-workspace"]').addEventListener('change', (event: Event & { target: HTMLInputElement }) => { - const value = event.target.checked; - const appearance = _appearance ?? {}; - appearance.transparentWorkspace = value; - if (value) { - document.body.style.setProperty('--workspace-transparency', appearance?.windowTransparency ?? '0.8'); - } else { - document.body.style.setProperty('--workspace-transparency', '1'); - } - Storage.set('appearance', appearance); - }); - settingsMain.querySelector('[name="transparent-topbar"]').addEventListener('change', (event: Event & { target: HTMLInputElement }) => { - const value = event.target.checked; - const appearance = _appearance ?? {}; - appearance.transparentTopbar = value; - if (value) { - document.body.style.setProperty('--topbar-transparency', appearance?.windowTransparency ?? '0.8'); - } else { - document.body.style.setProperty('--topbar-transparency', '1'); - } - Storage.set('appearance', appearance); - }); - settingsMain.querySelector('[name="transparent-effect"]').addEventListener('change', (event: Event & { target: HTMLInputElement }) => { - const appearance = _appearance ?? {}; - appearance.transparentEffect = event.target.value; - changeTransparentEffect(appearance.transparentEffect); - Storage.set('appearance', appearance); - }); - settingsMain.querySelector('[name="frame-style"]').addEventListener('change', (event: Event & { target: HTMLInputElement }) => { - const value = event.target.value; - const appearance = _appearance ?? {}; - appearance.frameStyle = value; - setDecorations(value === 'os'); - if (value === 'os') { - document.querySelector('.window-manager').parentNode.removeChild(document.querySelector('.window-manager')); - } else { - const windowManager = document.createElement('div'); - windowManager.classList.add('window-manager'); - windowManager.innerHTML = ` + settingsMain.querySelector(".transparency-slider").addEventListener("input", (event: Event & { target: HTMLInputElement }) => { + const value = Number.parseInt(event.target.value); + const appearance = _appearance ?? {}; + appearance.windowTransparency = `${value}%`; + document.getElementById("transparency-label").innerHTML = String(value); + if (appearance?.transparentSidebar ?? true) + document.body.style.setProperty("--sidebar-transparency", appearance?.windowTransparency ?? "0.8"); + if (appearance?.transparentWorkspace ?? false) + document.body.style.setProperty("--workspace-transparency", appearance?.windowTransparency ?? "0.8"); + if (appearance?.transparentTopbar ?? false) document.body.style.setProperty("--topbar-transparency", appearance?.windowTransparency ?? "0.8"); + Storage.set("appearance", appearance); + }); + settingsMain.querySelector('[name="transparent-sidebar"]').addEventListener("change", (event: Event & { target: HTMLInputElement }) => { + const value = event.target.checked; + const appearance = _appearance ?? {}; + appearance.transparentSidebar = value; + if (value) { + document.body.style.setProperty("--sidebar-transparency", appearance?.windowTransparency ?? "0.8"); + } else { + document.body.style.setProperty("--sidebar-transparency", "1"); + } + Storage.set("appearance", appearance); + }); + settingsMain.querySelector('[name="transparent-workspace"]').addEventListener("change", (event: Event & { target: HTMLInputElement }) => { + const value = event.target.checked; + const appearance = _appearance ?? {}; + appearance.transparentWorkspace = value; + if (value) { + document.body.style.setProperty("--workspace-transparency", appearance?.windowTransparency ?? "0.8"); + } else { + document.body.style.setProperty("--workspace-transparency", "1"); + } + Storage.set("appearance", appearance); + }); + settingsMain.querySelector('[name="transparent-topbar"]').addEventListener("change", (event: Event & { target: HTMLInputElement }) => { + const value = event.target.checked; + const appearance = _appearance ?? {}; + appearance.transparentTopbar = value; + if (value) { + document.body.style.setProperty("--topbar-transparency", appearance?.windowTransparency ?? "0.8"); + } else { + document.body.style.setProperty("--topbar-transparency", "1"); + } + Storage.set("appearance", appearance); + }); + settingsMain.querySelector('[name="transparent-effect"]').addEventListener("change", (event: Event & { target: HTMLInputElement }) => { + const appearance = _appearance ?? {}; + appearance.transparentEffect = event.target.value; + changeTransparentEffect(appearance.transparentEffect); + Storage.set("appearance", appearance); + }); + settingsMain.querySelector('[name="frame-style"]').addEventListener("change", (event: Event & { target: HTMLInputElement }) => { + const value = event.target.value; + const appearance = _appearance ?? {}; + appearance.frameStyle = value; + setDecorations(value === "os"); + if (value === "os") { + document.querySelector(".window-manager").parentNode.removeChild(document.querySelector(".window-manager")); + } else { + const windowManager = document.createElement("div"); + windowManager.classList.add("window-manager"); + windowManager.innerHTML = ` `; - document.querySelector('.tabs-manager').appendChild(windowManager); - // Minimize the screen - windowManager.querySelector('#minimize').addEventListener('click', minimize); - // Maximize the screen - windowManager.querySelector('#maximize').addEventListener('click', maximize); - // Exit window - windowManager.querySelector('#exit').addEventListener('click', close); - } - Storage.set('appearance', appearance); - }); - settingsMain.querySelector('[name="fontSize"]')?.addEventListener('input', (event: Event & { target: HTMLInputElement }) => { - const appearance = _appearance ?? {}; - appearance.fontSize = `${event.target.value}px`; - document.body.style.fontSize = `${event.target.value}px`; - document.documentElement.style.fontSize = `${parseInt(event.target.value)}px`; - Storage.set('appearance', appearance); - }); - settingsMain.querySelector('[name="theme"]')?.addEventListener('change', async (event: Event & { target: HTMLInputElement }) => { - const themes = (await Storage.get('theme')) ?? {}; - themes['theme'] = event.target.value; - Storage.set('theme', themes); - updateTheme('*'); - }); - settingsMain.querySelector('[name="font"]')?.addEventListener('change', (event: Event & { target: HTMLInputElement }) => { - const appearance = _appearance ?? {}; - appearance.fontFamily = event.target.value; - document.body.style.fontFamily = appearance.fontFamily; - Storage.set('appearance', appearance); - }); - settingsMain.querySelector('[name="layout"]')?.addEventListener('change', (event: Event & { target: HTMLInputElement }) => { - const appearance = _appearance ?? {}; - appearance.layout = event.target.value; - Storage.set('appearance', appearance); - reload(); - }); - settingsMain.querySelector(`[name="preview-video"]`)?.addEventListener('change', (event: Event & { target: HTMLInputElement }) => { - const appearance = _appearance ?? {}; - appearance.videoAsThumbnail = event.target.checked; - Storage.set('appearance', appearance); - reload(); - }); - settingsMain.querySelector(`[name="preview-image-on-hover"]`)?.addEventListener('change', (event: Event & { target: HTMLInputElement }) => { - const appearance = _appearance ?? {}; - appearance.previewImageOnHover = event.target.checked; - Storage.set('appearance', appearance); - reload(); - }); - settingsMain.querySelector(`[name="extract-exe-icon"]`)?.addEventListener('change', (event: Event & { target: HTMLInputElement }) => { - const appearance = _appearance ?? {}; - appearance.extractExeIcon = event.target.checked; - Storage.set('appearance', appearance); - reload(); - }); - settingsMain.querySelector('[name="imageAsThumbnail"]')?.addEventListener('change', (event: Event & { target: HTMLInputElement }) => { - const appearance = _appearance ?? {}; - appearance.imageAsThumbnail = event.target.value; - Storage.set('appearance', appearance); - reload(); - }); - settingsMain.querySelector('[name="show-info-bar"]').addEventListener('change', (event: Event & { target: HTMLInputElement }) => { - const value = event.target.checked; - const appearance = _appearance ?? {}; - appearance.showInfoBar = value; - Storage.set('appearance', appearance); - if (value) { - Infobar(); - reload(); - } else { - document.getElementById('infobar')?.parentNode?.removeChild?.(document.getElementById('infobar')); - } - }); + document.querySelector(".tabs-manager").appendChild(windowManager); + // Minimize the screen + windowManager.querySelector("#minimize").addEventListener("click", minimize); + // Maximize the screen + windowManager.querySelector("#maximize").addEventListener("click", maximize); + // Exit window + windowManager.querySelector("#exit").addEventListener("click", close); + } + Storage.set("appearance", appearance); + }); + settingsMain.querySelector('[name="fontSize"]')?.addEventListener("input", (event: Event & { target: HTMLInputElement }) => { + const appearance = _appearance ?? {}; + appearance.fontSize = `${event.target.value}px`; + document.body.style.fontSize = `${event.target.value}px`; + document.documentElement.style.fontSize = `${Number.parseInt(event.target.value)}px`; + Storage.set("appearance", appearance); + }); + settingsMain.querySelector('[name="theme"]')?.addEventListener("change", async (event: Event & { target: HTMLInputElement }) => { + const themes = (await Storage.get("theme")) ?? {}; + themes["theme"] = event.target.value; + Storage.set("theme", themes); + updateTheme("*"); + }); + settingsMain.querySelector('[name="font"]')?.addEventListener("change", (event: Event & { target: HTMLInputElement }) => { + const appearance = _appearance ?? {}; + appearance.fontFamily = event.target.value; + document.body.style.fontFamily = appearance.fontFamily; + Storage.set("appearance", appearance); + }); + settingsMain.querySelector('[name="layout"]')?.addEventListener("change", (event: Event & { target: HTMLInputElement }) => { + const appearance = _appearance ?? {}; + appearance.layout = event.target.value; + Storage.set("appearance", appearance); + reload(); + }); + settingsMain.querySelector(`[name="preview-video"]`)?.addEventListener("change", (event: Event & { target: HTMLInputElement }) => { + const appearance = _appearance ?? {}; + appearance.videoAsThumbnail = event.target.checked; + Storage.set("appearance", appearance); + reload(); + }); + settingsMain.querySelector(`[name="preview-image-on-hover"]`)?.addEventListener("change", (event: Event & { target: HTMLInputElement }) => { + const appearance = _appearance ?? {}; + appearance.previewImageOnHover = event.target.checked; + Storage.set("appearance", appearance); + reload(); + }); + settingsMain.querySelector(`[name="extract-exe-icon"]`)?.addEventListener("change", (event: Event & { target: HTMLInputElement }) => { + const appearance = _appearance ?? {}; + appearance.extractExeIcon = event.target.checked; + Storage.set("appearance", appearance); + reload(); + }); + settingsMain.querySelector('[name="imageAsThumbnail"]')?.addEventListener("change", (event: Event & { target: HTMLInputElement }) => { + const appearance = _appearance ?? {}; + appearance.imageAsThumbnail = event.target.value; + Storage.set("appearance", appearance); + reload(); + }); + settingsMain.querySelector('[name="show-info-bar"]').addEventListener("change", (event: Event & { target: HTMLInputElement }) => { + const value = event.target.checked; + const appearance = _appearance ?? {}; + appearance.showInfoBar = value; + Storage.set("appearance", appearance); + if (value) { + Infobar(); + reload(); + } else { + document.getElementById("infobar")?.parentNode?.removeChild?.(document.getElementById("infobar")); + } + }); }; export default Appearance; diff --git a/src/Components/Setting/Preference/preference.ts b/src/Components/Setting/Preference/preference.ts index c6ad0ed1..e5b5859b 100644 --- a/src/Components/Setting/Preference/preference.ts +++ b/src/Components/Setting/Preference/preference.ts @@ -1,98 +1,98 @@ -import { reload } from '../../Layout/windowManager'; -import Translate from '../../I18n/i18n'; -import LocalesAPI from '../../../Service/locales'; -import Storage from '../../../Service/storage'; -import { MAIN_BOX_ELEMENT } from '../../../Util/constants'; +import LocalesAPI from "../../../Service/locales"; +import Storage from "../../../Service/storage"; +import { MAIN_BOX_ELEMENT } from "../../../Util/constants"; +import Translate from "../../I18n/i18n"; +import { reload } from "../../Layout/windowManager"; let localesData: LocalesAPI; /** * Create preference section * @returns {Promise} */ const Preference = async (): Promise => { - if (!localesData) { - localesData = new LocalesAPI(); - localesData.build(); - } - const _preference = await Storage.get('preference'); - let language = _preference?.language ?? navigator.language; - if (Object.values(localesData.AVAILABLE_LOCALES).indexOf(language) === -1) language = 'en-US'; - const hideHiddenFiles = _preference?.hideHiddenFiles ?? true; - const hideSystemFiles = _preference?.hideSystemFiles ?? true; - const dirAlongsideFiles = _preference?.dirAlongsideFiles ?? false; - const detectDriveChange = _preference?.detectDriveChange ?? false; - const automaticallyChangePreviewFile = _preference?.automaticallyChangePreviewFile ?? true; - const settingsMain = document.querySelector('.settings-main'); - const on_startup = _preference?.on_startup ?? 'new'; - const clickToOpenSidebar = _preference?.clickToOpenSidebar ?? 'single'; - const clickToOpenHome = _preference?.clickToOpenHome ?? 'double'; - const clickToOpenFile = _preference?.clickToOpenFile ?? 'double'; - const calculateSubFolderSize = _preference?.calculateSubFolderSize ?? false; + if (!localesData) { + localesData = new LocalesAPI(); + localesData.build(); + } + const _preference = await Storage.get("preference"); + let language = _preference?.language ?? navigator.language; + if (Object.values(localesData.AVAILABLE_LOCALES).indexOf(language) === -1) language = "en-US"; + const hideHiddenFiles = _preference?.hideHiddenFiles ?? true; + const hideSystemFiles = _preference?.hideSystemFiles ?? true; + const dirAlongsideFiles = _preference?.dirAlongsideFiles ?? false; + const detectDriveChange = _preference?.detectDriveChange ?? false; + const automaticallyChangePreviewFile = _preference?.automaticallyChangePreviewFile ?? true; + const settingsMain = document.querySelector(".settings-main"); + const on_startup = _preference?.on_startup ?? "new"; + const clickToOpenSidebar = _preference?.clickToOpenSidebar ?? "single"; + const clickToOpenHome = _preference?.clickToOpenHome ?? "double"; + const clickToOpenFile = _preference?.clickToOpenFile ?? "double"; + const calculateSubFolderSize = _preference?.calculateSubFolderSize ?? false; - const appLanguage_i18n = await Translate('App Language'); - const fileAndFolders_i18n = await Translate('Files and Folders'); - const hideHiddenFiles_i18n = await Translate('Hide hidden files'); - const hideSystemFiles_i18n = await Translate('Hide system files'); - const dirAlongsideFiles_i18n = await Translate('List and sort directories alongside files'); - const on_startup_i18n = await Translate('On startup'); - const newTab_i18n = await Translate('New tab'); - const continuePreviousSession_i18n = await Translate('Continue previous session'); - const detectDriveChange_i18n = await Translate('Detect Drive Change'); - const automaticallyChangePreviewFile_i18n = await Translate('Automatically change preview file with selected file'); - const clickToOpen_i18n = await Translate('Single/Double Click to open a file'); - const clickToOpenSidebar_i18n = await Translate('Double click to open items under sidebar section'); - const clickToOpenHome_i18n = await Translate('Double click to open items under home section'); - const clickToOpenFile_i18n = await Translate('Double click to open files/folders'); - const calculateSubFolderSize_i18n = await Translate('Calculate sub folder size'); - const preferencePage = `

${appLanguage_i18n}

+ const appLanguage_i18n = await Translate("App Language"); + const fileAndFolders_i18n = await Translate("Files and Folders"); + const hideHiddenFiles_i18n = await Translate("Hide hidden files"); + const hideSystemFiles_i18n = await Translate("Hide system files"); + const dirAlongsideFiles_i18n = await Translate("List and sort directories alongside files"); + const on_startup_i18n = await Translate("On startup"); + const newTab_i18n = await Translate("New tab"); + const continuePreviousSession_i18n = await Translate("Continue previous session"); + const detectDriveChange_i18n = await Translate("Detect Drive Change"); + const automaticallyChangePreviewFile_i18n = await Translate("Automatically change preview file with selected file"); + const clickToOpen_i18n = await Translate("Single/Double Click to open a file"); + const clickToOpenSidebar_i18n = await Translate("Double click to open items under sidebar section"); + const clickToOpenHome_i18n = await Translate("Double click to open items under home section"); + const clickToOpenFile_i18n = await Translate("Double click to open files/folders"); + const calculateSubFolderSize_i18n = await Translate("Calculate sub folder size"); + const preferencePage = `

${appLanguage_i18n}

${fileAndFolders_i18n}

@@ -100,100 +100,100 @@ const Preference = async (): Promise => {

${clickToOpen_i18n}

${on_startup_i18n}

`; - settingsMain.innerHTML = preferencePage; - settingsMain.querySelector(`[name="language"]`).addEventListener('change', async (event: Event & { target: HTMLInputElement }) => { - const preference = (await Storage.get('preference')) ?? {}; - preference.language = event.target.value; - Storage.set('preference', preference); - reload(); + settingsMain.innerHTML = preferencePage; + settingsMain.querySelector(`[name="language"]`).addEventListener("change", async (event: Event & { target: HTMLInputElement }) => { + const preference = (await Storage.get("preference")) ?? {}; + preference.language = event.target.value; + Storage.set("preference", preference); + reload(); - document.querySelector('#sidebar-setting-btn-text').innerHTML = await Translate('Settings'); - Preference(); - }); - settingsMain.querySelector(`[name="hide-hidden-files"]`).addEventListener('change', async (event: Event & { target: HTMLInputElement }) => { - const preference = (await Storage.get('preference')) ?? {}; - preference.hideHiddenFiles = event.target.checked; - Storage.set('preference', preference); - MAIN_BOX_ELEMENT().dataset.hideHiddenFiles = String(event.target.checked); - }); - settingsMain.querySelector(`[name="hide-system-files"]`).addEventListener('change', async (event: Event & { target: HTMLInputElement }) => { - const preference = (await Storage.get('preference')) ?? {}; - preference.hideSystemFiles = event.target.checked; - Storage.set('preference', preference); - reload(); - }); - settingsMain.querySelector(`[name="dirAlongsideFiles"]`).addEventListener('change', async (event: Event & { target: HTMLInputElement }) => { - const preference = (await Storage.get('preference')) ?? {}; - preference.dirAlongsideFiles = event.target.checked; - Storage.set('preference', preference); - reload(); - }); - settingsMain.querySelector(`[name="detect-drive-change"]`).addEventListener('change', async (event: Event & { target: HTMLInputElement }) => { - const preference = (await Storage.get('preference')) ?? {}; - preference.detectDriveChange = event.target.checked; - Storage.set('preference', preference); - }); - settingsMain - .querySelector(`[name="automatically-change-preview-file"]`) - .addEventListener('change', async (event: Event & { target: HTMLInputElement }) => { - const preference = (await Storage.get('preference')) ?? {}; - preference.automaticallyChangePreviewFile = event.target.checked; - Storage.set('preference', preference); - }); - settingsMain - .querySelector(`[name="calculate-subfolder-size"]`) - .addEventListener('change', async (event: Event & { target: HTMLInputElement }) => { - const preference = (await Storage.get('preference')) ?? {}; - console.log(event.target); - preference.calculateSubFolderSize = event.target.checked; - Storage.set('preference', preference); - reload(); - }); - settingsMain.querySelector(`[name="click-to-open-sidebar"]`).addEventListener('change', async (event: Event & { target: HTMLInputElement }) => { - const preference = (await Storage.get('preference')) ?? {}; - preference.clickToOpenSidebar = event.target.checked ? 'double' : 'single'; - Storage.set('preference', preference); - }); - settingsMain.querySelector(`[name="click-to-open-home"]`).addEventListener('change', async (event: Event & { target: HTMLInputElement }) => { - const preference = (await Storage.get('preference')) ?? {}; - preference.clickToOpenHome = event.target.checked ? 'double' : 'single'; - Storage.set('preference', preference); - }); - settingsMain.querySelector(`[name="click-to-open-file"]`).addEventListener('change', async (event: Event & { target: HTMLInputElement }) => { - const preference = (await Storage.get('preference')) ?? {}; - preference.clickToOpenFile = event.target.checked ? 'double' : 'single'; - Storage.set('preference', preference); - }); - settingsMain.querySelector(`[name="on_startup"]`).addEventListener('change', async (event: Event & { target: HTMLInputElement }) => { - const preference = (await Storage.get('preference')) ?? {}; - preference.on_startup = event.target.value; - Storage.set('preference', preference); - reload(); - }); + document.querySelector("#sidebar-setting-btn-text").innerHTML = await Translate("Settings"); + Preference(); + }); + settingsMain.querySelector(`[name="hide-hidden-files"]`).addEventListener("change", async (event: Event & { target: HTMLInputElement }) => { + const preference = (await Storage.get("preference")) ?? {}; + preference.hideHiddenFiles = event.target.checked; + Storage.set("preference", preference); + MAIN_BOX_ELEMENT().dataset.hideHiddenFiles = String(event.target.checked); + }); + settingsMain.querySelector(`[name="hide-system-files"]`).addEventListener("change", async (event: Event & { target: HTMLInputElement }) => { + const preference = (await Storage.get("preference")) ?? {}; + preference.hideSystemFiles = event.target.checked; + Storage.set("preference", preference); + reload(); + }); + settingsMain.querySelector(`[name="dirAlongsideFiles"]`).addEventListener("change", async (event: Event & { target: HTMLInputElement }) => { + const preference = (await Storage.get("preference")) ?? {}; + preference.dirAlongsideFiles = event.target.checked; + Storage.set("preference", preference); + reload(); + }); + settingsMain.querySelector(`[name="detect-drive-change"]`).addEventListener("change", async (event: Event & { target: HTMLInputElement }) => { + const preference = (await Storage.get("preference")) ?? {}; + preference.detectDriveChange = event.target.checked; + Storage.set("preference", preference); + }); + settingsMain + .querySelector(`[name="automatically-change-preview-file"]`) + .addEventListener("change", async (event: Event & { target: HTMLInputElement }) => { + const preference = (await Storage.get("preference")) ?? {}; + preference.automaticallyChangePreviewFile = event.target.checked; + Storage.set("preference", preference); + }); + settingsMain + .querySelector(`[name="calculate-subfolder-size"]`) + .addEventListener("change", async (event: Event & { target: HTMLInputElement }) => { + const preference = (await Storage.get("preference")) ?? {}; + console.log(event.target); + preference.calculateSubFolderSize = event.target.checked; + Storage.set("preference", preference); + reload(); + }); + settingsMain.querySelector(`[name="click-to-open-sidebar"]`).addEventListener("change", async (event: Event & { target: HTMLInputElement }) => { + const preference = (await Storage.get("preference")) ?? {}; + preference.clickToOpenSidebar = event.target.checked ? "double" : "single"; + Storage.set("preference", preference); + }); + settingsMain.querySelector(`[name="click-to-open-home"]`).addEventListener("change", async (event: Event & { target: HTMLInputElement }) => { + const preference = (await Storage.get("preference")) ?? {}; + preference.clickToOpenHome = event.target.checked ? "double" : "single"; + Storage.set("preference", preference); + }); + settingsMain.querySelector(`[name="click-to-open-file"]`).addEventListener("change", async (event: Event & { target: HTMLInputElement }) => { + const preference = (await Storage.get("preference")) ?? {}; + preference.clickToOpenFile = event.target.checked ? "double" : "single"; + Storage.set("preference", preference); + }); + settingsMain.querySelector(`[name="on_startup"]`).addEventListener("change", async (event: Event & { target: HTMLInputElement }) => { + const preference = (await Storage.get("preference")) ?? {}; + preference.on_startup = event.target.value; + Storage.set("preference", preference); + reload(); + }); }; export default Preference; diff --git a/src/Components/Setting/setting.ts b/src/Components/Setting/setting.ts index 133dd183..babd266f 100644 --- a/src/Components/Setting/setting.ts +++ b/src/Components/Setting/setting.ts @@ -1,81 +1,81 @@ -import Translate from '../I18n/i18n'; -import fileThumbnail from '../Thumbnail/thumbnail'; -import Storage from '../../Service/storage'; +import Storage from "../../Service/storage"; +import Translate from "../I18n/i18n"; +import fileThumbnail from "../Thumbnail/thumbnail"; -import About from './About/about'; -import Appearance from './Appearance/Appearance'; -import Preference from './Preference/preference'; +import About from "./About/about"; +import Appearance from "./Appearance/Appearance"; +import Preference from "./Preference/preference"; /** * Setting initializer function * @returns {Promise} */ const Setting = async (): Promise => { - const settingsItem = ['Appearance', 'Preference', 'About']; - const defaultTab = settingsItem[0]; + const settingsItem = ["Appearance", "Preference", "About"]; + const defaultTab = settingsItem[0]; - const setActiveTab = (tab: string) => { - settingsItem.forEach((tabs: string) => { - if (tabs === tab) { - document.getElementById(tab.toLowerCase()).parentElement.classList.add('active'); - } else document.getElementById(tabs.toLowerCase()).parentElement.classList.remove('active'); - }); - Array.from(document.getElementsByClassName('settings-sidebar-item') as HTMLCollectionOf).forEach((element) => { - if (!element.classList.contains('active')) element.style.background = ''; - }); - }; + const setActiveTab = (tab: string) => { + settingsItem.forEach((tabs: string) => { + if (tabs === tab) { + document.getElementById(tab.toLowerCase()).parentElement.classList.add("active"); + } else document.getElementById(tabs.toLowerCase()).parentElement.classList.remove("active"); + }); + Array.from(document.getElementsByClassName("settings-sidebar-item") as HTMLCollectionOf).forEach((element) => { + if (!element.classList.contains("active")) element.style.background = ""; + }); + }; - document.querySelector('#sidebar-setting-btn').addEventListener('click', async () => { - document.querySelector('.settings').style.animation = 'open-setting 1s forwards'; - document.querySelector('.settings-sidebar-heading').innerHTML = await Translate('Settings'); - const settingsSidebarItems = document.querySelector('.settings-sidebar-items'); - settingsSidebarItems.innerHTML = ''; + document.querySelector("#sidebar-setting-btn").addEventListener("click", async () => { + document.querySelector(".settings").style.animation = "open-setting 1s forwards"; + document.querySelector(".settings-sidebar-heading").innerHTML = await Translate("Settings"); + const settingsSidebarItems = document.querySelector(".settings-sidebar-items"); + settingsSidebarItems.innerHTML = ""; - for (const item of settingsItem) { - const settingsItem = document.createElement('span'); - settingsItem.classList.add('settings-sidebar-item', 'sidebar-hover-effect'); - settingsItem.innerHTML = `${await Translate( - item - )}`; - settingsSidebarItems.appendChild(settingsItem); + for (const item of settingsItem) { + const settingsItem = document.createElement("span"); + settingsItem.classList.add("settings-sidebar-item", "sidebar-hover-effect"); + settingsItem.innerHTML = `${await Translate( + item, + )}`; + settingsSidebarItems.appendChild(settingsItem); - settingsItem.addEventListener('click', async () => { - setActiveTab(item); - switch (item) { - case 'Appearance': - Appearance(); - break; - case 'Preference': - Preference(); - break; - case 'About': - About(); - break; - } - const appearance = (await Storage.get('appearance')) ?? {}; - appearance['activeSettingsTab'] = item; - Storage.set('appearance', appearance); - }); - } - const appearance = (await Storage.get('appearance')) ?? {}; - const activeSettingsTab = appearance['activeSettingsTab'] ?? defaultTab; - setActiveTab(activeSettingsTab); - switch (activeSettingsTab) { - case 'Appearance': - Appearance(); - break; - case 'Preference': - Preference(); - break; - case 'About': - About(); - break; - } + settingsItem.addEventListener("click", async () => { + setActiveTab(item); + switch (item) { + case "Appearance": + Appearance(); + break; + case "Preference": + Preference(); + break; + case "About": + About(); + break; + } + const appearance = (await Storage.get("appearance")) ?? {}; + appearance["activeSettingsTab"] = item; + Storage.set("appearance", appearance); + }); + } + const appearance = (await Storage.get("appearance")) ?? {}; + const activeSettingsTab = appearance["activeSettingsTab"] ?? defaultTab; + setActiveTab(activeSettingsTab); + switch (activeSettingsTab) { + case "Appearance": + Appearance(); + break; + case "Preference": + Preference(); + break; + case "About": + About(); + break; + } - document.querySelector('.exit-setting-btn').addEventListener('click', () => { - document.querySelector('.settings').style.animation = 'close-setting 1s forwards'; - }); - }); + document.querySelector(".exit-setting-btn").addEventListener("click", () => { + document.querySelector(".settings").style.animation = "close-setting 1s forwards"; + }); + }); }; export default Setting; diff --git a/src/Components/SettingsView/index.tsx b/src/Components/SettingsView/index.tsx index 721954e8..e44b49d0 100644 --- a/src/Components/SettingsView/index.tsx +++ b/src/Components/SettingsView/index.tsx @@ -1,16 +1,16 @@ -import React from 'react'; +import React from "react"; const SettingsView = () => ( -
-
-
- - Settings -
-
+
+
+
+ + Settings +
+
+
+
-
-
); export default SettingsView; diff --git a/src/Components/Shortcut/shortcut.ts b/src/Components/Shortcut/shortcut.ts index fda87b61..d26e789b 100644 --- a/src/Components/Shortcut/shortcut.ts +++ b/src/Components/Shortcut/shortcut.ts @@ -1,32 +1,32 @@ -import { createNewTab, goBack, goForward } from '../Layout/tab'; -import focusingPath from '../Functions/focusingPath'; -import { OpenDir } from '../Open/open'; -import getDirname from '../Functions/path/dirname'; -import copyLocation from '../Files/File Operation/location'; -import { ChangeSelectedEvent, getSelected, Select, unselectAllSelected } from '../Files/File Operation/select'; -import Pin from '../Files/File Operation/pin'; -import New from '../Functions/new'; -import { createNewWindow } from '../../Service/window'; -import Storage from '../../Service/storage'; -import windowName from '../../Service/window'; -import FileAPI from '../../Service/files'; -import DirectoryAPI from '../../Service/directory'; -import reveal from '../../Service/reveal'; -import NormalizeSlash from '../Functions/path/normalizeSlash'; -import { reload } from '../Layout/windowManager'; -import Cut from '../Files/File Operation/cut'; -import Copy from '../Files/File Operation/copy'; -import Paste from '../Files/File Operation/paste'; -import toggleHiddenFiles from '../Functions/toggleHiddenFiles'; -import Rename from '../Files/File Operation/rename'; -import Undo from '../Files/File Operation/undo'; -import Redo from '../Files/File Operation/redo'; -import { Trash, PermanentDelete, Purge } from '../Files/File Operation/trash'; -import Properties from '../Properties/properties'; -import Preview, { closePreviewFile } from '../Files/File Preview/preview'; -import { ensureElementInViewPort } from '../Functions/viewport'; -import OperationAPI from '../../Service/operation'; -import { resizeSidebar } from '../Layout/resizer'; +import DirectoryAPI from "../../Service/directory"; +import FileAPI from "../../Service/files"; +import OperationAPI from "../../Service/operation"; +import reveal from "../../Service/reveal"; +import Storage from "../../Service/storage"; +import { createNewWindow } from "../../Service/window"; +import windowName from "../../Service/window"; +import Copy from "../Files/File Operation/copy"; +import Cut from "../Files/File Operation/cut"; +import copyLocation from "../Files/File Operation/location"; +import Paste from "../Files/File Operation/paste"; +import Pin from "../Files/File Operation/pin"; +import Redo from "../Files/File Operation/redo"; +import Rename from "../Files/File Operation/rename"; +import { ChangeSelectedEvent, Select, getSelected, unselectAllSelected } from "../Files/File Operation/select"; +import { PermanentDelete, Purge, Trash } from "../Files/File Operation/trash"; +import Undo from "../Files/File Operation/undo"; +import Preview, { closePreviewFile } from "../Files/File Preview/preview"; +import focusingPath from "../Functions/focusingPath"; +import New from "../Functions/new"; +import getDirname from "../Functions/path/dirname"; +import NormalizeSlash from "../Functions/path/normalizeSlash"; +import toggleHiddenFiles from "../Functions/toggleHiddenFiles"; +import { ensureElementInViewPort } from "../Functions/viewport"; +import { resizeSidebar } from "../Layout/resizer"; +import { createNewTab, goBack, goForward } from "../Layout/tab"; +import { reload } from "../Layout/windowManager"; +import { OpenDir } from "../Open/open"; +import Properties from "../Properties/properties"; let selectedAll = true; let pauseEnterListener = false; /** @@ -39,11 +39,11 @@ const getSelectedAllStatus = (): boolean => selectedAll; * @returns {void} */ const changeSelectedAllStatus = (): void => { - selectedAll = false; + selectedAll = false; }; const pauseEnter = (): void => { - pauseEnterListener = true; + pauseEnterListener = true; }; /** @@ -51,346 +51,346 @@ const pauseEnter = (): void => { * @returns {void} */ const Shortcut = (): void => { - const searchElement = document.querySelector('.search-bar'); - let searchingState = false; - let searchingFileName = ''; - let searchingFiles: HTMLElement[] | null = null; - let _searchListener: ReturnType | null = null; + const searchElement = document.querySelector(".search-bar"); + let searchingState = false; + let searchingFileName = ""; + let searchingFiles: HTMLElement[] | null = null; + let _searchListener: ReturnType | null = null; - const KeyUpShortcutsHandler = async (e: KeyboardEvent) => { - // Don't react if cursor is over input field - if (document.activeElement.tagName === 'INPUT') return; + const KeyUpShortcutsHandler = async (e: KeyboardEvent) => { + // Don't react if cursor is over input field + if (document.activeElement.tagName === "INPUT") return; - const isAlphanumeric = ['Key', 'Digit'].some((a) => e.code.startsWith(a)); - // Fast search for files - if (!e.ctrlKey && !e.shiftKey && !e.altKey && isAlphanumeric) { - const resetTimer = () => { - clearTimeout(_searchListener); - _searchListener = setTimeout(() => (searchingState = false), 400); - }; + const isAlphanumeric = ["Key", "Digit"].some((a) => e.code.startsWith(a)); + // Fast search for files + if (!e.ctrlKey && !e.shiftKey && !e.altKey && isAlphanumeric) { + const resetTimer = () => { + clearTimeout(_searchListener); + _searchListener = setTimeout(() => (searchingState = false), 400); + }; - const isMatchFile = (file: HTMLElement) => { - return file - .querySelector('#file-filename') - ?.textContent.toLowerCase() - .normalize('NFD') - .replace(/[\u0300-\u036f]/gu, '') - .startsWith(searchingFileName); - }; + const isMatchFile = (file: HTMLElement) => { + return file + .querySelector("#file-filename") + ?.textContent.toLowerCase() + .normalize("NFD") + .replace(/[\u0300-\u036f]/gu, "") + .startsWith(searchingFileName); + }; - const search = (files: HTMLElement[], isStateSwitcher = false) => { - if (isStateSwitcher) { - searchingState = true; - searchingFileName = ''; - } - searchingFileName += e.key.toLowerCase(); - searchElement.placeholder = '⚡ ' + searchingFileName; - searchingFiles = null; - resetTimer(); - unselectAllSelected(); - const file = files.find((file) => isMatchFile(file)); - if (!file) return; - Select(file, false, false); - ensureElementInViewPort(file); - }; + const search = (files: HTMLElement[], isStateSwitcher = false) => { + if (isStateSwitcher) { + searchingState = true; + searchingFileName = ""; + } + searchingFileName += e.key.toLowerCase(); + searchElement.placeholder = "⚡ " + searchingFileName; + searchingFiles = null; + resetTimer(); + unselectAllSelected(); + const file = files.find((file) => isMatchFile(file)); + if (!file) return; + Select(file, false, false); + ensureElementInViewPort(file); + }; - const navigate = (files: HTMLElement[]) => { - searchingFiles ||= files.filter((file) => isMatchFile(file)); - const fileIndex = searchingFiles.findIndex((file) => { - return file.classList.contains('selected'); - }); - unselectAllSelected(); - const fileNext = searchingFiles[fileIndex + 1] || searchingFiles[0]; - if (!fileNext) return; - Select(fileNext, false, false); - ensureElementInViewPort(fileNext); - }; + const navigate = (files: HTMLElement[]) => { + searchingFiles ||= files.filter((file) => isMatchFile(file)); + const fileIndex = searchingFiles.findIndex((file) => { + return file.classList.contains("selected"); + }); + unselectAllSelected(); + const fileNext = searchingFiles[fileIndex + 1] || searchingFiles[0]; + if (!fileNext) return; + Select(fileNext, false, false); + ensureElementInViewPort(fileNext); + }; - const files = [...document.querySelectorAll('.file')]; - if (searchingState) search(files); - else if (e.key.toLowerCase() === searchingFileName.at(-1)) navigate(files); - else search(files, true); - return; - } + const files = [...document.querySelectorAll(".file")]; + if (searchingState) search(files); + else if (e.key.toLowerCase() === searchingFileName.at(-1)) navigate(files); + else search(files, true); + return; + } - searchingState = false; - searchingFileName = ''; - searchingFiles = null; - clearTimeout(_searchListener); - searchElement.placeholder = '🔎 Search'; + searchingState = false; + searchingFileName = ""; + searchingFiles = null; + clearTimeout(_searchListener); + searchElement.placeholder = "🔎 Search"; - const selectedFile = getSelected()?.[0]; - const selectedFilePath = decodeURI(selectedFile?.dataset?.path); - const isDir = selectedFile?.dataset.isdir === 'true'; - const _focusingPath = await focusingPath(); + const selectedFile = getSelected()?.[0]; + const selectedFilePath = decodeURI(selectedFile?.dataset?.path); + const isDir = selectedFile?.dataset.isdir === "true"; + const _focusingPath = await focusingPath(); - // Open file shorcut (Enter) - if (e.key === 'Enter') { - for (const selected of getSelected()) { - const targetPath = decodeURI(selected.dataset.path) === 'undefined' ? _focusingPath : decodeURI(selected.dataset.path); - if ((await new DirectoryAPI(targetPath).exists()) && !pauseEnterListener) { - // Open file in vscode (Shift + Enter) - if (e.shiftKey) { - reveal(targetPath, 'vscode'); - } else { - if (isDir) { - OpenDir(targetPath); - } else { - new FileAPI(targetPath).openFile(); - } - } - } else pauseEnterListener = false; - } - } - // Collapse sidebar (Ctrl + B) - if (e.ctrlKey && e.key === 'b') { - resizeSidebar(); - } - // Duplicate file (Ctrl + D) - if (e.ctrlKey && e.key === 'd') { - new OperationAPI(selectedFilePath).duplicate(); - } - // New tab shortcut (Ctrl + T) - else if (e.key === 't' && e.ctrlKey) { - createNewTab(); - } - // New window shortcut (Ctrl + N) - else if (e.key === 'n' && e.ctrlKey) { - createNewWindow(); - } - // New file shortcut (Alt + N) - else if (e.key === 'n' && e.altKey && !e.shiftKey) { - New('file'); - } - // New folder shortcut (Shift + N) - else if (e.key === 'N' && !e.altKey && e.shiftKey) { - New('folder'); - } + // Open file shorcut (Enter) + if (e.key === "Enter") { + for (const selected of getSelected()) { + const targetPath = decodeURI(selected.dataset.path) === "undefined" ? _focusingPath : decodeURI(selected.dataset.path); + if ((await new DirectoryAPI(targetPath).exists()) && !pauseEnterListener) { + // Open file in vscode (Shift + Enter) + if (e.shiftKey) { + reveal(targetPath, "vscode"); + } else { + if (isDir) { + OpenDir(targetPath); + } else { + new FileAPI(targetPath).openFile(); + } + } + } else pauseEnterListener = false; + } + } + // Collapse sidebar (Ctrl + B) + if (e.ctrlKey && e.key === "b") { + resizeSidebar(); + } + // Duplicate file (Ctrl + D) + if (e.ctrlKey && e.key === "d") { + new OperationAPI(selectedFilePath).duplicate(); + } + // New tab shortcut (Ctrl + T) + else if (e.key === "t" && e.ctrlKey) { + createNewTab(); + } + // New window shortcut (Ctrl + N) + else if (e.key === "n" && e.ctrlKey) { + createNewWindow(); + } + // New file shortcut (Alt + N) + else if (e.key === "n" && e.altKey && !e.shiftKey) { + New("file"); + } + // New folder shortcut (Shift + N) + else if (e.key === "N" && !e.altKey && e.shiftKey) { + New("folder"); + } - // Open in terminal shortcut (Alt + T) - else if (e.altKey && e.key === 't') { - const _to_reveal = NormalizeSlash(selectedFilePath && selectedFilePath !== 'undefined' ? selectedFilePath : _focusingPath); - if (_to_reveal.startsWith('xplorer://')) return; - reveal(_to_reveal, 'terminal'); - } - // Pin to sidebar shortcut (Alt+P) - else if (e.altKey && e.key === 'p') { - let filePaths = []; - for (const element of getSelected()) { - filePaths.push(decodeURI(element.dataset.path)); - } - if (!filePaths.length) filePaths = [_focusingPath]; - Pin(filePaths); - } + // Open in terminal shortcut (Alt + T) + else if (e.altKey && e.key === "t") { + const _to_reveal = NormalizeSlash(selectedFilePath && selectedFilePath !== "undefined" ? selectedFilePath : _focusingPath); + if (_to_reveal.startsWith("xplorer://")) return; + reveal(_to_reveal, "terminal"); + } + // Pin to sidebar shortcut (Alt+P) + else if (e.altKey && e.key === "p") { + let filePaths = []; + for (const element of getSelected()) { + filePaths.push(decodeURI(element.dataset.path)); + } + if (!filePaths.length) filePaths = [_focusingPath]; + Pin(filePaths); + } - // Copy file shortcut (Ctrl + C) - else if (e.ctrlKey && e.key === 'c') { - const filePaths = []; - for (const element of getSelected()) { - filePaths.push(decodeURI(element.dataset.path)); - } - Copy(filePaths); - } + // Copy file shortcut (Ctrl + C) + else if (e.ctrlKey && e.key === "c") { + const filePaths = []; + for (const element of getSelected()) { + filePaths.push(decodeURI(element.dataset.path)); + } + Copy(filePaths); + } - // Toggle hidden files shortcut (Ctrl+H) - else if (e.ctrlKey && e.key === 'h') { - toggleHiddenFiles(); - } - // Open file in preview shortcut (Ctrl+O) - else if (e.ctrlKey && e.key === 'o') { - if (document.querySelectorAll('.preview').length > 0) { - closePreviewFile(); - } else Preview(selectedFilePath); - } + // Toggle hidden files shortcut (Ctrl+H) + else if (e.ctrlKey && e.key === "h") { + toggleHiddenFiles(); + } + // Open file in preview shortcut (Ctrl+O) + else if (e.ctrlKey && e.key === "o") { + if (document.querySelectorAll(".preview").length > 0) { + closePreviewFile(); + } else Preview(selectedFilePath); + } - // Exit tab shortcut (Ctrl + W) - else if (e.ctrlKey && e.key === 'w') { - const tabs = await Storage.get(`tabs-${windowName}`); + // Exit tab shortcut (Ctrl + W) + else if (e.ctrlKey && e.key === "w") { + const tabs = await Storage.get(`tabs-${windowName}`); - if (document.querySelectorAll('.tab').length === 1) { - close(); - } else { - const tab = document.getElementById(`tab${tabs.focus}`); - tab.parentElement.removeChild(tab); - tabs.focusHistory = tabs.focusHistory.filter((tabIndex: number) => String(tabIndex) !== tabs.focus); - delete tabs.tabs[tabs.focus]; - tabs.focus = String(tabs.focusHistory[tabs.focusHistory.length - 1]); - Storage.set(`tabs-${windowName}`, tabs); - OpenDir(tabs.tabs[tabs.focus].position); + if (document.querySelectorAll(".tab").length === 1) { + close(); + } else { + const tab = document.getElementById(`tab${tabs.focus}`); + tab.parentElement.removeChild(tab); + tabs.focusHistory = tabs.focusHistory.filter((tabIndex: number) => String(tabIndex) !== tabs.focus); + delete tabs.tabs[tabs.focus]; + tabs.focus = String(tabs.focusHistory[tabs.focusHistory.length - 1]); + Storage.set(`tabs-${windowName}`, tabs); + OpenDir(tabs.tabs[tabs.focus].position); - const tabsManager = document.querySelector('.tabs-manager'); - if (tabsManager.scrollWidth > tabsManager.clientWidth) tabsManager.removeAttribute('data-tauri-drag-region'); - else tabsManager.setAttribute('data-tauri-drag-region', ''); - } - } - // Copy file shortcut (Ctrl + V) - else if (e.ctrlKey && e.key === 'v') { - Paste(_focusingPath); - } - // Copy file shortcut (Ctrl + X) - else if (e.ctrlKey && e.key === 'x') { - const filePaths = []; - for (const element of getSelected()) { - filePaths.push(decodeURI(element.dataset.path)); - } - Cut(filePaths); - } - // Undo file action (Ctrl+Z) - else if (e.ctrlKey && e.key === 'z') { - Undo(); - } - // Redo file action (Ctrl+Shift+Z OR Ctrl+Y) - else if ((e.ctrlKey && e.shiftKey && e.key === 'Z') || (e.ctrlKey && e.key === 'y')) { - Redo(); - } - // Previous tab shortcut (Alt+Arrow Left) - else if (e.altKey && e.key === 'ArrowLeft') { - goBack(); - } + const tabsManager = document.querySelector(".tabs-manager"); + if (tabsManager.scrollWidth > tabsManager.clientWidth) tabsManager.removeAttribute("data-tauri-drag-region"); + else tabsManager.setAttribute("data-tauri-drag-region", ""); + } + } + // Copy file shortcut (Ctrl + V) + else if (e.ctrlKey && e.key === "v") { + Paste(_focusingPath); + } + // Copy file shortcut (Ctrl + X) + else if (e.ctrlKey && e.key === "x") { + const filePaths = []; + for (const element of getSelected()) { + filePaths.push(decodeURI(element.dataset.path)); + } + Cut(filePaths); + } + // Undo file action (Ctrl+Z) + else if (e.ctrlKey && e.key === "z") { + Undo(); + } + // Redo file action (Ctrl+Shift+Z OR Ctrl+Y) + else if ((e.ctrlKey && e.shiftKey && e.key === "Z") || (e.ctrlKey && e.key === "y")) { + Redo(); + } + // Previous tab shortcut (Alt+Arrow Left) + else if (e.altKey && e.key === "ArrowLeft") { + goBack(); + } - // Next tab shortcut (Alt+Arrow Right) - else if (e.altKey && e.key === 'ArrowRight') { - goForward(); - } + // Next tab shortcut (Alt+Arrow Right) + else if (e.altKey && e.key === "ArrowRight") { + goForward(); + } - // Go to parent directory (Alt + Arrow Up) - else if (e.altKey && e.key === 'ArrowUp') { - const _dirPath = getDirname(_focusingPath); - if (!_focusingPath.startsWith('xplorer://') && _dirPath !== '.') OpenDir(_dirPath); - } + // Go to parent directory (Alt + Arrow Up) + else if (e.altKey && e.key === "ArrowUp") { + const _dirPath = getDirname(_focusingPath); + if (!_focusingPath.startsWith("xplorer://") && _dirPath !== ".") OpenDir(_dirPath); + } - // Copy location path (Alt + Shift + C) - else if (e.altKey && e.shiftKey && e.key === 'C') { - copyLocation(selectedFile); - } + // Copy location path (Alt + Shift + C) + else if (e.altKey && e.shiftKey && e.key === "C") { + copyLocation(selectedFile); + } - // Rename file shortcut (F2) - else if (e.key === 'F2') { - if (selectedFile) Rename(selectedFilePath); - } - // Delete file shortcut (Del) - else if (e.key === 'Delete') { - if (e.shiftKey) { - const filePaths = []; - for (const element of getSelected()) { - filePaths.push(decodeURI(element.dataset.path)); - } - if (_focusingPath === 'xplorer://Trash') Purge(filePaths); - else PermanentDelete(filePaths); - } else { - if (_focusingPath === 'xplorer://Trash') return; - const filePaths = []; - for (const element of getSelected()) { - filePaths.push(decodeURI(element.dataset.path)); - } - Trash(filePaths); - } - } else if (e.keyCode >= 65 && e.keyCode <= 90) { - // ignore some keys that has its own function - if (e.ctrlKey && (e.key === 'a' || e.key === 'p' || e.key === 'f')) return; - clearInterval(_searchListener); - if (e.key.toLowerCase() === searchingFileName.at(-1)) { - const _files = [...document.querySelectorAll('.file')].filter((file: HTMLElement) => { - return file - .querySelector('#file-filename') - .innerHTML.toLowerCase() - .normalize('NFD') - .replace(/[\u0300-\u036f]/g, '') - .startsWith(searchingFileName); - }); - for (let i = 0; i < _files.length; i++) { - const _file = _files[i]; - if (_file.classList.contains('selected')) { - unselectAllSelected(); - Select((_files[i + 1] ?? _files[0]) as HTMLElement, false, false); - break; - } - } - } else { - searchingFileName += e.key.toLowerCase(); + // Rename file shortcut (F2) + else if (e.key === "F2") { + if (selectedFile) Rename(selectedFilePath); + } + // Delete file shortcut (Del) + else if (e.key === "Delete") { + if (e.shiftKey) { + const filePaths = []; + for (const element of getSelected()) { + filePaths.push(decodeURI(element.dataset.path)); + } + if (_focusingPath === "xplorer://Trash") Purge(filePaths); + else PermanentDelete(filePaths); + } else { + if (_focusingPath === "xplorer://Trash") return; + const filePaths = []; + for (const element of getSelected()) { + filePaths.push(decodeURI(element.dataset.path)); + } + Trash(filePaths); + } + } else if (e.keyCode >= 65 && e.keyCode <= 90) { + // ignore some keys that has its own function + if (e.ctrlKey && (e.key === "a" || e.key === "p" || e.key === "f")) return; + clearInterval(_searchListener); + if (e.key.toLowerCase() === searchingFileName.at(-1)) { + const _files = [...document.querySelectorAll(".file")].filter((file: HTMLElement) => { + return file + .querySelector("#file-filename") + .innerHTML.toLowerCase() + .normalize("NFD") + .replace(/[\u0300-\u036f]/g, "") + .startsWith(searchingFileName); + }); + for (let i = 0; i < _files.length; i++) { + const _file = _files[i]; + if (_file.classList.contains("selected")) { + unselectAllSelected(); + Select((_files[i + 1] ?? _files[0]) as HTMLElement, false, false); + break; + } + } + } else { + searchingFileName += e.key.toLowerCase(); - const _files = document.querySelectorAll('.file'); - unselectAllSelected(); - for (const _file of _files) { - const _fileName = _file.querySelector('#file-filename').innerHTML.toLowerCase(); - console.log(_fileName.normalize('NFD').replace(/[\u0300-\u036f]/g, '')); - if ( - _fileName - .normalize('NFD') - .replace(/[\u0300-\u036f]/g, '') - .startsWith(searchingFileName) - ) { - Select(_file as HTMLElement, false, false); - ensureElementInViewPort(_file as HTMLElement); - ChangeSelectedEvent(); - break; - } - } - } + const _files = document.querySelectorAll(".file"); + unselectAllSelected(); + for (const _file of _files) { + const _fileName = _file.querySelector("#file-filename").innerHTML.toLowerCase(); + console.log(_fileName.normalize("NFD").replace(/[\u0300-\u036f]/g, "")); + if ( + _fileName + .normalize("NFD") + .replace(/[\u0300-\u036f]/g, "") + .startsWith(searchingFileName) + ) { + Select(_file as HTMLElement, false, false); + ensureElementInViewPort(_file as HTMLElement); + ChangeSelectedEvent(); + break; + } + } + } - _searchListener = setInterval(() => { - searchingFileName = ''; - clearInterval(_searchListener); - }, 750); - } - }; - const KeyDownShortcutsHandler = async (e: KeyboardEvent) => { - // Don't react if cursor is over input field - if (document.activeElement.tagName === 'INPUT') return; - // Select all shortcut (Ctrl + A) - if (e.key === 'a' && e.ctrlKey) { - e.preventDefault(); - selectedAll = !selectedAll; - if (selectedAll) { - document.querySelectorAll('.file').forEach((element) => element.classList.add('selected')); - } else document.querySelectorAll('.file').forEach((element) => element.classList.remove('selected')); - ChangeSelectedEvent(); - } + _searchListener = setInterval(() => { + searchingFileName = ""; + clearInterval(_searchListener); + }, 750); + } + }; + const KeyDownShortcutsHandler = async (e: KeyboardEvent) => { + // Don't react if cursor is over input field + if (document.activeElement.tagName === "INPUT") return; + // Select all shortcut (Ctrl + A) + if (e.key === "a" && e.ctrlKey) { + e.preventDefault(); + selectedAll = !selectedAll; + if (selectedAll) { + document.querySelectorAll(".file").forEach((element) => element.classList.add("selected")); + } else document.querySelectorAll(".file").forEach((element) => element.classList.remove("selected")); + ChangeSelectedEvent(); + } - // File properties (Ctrl+P) - else if (e.ctrlKey && e.key === 'p') { - e.preventDefault(); - const selectedFile = getSelected()?.[0]; - const selectedFilePath = decodeURI(selectedFile?.dataset?.path); - Properties(selectedFilePath === 'undefined' ? await focusingPath() : selectedFilePath); - } - // Find files (Ctrl+F) - else if (e.ctrlKey && e.key === 'f') { - e.preventDefault(); - searchElement.select(); - searchElement.focus(); - } - // Internal Reload (F5) - if (e.key === 'F5') { - e.preventDefault(); - reload(); - } - }; + // File properties (Ctrl+P) + else if (e.ctrlKey && e.key === "p") { + e.preventDefault(); + const selectedFile = getSelected()?.[0]; + const selectedFilePath = decodeURI(selectedFile?.dataset?.path); + Properties(selectedFilePath === "undefined" ? await focusingPath() : selectedFilePath); + } + // Find files (Ctrl+F) + else if (e.ctrlKey && e.key === "f") { + e.preventDefault(); + searchElement.select(); + searchElement.focus(); + } + // Internal Reload (F5) + if (e.key === "F5") { + e.preventDefault(); + reload(); + } + }; - const MouseShortcutsHandler = (e: MouseEvent) => { - // Don't react if cursor is over input field - if (document.activeElement.tagName === 'INPUT') return; + const MouseShortcutsHandler = (e: MouseEvent) => { + // Don't react if cursor is over input field + if (document.activeElement.tagName === "INPUT") return; - switch (e.button) { - // Back button - case 3: - goBack(); - break; - // Forward button - case 4: - goForward(); - break; - } - }; + switch (e.button) { + // Back button + case 3: + goBack(); + break; + // Forward button + case 4: + goForward(); + break; + } + }; - document.addEventListener('keyup', KeyUpShortcutsHandler); - document.addEventListener('keydown', KeyDownShortcutsHandler); - document.addEventListener('mouseup', MouseShortcutsHandler); + document.addEventListener("keyup", KeyUpShortcutsHandler); + document.addEventListener("keydown", KeyDownShortcutsHandler); + document.addEventListener("mouseup", MouseShortcutsHandler); - window.addEventListener('beforeunload', () => { - document.removeEventListener('keyup', KeyUpShortcutsHandler, false); - document.removeEventListener('keydown', KeyDownShortcutsHandler, false); - document.removeEventListener('mouseup', MouseShortcutsHandler); - }); + window.addEventListener("beforeunload", () => { + document.removeEventListener("keyup", KeyUpShortcutsHandler, false); + document.removeEventListener("keydown", KeyDownShortcutsHandler, false); + document.removeEventListener("mouseup", MouseShortcutsHandler); + }); }; export { Shortcut, changeSelectedAllStatus, getSelectedAllStatus, pauseEnter }; diff --git a/src/Components/Sidebar/index.tsx b/src/Components/Sidebar/index.tsx index cbf5c70b..676e0ac3 100644 --- a/src/Components/Sidebar/index.tsx +++ b/src/Components/Sidebar/index.tsx @@ -2,8 +2,8 @@ import React from "react"; import { useDispatch, useSelector } from "react-redux"; import { setActiveTab, updateTab } from "../../Store/ActionCreators/TabActionCreators"; -import { IAppState } from "../../Store/Reducers"; -import { IFavoritesReducerState } from "../../Typings/Store/favorites"; +import type { IAppState } from "../../Store/Reducers"; +import type { IFavoritesReducerState } from "../../Typings/Store/favorites"; import XplorerLogo from "../../Icon/extension/xplorer.svg"; import FavoriteLogo from "../../Icon/folder/sidebar-favorite.svg"; diff --git a/src/Components/Thumbnail/thumbnail.ts b/src/Components/Thumbnail/thumbnail.ts index c3532015..e503b0fc 100644 --- a/src/Components/Thumbnail/thumbnail.ts +++ b/src/Components/Thumbnail/thumbnail.ts @@ -1,13 +1,13 @@ -import { customThumbnail, defaultThumbnail } from '../../Config/folder.config'; -import { IMAGE_TYPES, VIDEO_TYPES } from '../../Config/file.config'; -import getBasename from '../Functions/path/basename'; -import Storage from '../../Service/storage'; -import FileAPI from '../../Service/files'; -import FileLib from '../../../lib/files.json'; -import FolderLib from '../../../lib/folder.json'; -import ThumbnailExtensionTrie from './thumbnailExtensionTrie'; -import ThumbnailFileTrie from './thumbnailFileTrie'; -import ThumbnailFolderTrie from './thumbnailFolderTrie'; +import FileLib from "../../../lib/files.json"; +import FolderLib from "../../../lib/folder.json"; +import { IMAGE_TYPES, VIDEO_TYPES } from "../../Config/file.config"; +import { customThumbnail, defaultThumbnail } from "../../Config/folder.config"; +import FileAPI from "../../Service/files"; +import Storage from "../../Service/storage"; +import getBasename from "../Functions/path/basename"; +import ThumbnailExtensionTrie from "./thumbnailExtensionTrie"; +import ThumbnailFileTrie from "./thumbnailFileTrie"; +import ThumbnailFolderTrie from "./thumbnailFolderTrie"; let trieInitilized = false; const extensionThumbnailTrie = new ThumbnailExtensionTrie(); @@ -24,10 +24,10 @@ const DEFAULT_IMAGE_THUMBNAIL = require(`../../Icon/${defaultThumbnail.DEFAULT_I * @returns {string} HTML Result */ const imageThumbnail = async (source: string, HTMLFormat?: boolean, isImg = false): Promise => { - if (!HTMLFormat) return (await new FileAPI(source).exists()) ? new FileAPI(source).readAsset() : require(`../../Icon/${source}`); - return source?.startsWith('data:image/') - ? `` - : ``; + if (!HTMLFormat) return (await new FileAPI(source).exists()) ? new FileAPI(source).readAsset() : require(`../../Icon/${source}`); + return source?.startsWith("data:image/") + ? `` + : ``; }; /** @@ -36,11 +36,11 @@ const imageThumbnail = async (source: string, HTMLFormat?: boolean, isImg = fals * @returns {string} HTML Result */ const videoPreview = async (filename: string): Promise => { - const appearance = await Storage.get('appearance'); - const alt = require(`../../Icon/${defaultThumbnail.DEFAULT_VIDEO_THUMBNAIL}`); - return appearance?.videoAsThumbnail - ? `` - : imageThumbnail(alt, true); + const appearance = await Storage.get("appearance"); + const alt = require(`../../Icon/${defaultThumbnail.DEFAULT_VIDEO_THUMBNAIL}`); + return appearance?.videoAsThumbnail + ? `` + : imageThumbnail(alt, true); }; /** * Get file icon of a file/folder @@ -50,67 +50,67 @@ const videoPreview = async (filename: string): Promise => { * @param {boolean} imageAsThumbnail - return image as thumbnail (optional) * @returns {Promise} the preview of the file/folder */ -const fileThumbnail = async (filePath: string, category = 'folder', HTMLFormat = true, imageAsThumbnail = true): Promise => { - if (!trieInitilized) { - for (const category of FileLib) { - if (category.extensions?.length && category.thumbnail) { - for (const extension of category.extensions) { - extensionThumbnailTrie.insert(extension, category.thumbnail); - } - } - if (category.fileNames?.length && category.thumbnail) { - for (const fileName of category.fileNames) { - filenameThumbnailTrie.insert(fileName, category.thumbnail); - } - } - } - for (const category of FolderLib) { - if (category.folderNames?.length && category.thumbnail) { - for (const folderName of category.folderNames) { - folderThumbnailTrie.insert(folderName, category.thumbnail); - } - } - } - trieInitilized = true; - } - if (category === 'file' && filePath.indexOf('.') === -1) return imageThumbnail(defaultThumbnail.DEFAULT_FILE_THUMBNAIL, HTMLFormat); - const ext = filePath.split('.').pop().toLowerCase(); // Get extension of filename - const basename = getBasename(filePath).toLowerCase(); - const appearance = await Storage.get('appearance'); - if (category === 'file') { - if (IMAGE_TYPES.indexOf(ext) !== -1) { - if (imageAsThumbnail) { - return imageThumbnail(filePath, HTMLFormat, true); - } else { - return imageThumbnail(DEFAULT_IMAGE_THUMBNAIL, HTMLFormat); - } - } else if (VIDEO_TYPES.indexOf(ext) !== -1) { - const assetSrc = new FileAPI(filePath).readAsset(); - return HTMLFormat ? await videoPreview(assetSrc) : assetSrc; - } else if ((appearance?.extractExeIcon ?? false) && (ext === 'exe' || ext === 'msi')) { - return imageThumbnail(await new FileAPI(filePath).extractIcon(), HTMLFormat, true); - } - } +const fileThumbnail = async (filePath: string, category = "folder", HTMLFormat = true, imageAsThumbnail = true): Promise => { + if (!trieInitilized) { + for (const category of FileLib) { + if (category.extensions?.length && category.thumbnail) { + for (const extension of category.extensions) { + extensionThumbnailTrie.insert(extension, category.thumbnail); + } + } + if (category.fileNames?.length && category.thumbnail) { + for (const fileName of category.fileNames) { + filenameThumbnailTrie.insert(fileName, category.thumbnail); + } + } + } + for (const category of FolderLib) { + if (category.folderNames?.length && category.thumbnail) { + for (const folderName of category.folderNames) { + folderThumbnailTrie.insert(folderName, category.thumbnail); + } + } + } + trieInitilized = true; + } + if (category === "file" && filePath.indexOf(".") === -1) return imageThumbnail(defaultThumbnail.DEFAULT_FILE_THUMBNAIL, HTMLFormat); + const ext = filePath.split(".").pop().toLowerCase(); // Get extension of filename + const basename = getBasename(filePath).toLowerCase(); + const appearance = await Storage.get("appearance"); + if (category === "file") { + if (IMAGE_TYPES.indexOf(ext) !== -1) { + if (imageAsThumbnail) { + return imageThumbnail(filePath, HTMLFormat, true); + } else { + return imageThumbnail(DEFAULT_IMAGE_THUMBNAIL, HTMLFormat); + } + } else if (VIDEO_TYPES.indexOf(ext) !== -1) { + const assetSrc = new FileAPI(filePath).readAsset(); + return HTMLFormat ? await videoPreview(assetSrc) : assetSrc; + } else if ((appearance?.extractExeIcon ?? false) && (ext === "exe" || ext === "msi")) { + return imageThumbnail(await new FileAPI(filePath).extractIcon(), HTMLFormat, true); + } + } - const filename = filePath.toLowerCase(); // Lowercase filename - if (category === 'contextmenu') { - return imageThumbnail(`contextmenu/${filePath + '.svg'}`); - } + const filename = filePath.toLowerCase(); // Lowercase filename + if (category === "contextmenu") { + return imageThumbnail(`contextmenu/${filePath + ".svg"}`); + } - if (category === 'file') { - return imageThumbnail( - filenameThumbnailTrie.search(basename) ?? extensionThumbnailTrie.search(ext) ?? defaultThumbnail.DEFAULT_FILE_THUMBNAIL, - HTMLFormat - ); - } else { - if (category !== 'folder') { - const _key = `${category}-${filename}`; - if (Object.keys(customThumbnail).indexOf(_key) !== -1) { - return imageThumbnail(customThumbnail[_key], HTMLFormat); - } - } - return imageThumbnail(folderThumbnailTrie.search(basename) ?? defaultThumbnail.DEFAULT_FOLDER_THUMBNAIL, HTMLFormat); - } + if (category === "file") { + return imageThumbnail( + filenameThumbnailTrie.search(basename) ?? extensionThumbnailTrie.search(ext) ?? defaultThumbnail.DEFAULT_FILE_THUMBNAIL, + HTMLFormat, + ); + } else { + if (category !== "folder") { + const _key = `${category}-${filename}`; + if (Object.keys(customThumbnail).indexOf(_key) !== -1) { + return imageThumbnail(customThumbnail[_key], HTMLFormat); + } + } + return imageThumbnail(folderThumbnailTrie.search(basename) ?? defaultThumbnail.DEFAULT_FOLDER_THUMBNAIL, HTMLFormat); + } }; export default fileThumbnail; diff --git a/src/Components/Thumbnail/thumbnailExtensionNode.ts b/src/Components/Thumbnail/thumbnailExtensionNode.ts index f9c3e469..4f88728d 100644 --- a/src/Components/Thumbnail/thumbnailExtensionNode.ts +++ b/src/Components/Thumbnail/thumbnailExtensionNode.ts @@ -1,13 +1,13 @@ class ThumbnailExtensionNode { - public _ch: string; - public _icon: string; - public _isLeaf: boolean; - public _children: ThumbnailExtensionNode[]; + public _ch: string; + public _icon: string; + public _isLeaf: boolean; + public _children: ThumbnailExtensionNode[]; - constructor(ch: string) { - this._ch = ch; - this._children = []; - } + constructor(ch: string) { + this._ch = ch; + this._children = []; + } } export default ThumbnailExtensionNode; diff --git a/src/Components/Thumbnail/thumbnailExtensionTrie.ts b/src/Components/Thumbnail/thumbnailExtensionTrie.ts index f3138ca5..1ce3cf0f 100644 --- a/src/Components/Thumbnail/thumbnailExtensionTrie.ts +++ b/src/Components/Thumbnail/thumbnailExtensionTrie.ts @@ -1,45 +1,45 @@ -import ThumbnailExtensionNode from './thumbnailExtensionNode'; +import ThumbnailExtensionNode from "./thumbnailExtensionNode"; class ThumbnailExtensionTrie { - public _root: ThumbnailExtensionNode; + public _root: ThumbnailExtensionNode; - constructor() { - this._root = new ThumbnailExtensionNode(''); - } + constructor() { + this._root = new ThumbnailExtensionNode(""); + } - insert(suffix: string, icon: string): void { - let node = this._root; - for (let i = 0; i < suffix.length; i++) { - let position = 0; - for (const child of node._children) { - if (child._ch === suffix[i]) break; - position++; - } - if (position < node._children.length) { - //find it - node = node._children[position]; - } else { - //not find, create new Node - node._children.push(new ThumbnailExtensionNode(suffix[i])); - node = node._children[position]; - } - } - node._isLeaf = true; - node._icon = icon; - } + insert(suffix: string, icon: string): void { + let node = this._root; + for (let i = 0; i < suffix.length; i++) { + let position = 0; + for (const child of node._children) { + if (child._ch === suffix[i]) break; + position++; + } + if (position < node._children.length) { + //find it + node = node._children[position]; + } else { + //not find, create new Node + node._children.push(new ThumbnailExtensionNode(suffix[i])); + node = node._children[position]; + } + } + node._isLeaf = true; + node._icon = icon; + } - search(suffix: string): string { - let node = this._root; - for (let i = 0; i < suffix.length; i++) { - for (const child of node._children) { - if (child._ch === suffix[i]) { - node = child; - } - } - } - if (node._isLeaf) return node._icon; - return null; - } + search(suffix: string): string { + let node = this._root; + for (let i = 0; i < suffix.length; i++) { + for (const child of node._children) { + if (child._ch === suffix[i]) { + node = child; + } + } + } + if (node._isLeaf) return node._icon; + return null; + } } export default ThumbnailExtensionTrie; diff --git a/src/Components/Thumbnail/thumbnailFileNode.ts b/src/Components/Thumbnail/thumbnailFileNode.ts index 3b7f8daa..bb1e721e 100644 --- a/src/Components/Thumbnail/thumbnailFileNode.ts +++ b/src/Components/Thumbnail/thumbnailFileNode.ts @@ -1,13 +1,13 @@ class ThumbnailFileNode { - public _ch: string; - public _icon: string; - public _isLeaf: boolean; - public _children: ThumbnailFileNode[]; + public _ch: string; + public _icon: string; + public _isLeaf: boolean; + public _children: ThumbnailFileNode[]; - constructor(ch: string) { - this._ch = ch; - this._children = []; - } + constructor(ch: string) { + this._ch = ch; + this._children = []; + } } export default ThumbnailFileNode; diff --git a/src/Components/Thumbnail/thumbnailFileTrie.ts b/src/Components/Thumbnail/thumbnailFileTrie.ts index 1043cdce..be0850ff 100644 --- a/src/Components/Thumbnail/thumbnailFileTrie.ts +++ b/src/Components/Thumbnail/thumbnailFileTrie.ts @@ -1,45 +1,45 @@ -import ThumbnailFileNode from './thumbnailFileNode'; +import ThumbnailFileNode from "./thumbnailFileNode"; class ThumbnailFileTrie { - public _root: ThumbnailFileNode; + public _root: ThumbnailFileNode; - constructor() { - this._root = new ThumbnailFileNode(''); - } + constructor() { + this._root = new ThumbnailFileNode(""); + } - insert(suffix: string, icon: string): void { - let node = this._root; - for (let i = 0; i < suffix.length; i++) { - let position = 0; - for (const child of node._children) { - if (child._ch === suffix[i]) break; - position++; - } - if (position < node._children.length) { - //find it - node = node._children[position]; - } else { - //not find, create new Node - node._children.push(new ThumbnailFileNode(suffix[i])); - node = node._children[position]; - } - } - node._isLeaf = true; - node._icon = icon; - } + insert(suffix: string, icon: string): void { + let node = this._root; + for (let i = 0; i < suffix.length; i++) { + let position = 0; + for (const child of node._children) { + if (child._ch === suffix[i]) break; + position++; + } + if (position < node._children.length) { + //find it + node = node._children[position]; + } else { + //not find, create new Node + node._children.push(new ThumbnailFileNode(suffix[i])); + node = node._children[position]; + } + } + node._isLeaf = true; + node._icon = icon; + } - search(suffix: string): string { - let node = this._root; - for (let i = 0; i < suffix.length; i++) { - for (const child of node._children) { - if (child._ch === suffix[i]) { - node = child; - } - } - } - if (node._isLeaf) return node._icon; - return null; - } + search(suffix: string): string { + let node = this._root; + for (let i = 0; i < suffix.length; i++) { + for (const child of node._children) { + if (child._ch === suffix[i]) { + node = child; + } + } + } + if (node._isLeaf) return node._icon; + return null; + } } export default ThumbnailFileTrie; diff --git a/src/Components/Thumbnail/thumbnailFolderNode.ts b/src/Components/Thumbnail/thumbnailFolderNode.ts index 9c0bb1ac..409c5faa 100644 --- a/src/Components/Thumbnail/thumbnailFolderNode.ts +++ b/src/Components/Thumbnail/thumbnailFolderNode.ts @@ -1,13 +1,13 @@ class ThumbnailFolderNode { - public _ch: string; - public _icon: string; - public _isLeaf: boolean; - public _children: ThumbnailFolderNode[]; + public _ch: string; + public _icon: string; + public _isLeaf: boolean; + public _children: ThumbnailFolderNode[]; - constructor(ch: string) { - this._ch = ch; - this._children = []; - } + constructor(ch: string) { + this._ch = ch; + this._children = []; + } } export default ThumbnailFolderNode; diff --git a/src/Components/Thumbnail/thumbnailFolderTrie.ts b/src/Components/Thumbnail/thumbnailFolderTrie.ts index b5db4cce..8963673a 100644 --- a/src/Components/Thumbnail/thumbnailFolderTrie.ts +++ b/src/Components/Thumbnail/thumbnailFolderTrie.ts @@ -1,45 +1,45 @@ -import ThumbnailFolderNode from './thumbnailFolderNode'; +import ThumbnailFolderNode from "./thumbnailFolderNode"; class ThumbnailFolderTrie { - public _root: ThumbnailFolderNode; + public _root: ThumbnailFolderNode; - constructor() { - this._root = new ThumbnailFolderNode(''); - } + constructor() { + this._root = new ThumbnailFolderNode(""); + } - insert(suffix: string, icon: string): void { - let node = this._root; - for (let i = 0; i < suffix.length; i++) { - let position = 0; - for (const child of node._children) { - if (child._ch === suffix[i]) break; - position++; - } - if (position < node._children.length) { - //find it - node = node._children[position]; - } else { - //not find, create new Node - node._children.push(new ThumbnailFolderNode(suffix[i])); - node = node._children[position]; - } - } - node._isLeaf = true; - node._icon = icon; - } + insert(suffix: string, icon: string): void { + let node = this._root; + for (let i = 0; i < suffix.length; i++) { + let position = 0; + for (const child of node._children) { + if (child._ch === suffix[i]) break; + position++; + } + if (position < node._children.length) { + //find it + node = node._children[position]; + } else { + //not find, create new Node + node._children.push(new ThumbnailFolderNode(suffix[i])); + node = node._children[position]; + } + } + node._isLeaf = true; + node._icon = icon; + } - search(suffix: string): string { - let node = this._root; - for (let i = 0; i < suffix.length; i++) { - for (const child of node._children) { - if (child._ch === suffix[i]) { - node = child; - } - } - } - if (node._isLeaf) return node._icon; - return null; - } + search(suffix: string): string { + let node = this._root; + for (let i = 0; i < suffix.length; i++) { + for (const child of node._children) { + if (child._ch === suffix[i]) { + node = child; + } + } + } + if (node._isLeaf) return node._icon; + return null; + } } export default ThumbnailFolderTrie; diff --git a/src/Config/file.config.ts b/src/Config/file.config.ts index e8d46707..8fc239c9 100644 --- a/src/Config/file.config.ts +++ b/src/Config/file.config.ts @@ -1,10 +1,10 @@ -export const IMAGE_TYPES = ['jpg', 'png', 'gif', 'bmp', 'jpeg', 'jpe', 'jif', 'jfif', 'jfi', 'webp', 'tiff', 'tif', 'ico', 'svg', 'webp']; -export const VIDEO_TYPES = ['mp4', 'webm', 'mpg', 'mp2', 'mpeg', 'mpe', 'mpv', 'ocg', 'm4p', 'm4v', 'avi', 'wmv', 'mov', 'qt', 'flv', 'swf']; -export const PLAINTEXT_TYPES = ['txt']; -export const HTML_TYPES = ['html', 'htm', 'xhtml', 'html_vm', 'asp']; -export const MARKDOWN_TYPES = ['md', 'markdown', 'mdown', 'mkd', 'mkdown', 'mdwn', 'mdtxt', 'mdtext', 'text']; -export const XLSX_TYPES = ['xlsx', 'xls', 'xlsb', 'xls', 'ods', 'fods', 'csv']; -export const DOCX_TYPES = ['doc', 'docb', 'docm', 'dot', 'dotm', 'docx', 'rtf']; -export const PDF_TYPES = ['pdf']; +export const IMAGE_TYPES = ["jpg", "png", "gif", "bmp", "jpeg", "jpe", "jif", "jfif", "jfi", "webp", "tiff", "tif", "ico", "svg", "webp"]; +export const VIDEO_TYPES = ["mp4", "webm", "mpg", "mp2", "mpeg", "mpe", "mpv", "ocg", "m4p", "m4v", "avi", "wmv", "mov", "qt", "flv", "swf"]; +export const PLAINTEXT_TYPES = ["txt"]; +export const HTML_TYPES = ["html", "htm", "xhtml", "html_vm", "asp"]; +export const MARKDOWN_TYPES = ["md", "markdown", "mdown", "mkd", "mkdown", "mdwn", "mdtxt", "mdtext", "text"]; +export const XLSX_TYPES = ["xlsx", "xls", "xlsb", "xls", "ods", "fods", "csv"]; +export const DOCX_TYPES = ["doc", "docb", "docm", "dot", "dotm", "docx", "rtf"]; +export const PDF_TYPES = ["pdf"]; export const extensionMatches = (extList: string[], extension: string): boolean => extList.includes(extension); diff --git a/src/Config/folder.config.ts b/src/Config/folder.config.ts index d5b02246..8963e4e9 100644 --- a/src/Config/folder.config.ts +++ b/src/Config/folder.config.ts @@ -1,30 +1,30 @@ const defaultThumbnail = { - DEFAULT_FILE_THUMBNAIL: 'file.svg', - DEFAULT_FOLDER_THUMBNAIL: 'folder.svg', - DEFAULT_IMAGE_THUMBNAIL: 'extension/image.svg', - DEFAULT_VIDEO_THUMBNAIL: 'extension/video.svg', + DEFAULT_FILE_THUMBNAIL: "file.svg", + DEFAULT_FOLDER_THUMBNAIL: "folder.svg", + DEFAULT_IMAGE_THUMBNAIL: "extension/image.svg", + DEFAULT_VIDEO_THUMBNAIL: "extension/video.svg", }; interface customThumbnailType { - [key: string]: string; + [key: string]: string; } const customThumbnail: customThumbnailType = { - 'sidebar-about': 'folder/sidebar-about.svg', - 'sidebar-recent': 'folder/sidebar-recent.svg', - 'sidebar-favorites': 'folder/sidebar-favorite.svg', - 'sidebar-setting': 'folder/sidebar-setting.svg', - 'sidebar-trash': 'folder/sidebar-trash.svg', - 'sidebar-desktop': 'folder/sidebar-desktop.svg', - 'sidebar-home': 'folder/sidebar-home.svg', - 'sidebar-documents': 'folder/sidebar-document.svg', - 'sidebar-downloads': 'folder/sidebar-download.svg', - 'sidebar-music': 'folder/sidebar-music.svg', - 'sidebar-pictures': 'folder/sidebar-picture.svg', - 'sidebar-videos': 'folder/sidebar-video.svg', - 'settings-about': 'folder/setting-about.svg', - 'settings-appearance': 'folder/setting-appearance.svg', - 'settings-preference': 'folder/setting-preference.svg', - 'favorites-usb': 'usb.svg', - 'favorites-hard-disk': 'hard-disk.svg', + "sidebar-about": "folder/sidebar-about.svg", + "sidebar-recent": "folder/sidebar-recent.svg", + "sidebar-favorites": "folder/sidebar-favorite.svg", + "sidebar-setting": "folder/sidebar-setting.svg", + "sidebar-trash": "folder/sidebar-trash.svg", + "sidebar-desktop": "folder/sidebar-desktop.svg", + "sidebar-home": "folder/sidebar-home.svg", + "sidebar-documents": "folder/sidebar-document.svg", + "sidebar-downloads": "folder/sidebar-download.svg", + "sidebar-music": "folder/sidebar-music.svg", + "sidebar-pictures": "folder/sidebar-picture.svg", + "sidebar-videos": "folder/sidebar-video.svg", + "settings-about": "folder/setting-about.svg", + "settings-appearance": "folder/setting-appearance.svg", + "settings-preference": "folder/setting-preference.svg", + "favorites-usb": "usb.svg", + "favorites-hard-disk": "hard-disk.svg", }; export { customThumbnail, defaultThumbnail }; diff --git a/src/Locales/ar-SA.json b/src/Locales/ar-SA.json index 6e5f2b2a..0fbb0f5b 100644 --- a/src/Locales/ar-SA.json +++ b/src/Locales/ar-SA.json @@ -1,114 +1,114 @@ { - "Favorites": "المفضلات", - "Desktop": "سطح مكتب", - "Documents": "المستندات", - "Downloads": "التنزيلات", - "Pictures": "الصور", - "Music": "الموسيقى", - "Videos": "الفيديوهات", - "Icon": "الأيقونة", - "Show hidden files": "إظهار الملفات المخفية", - "Files": "الملفات", - "Pendrives": "Pendrives", - "Home": "Home", - "Recent": "Recent", - "Trash": "مهملات", - "Drives": "Drives", - "free of": "free of", - "Settings": "إعدادات", - "Appearance": "Appearance", - "App Theme": "App Theme", - "Apply Shadow Effect": "Apply Shadow Effect", - "File Preview": "File Preview", - "Default File Layout": "Default File Layout", - "Show image as thumbnail": "Show image as thumbnail", - "Disabled": "Disabled", - "For small directory (recommended)": "For small directory (recommended)", - "Enable for all directory": "Enable for all directory", - "System Default": "النظام الافتراضي", - "Automatically play video file as thumbnail (May consume high amount of RAM)": "Automatically play video file as thumbnail (May consume high amount of RAM)", - "Extract exe file icon and make it as the thumbnail (Turning it on might crashes Xplorer)": "Extract exe file icon and make it as the thumbnail (Turning it on might crashes Xplorer)", - "Preview image on hover": "Preview image on hover", - "Font Family": "Font Family", - "Font Size": "Font Size", - "Window Transparency": "Window Transparency", - "Transparent Effect": "Transparent Effect", - "Blur": "Blur", - "Acrylic": "Acrylic", - "Mica": "Mica", - "Vibrancy": "Vibrancy (MacOS)", - "None": "None", - "Transparent Sidebar": "Transparent Sidebar", - "Transparent Topbar": "Transparent Topbar", - "Transparent Workspace": "Transparent Workspace", - "Frame Style": "Frame Style", - "Default": "Default", - "Detect Drive Change": "Detect Drive Change", - "Automatically change preview file with selected file": "Automatically change preview file with selected file", - "Single/Double Click to open a file": "Single/Double Click to open a file", - "Double click to open items under sidebar section": "Double click to open items under sidebar section", - "Double click to open items under home section": "Double click to open items under home section", - "Double click to open files/folders": "Double click to open files/folders", - "Preference": "Preference", - "App Language": "لغة التطبيق", - "Files and Folders": "الملفات والمجلدات", - "Hide hidden files": "إخفاء الملفات المخفية", - "Hide system files": "Hide system files", - "List and sort directories alongside files": "List and sort directories alongside files", - "On startup": "On startup", - "New tab": "New tab", - "Continue previous session": "Continue previous session", - "Workspace": "Workspace", - "Show Info Bar": "Show Info Bar", - "About": "About", - "Layout Mode": "Layout Mode", - "Grid View (Large)": "Grid View (Large)", - "Grid View (Medium)": "Grid View (Medium)", - "Grid View (Small)": "Grid View (Small)", - "Detail View": "Detail View", - "Sort By": "Sort By", - "A-Z": "A-Z", - "Z-A": "Z-A", - "Last Modified": "Last Modified", - "First Modified": "First Modified", - "Size": "Size", - "Type": "Type", - "Reload": "Reload", - "Copy": "Copy", - "Cut": "Cut", - "Paste": "Paste", - "Undo Action": "Undo Action", - "Redo Action": "Redo Action", - "Copy Location Path": "Copy Location Path", - "Clear Recent List": "Clear Recent List", - "Open": "Open", - "Open in Terminal": "Open in Terminal", - "Open in VSCode": "Open in VSCode", - "New": "New", - "File": "File", - "Folder": "Folder", - "Unpin from Sidebar": "Unpin from Sidebar", - "Pin to Sidebar": "Pin to Sidebar", - "Compress to Zip": "Compress to Zip", - "Properties": "Properties", - "Rename": "Rename", - "Delete": "Delete", - "Restore": "Restore", - "Permanently Delete": "Permanently Delete", - "Open in New Tab": "Open in New Tab", - "Preview": "Preview", - "Restore all files": "Restore all files", - "Permanently delete all files": "Permanently delete all files", - "Restore these files": "Restore these files", - "Permanently delete these files": "Permanently delete these files", - "Calculate sub folder size": "Calculate sub folder size", - "Search": "Search", - "Minimize": "Minimize", - "Maximize": "Maximize", - "Exit (Ctrl + w)": "Exit (Ctrl + w)", - "Go Back (Alt + Left Arrow)": "Go Back (Alt + Left Arrow)", - "Go Forward (Alt + Right Arrow)": "Go Forward (Alt + Right Arrow)", - "Parent Directory (Alt + Up Arrow)": "Parent Directory (Alt + Up Arrow)", - "Reload (f5)": "Reload (f5)", - "Close Tab": "Close Tab" + "Favorites": "المفضلات", + "Desktop": "سطح مكتب", + "Documents": "المستندات", + "Downloads": "التنزيلات", + "Pictures": "الصور", + "Music": "الموسيقى", + "Videos": "الفيديوهات", + "Icon": "الأيقونة", + "Show hidden files": "إظهار الملفات المخفية", + "Files": "الملفات", + "Pendrives": "Pendrives", + "Home": "Home", + "Recent": "Recent", + "Trash": "مهملات", + "Drives": "Drives", + "free of": "free of", + "Settings": "إعدادات", + "Appearance": "Appearance", + "App Theme": "App Theme", + "Apply Shadow Effect": "Apply Shadow Effect", + "File Preview": "File Preview", + "Default File Layout": "Default File Layout", + "Show image as thumbnail": "Show image as thumbnail", + "Disabled": "Disabled", + "For small directory (recommended)": "For small directory (recommended)", + "Enable for all directory": "Enable for all directory", + "System Default": "النظام الافتراضي", + "Automatically play video file as thumbnail (May consume high amount of RAM)": "Automatically play video file as thumbnail (May consume high amount of RAM)", + "Extract exe file icon and make it as the thumbnail (Turning it on might crashes Xplorer)": "Extract exe file icon and make it as the thumbnail (Turning it on might crashes Xplorer)", + "Preview image on hover": "Preview image on hover", + "Font Family": "Font Family", + "Font Size": "Font Size", + "Window Transparency": "Window Transparency", + "Transparent Effect": "Transparent Effect", + "Blur": "Blur", + "Acrylic": "Acrylic", + "Mica": "Mica", + "Vibrancy": "Vibrancy (MacOS)", + "None": "None", + "Transparent Sidebar": "Transparent Sidebar", + "Transparent Topbar": "Transparent Topbar", + "Transparent Workspace": "Transparent Workspace", + "Frame Style": "Frame Style", + "Default": "Default", + "Detect Drive Change": "Detect Drive Change", + "Automatically change preview file with selected file": "Automatically change preview file with selected file", + "Single/Double Click to open a file": "Single/Double Click to open a file", + "Double click to open items under sidebar section": "Double click to open items under sidebar section", + "Double click to open items under home section": "Double click to open items under home section", + "Double click to open files/folders": "Double click to open files/folders", + "Preference": "Preference", + "App Language": "لغة التطبيق", + "Files and Folders": "الملفات والمجلدات", + "Hide hidden files": "إخفاء الملفات المخفية", + "Hide system files": "Hide system files", + "List and sort directories alongside files": "List and sort directories alongside files", + "On startup": "On startup", + "New tab": "New tab", + "Continue previous session": "Continue previous session", + "Workspace": "Workspace", + "Show Info Bar": "Show Info Bar", + "About": "About", + "Layout Mode": "Layout Mode", + "Grid View (Large)": "Grid View (Large)", + "Grid View (Medium)": "Grid View (Medium)", + "Grid View (Small)": "Grid View (Small)", + "Detail View": "Detail View", + "Sort By": "Sort By", + "A-Z": "A-Z", + "Z-A": "Z-A", + "Last Modified": "Last Modified", + "First Modified": "First Modified", + "Size": "Size", + "Type": "Type", + "Reload": "Reload", + "Copy": "Copy", + "Cut": "Cut", + "Paste": "Paste", + "Undo Action": "Undo Action", + "Redo Action": "Redo Action", + "Copy Location Path": "Copy Location Path", + "Clear Recent List": "Clear Recent List", + "Open": "Open", + "Open in Terminal": "Open in Terminal", + "Open in VSCode": "Open in VSCode", + "New": "New", + "File": "File", + "Folder": "Folder", + "Unpin from Sidebar": "Unpin from Sidebar", + "Pin to Sidebar": "Pin to Sidebar", + "Compress to Zip": "Compress to Zip", + "Properties": "Properties", + "Rename": "Rename", + "Delete": "Delete", + "Restore": "Restore", + "Permanently Delete": "Permanently Delete", + "Open in New Tab": "Open in New Tab", + "Preview": "Preview", + "Restore all files": "Restore all files", + "Permanently delete all files": "Permanently delete all files", + "Restore these files": "Restore these files", + "Permanently delete these files": "Permanently delete these files", + "Calculate sub folder size": "Calculate sub folder size", + "Search": "Search", + "Minimize": "Minimize", + "Maximize": "Maximize", + "Exit (Ctrl + w)": "Exit (Ctrl + w)", + "Go Back (Alt + Left Arrow)": "Go Back (Alt + Left Arrow)", + "Go Forward (Alt + Right Arrow)": "Go Forward (Alt + Right Arrow)", + "Parent Directory (Alt + Up Arrow)": "Parent Directory (Alt + Up Arrow)", + "Reload (f5)": "Reload (f5)", + "Close Tab": "Close Tab" } diff --git a/src/Locales/base.json b/src/Locales/base.json index 6669ef95..468907ed 100644 --- a/src/Locales/base.json +++ b/src/Locales/base.json @@ -1,114 +1,114 @@ { - "Favorites": "Favorites", - "Desktop": "Desktop", - "Documents": "Documents", - "Downloads": "Downloads", - "Pictures": "Pictures", - "Music": "Music", - "Videos": "Videos", - "Icon": "Icon", - "Show hidden files": "Show hidden files", - "Files": "Files", - "Pendrives": "Pendrives", - "Home": "Home", - "Recent": "Recent", - "Trash": "Trash", - "Drives": "Drives", - "free of": "free of", - "Settings": "Settings", - "Appearance": "Appearance", - "App Theme": "App Theme", - "Apply Shadow Effect": "Apply Shadow Effect", - "File Preview": "File Preview", - "Default File Layout": "Default File Layout", - "Show image as thumbnail": "Show image as thumbnail", - "Disabled": "Disabled", - "For small directory (recommended)": "For small directory (recommended)", - "Enable for all directory": "Enable for all directory", - "System Default": "System Default", - "Automatically play video file as thumbnail (May consume high amount of RAM)": "Automatically play video file as thumbnail (May consume high amount of RAM)", - "Extract exe file icon and make it as the thumbnail (Turning it on might crashes Xplorer)": "Extract exe file icon and make it as the thumbnail (Turning it on might crashes Xplorer)", - "Preview image on hover": "Preview image on hover", - "Font Family": "Font Family", - "Font Size": "Font Size", - "Window Transparency": "Window Transparency", - "Transparent Effect": "Transparent Effect", - "Blur": "Blur", - "Acrylic": "Acrylic", - "Mica": "Mica", - "Vibrancy": "Vibrancy (MacOS)", - "None": "None", - "Transparent Sidebar": "Transparent Sidebar", - "Transparent Topbar": "Transparent Topbar", - "Transparent Workspace": "Transparent Workspace", - "Frame Style": "Frame Style", - "Default": "Default", - "Detect Drive Change": "Detect Drive Change", - "Automatically change preview file with selected file": "Automatically change preview file with selected file", - "Single/Double Click to open a file": "Single/Double Click to open a file", - "Double click to open items under sidebar section": "Double click to open items under sidebar section", - "Double click to open items under home section": "Double click to open items under home section", - "Double click to open files/folders": "Double click to open files/folders", - "Preference": "Preference", - "App Language": "App Language", - "Files and Folders": "Files and Folders", - "Hide hidden files": "Hide hidden files", - "Hide system files": "Hide system files", - "List and sort directories alongside files": "List and sort directories alongside files", - "On startup": "On startup", - "New tab": "New tab", - "Continue previous session": "Continue previous session", - "Workspace": "Workspace", - "Show Info Bar": "Show Info Bar", - "About": "About", - "Layout Mode": "Layout Mode", - "Grid View (Large)": "Grid View (Large)", - "Grid View (Medium)": "Grid View (Medium)", - "Grid View (Small)": "Grid View (Small)", - "Detail View": "Detail View", - "Sort By": "Sort By", - "A-Z": "A-Z", - "Z-A": "Z-A", - "Last Modified": "Last Modified", - "First Modified": "First Modified", - "Size": "Size", - "Type": "Type", - "Reload": "Reload", - "Copy": "Copy", - "Cut": "Cut", - "Paste": "Paste", - "Undo Action": "Undo Action", - "Redo Action": "Redo Action", - "Copy Location Path": "Copy Location Path", - "Clear Recent List": "Clear Recent List", - "Open": "Open", - "Open in Terminal": "Open in Terminal", - "Open in VSCode": "Open in VSCode", - "New": "New", - "File": "File", - "Folder": "Folder", - "Unpin from Sidebar": "Unpin from Sidebar", - "Pin to Sidebar": "Pin to Sidebar", - "Compress to Zip": "Compress to Zip", - "Properties": "Properties", - "Rename": "Rename", - "Delete": "Delete", - "Restore": "Restore", - "Permanently Delete": "Permanently Delete", - "Open in New Tab": "Open in New Tab", - "Preview": "Preview", - "Restore all files": "Restore all files", - "Permanently delete all files": "Permanently delete all files", - "Restore these files": "Restore these files", - "Permanently delete these files": "Permanently delete these files", - "Calculate sub folder size": "Calculate sub folder size", - "Search": "Search", - "Minimize": "Minimize", - "Maximize": "Maximize", - "Exit (Ctrl + w)": "Exit (Ctrl + w)", - "Go Back (Alt + Left Arrow)": "Go Back (Alt + Left Arrow)", - "Go Forward (Alt + Right Arrow)": "Go Forward (Alt + Right Arrow)", - "Parent Directory (Alt + Up Arrow)": "Parent Directory (Alt + Up Arrow)", - "Reload (f5)": "Reload (f5)", - "Close Tab": "Close Tab" + "Favorites": "Favorites", + "Desktop": "Desktop", + "Documents": "Documents", + "Downloads": "Downloads", + "Pictures": "Pictures", + "Music": "Music", + "Videos": "Videos", + "Icon": "Icon", + "Show hidden files": "Show hidden files", + "Files": "Files", + "Pendrives": "Pendrives", + "Home": "Home", + "Recent": "Recent", + "Trash": "Trash", + "Drives": "Drives", + "free of": "free of", + "Settings": "Settings", + "Appearance": "Appearance", + "App Theme": "App Theme", + "Apply Shadow Effect": "Apply Shadow Effect", + "File Preview": "File Preview", + "Default File Layout": "Default File Layout", + "Show image as thumbnail": "Show image as thumbnail", + "Disabled": "Disabled", + "For small directory (recommended)": "For small directory (recommended)", + "Enable for all directory": "Enable for all directory", + "System Default": "System Default", + "Automatically play video file as thumbnail (May consume high amount of RAM)": "Automatically play video file as thumbnail (May consume high amount of RAM)", + "Extract exe file icon and make it as the thumbnail (Turning it on might crashes Xplorer)": "Extract exe file icon and make it as the thumbnail (Turning it on might crashes Xplorer)", + "Preview image on hover": "Preview image on hover", + "Font Family": "Font Family", + "Font Size": "Font Size", + "Window Transparency": "Window Transparency", + "Transparent Effect": "Transparent Effect", + "Blur": "Blur", + "Acrylic": "Acrylic", + "Mica": "Mica", + "Vibrancy": "Vibrancy (MacOS)", + "None": "None", + "Transparent Sidebar": "Transparent Sidebar", + "Transparent Topbar": "Transparent Topbar", + "Transparent Workspace": "Transparent Workspace", + "Frame Style": "Frame Style", + "Default": "Default", + "Detect Drive Change": "Detect Drive Change", + "Automatically change preview file with selected file": "Automatically change preview file with selected file", + "Single/Double Click to open a file": "Single/Double Click to open a file", + "Double click to open items under sidebar section": "Double click to open items under sidebar section", + "Double click to open items under home section": "Double click to open items under home section", + "Double click to open files/folders": "Double click to open files/folders", + "Preference": "Preference", + "App Language": "App Language", + "Files and Folders": "Files and Folders", + "Hide hidden files": "Hide hidden files", + "Hide system files": "Hide system files", + "List and sort directories alongside files": "List and sort directories alongside files", + "On startup": "On startup", + "New tab": "New tab", + "Continue previous session": "Continue previous session", + "Workspace": "Workspace", + "Show Info Bar": "Show Info Bar", + "About": "About", + "Layout Mode": "Layout Mode", + "Grid View (Large)": "Grid View (Large)", + "Grid View (Medium)": "Grid View (Medium)", + "Grid View (Small)": "Grid View (Small)", + "Detail View": "Detail View", + "Sort By": "Sort By", + "A-Z": "A-Z", + "Z-A": "Z-A", + "Last Modified": "Last Modified", + "First Modified": "First Modified", + "Size": "Size", + "Type": "Type", + "Reload": "Reload", + "Copy": "Copy", + "Cut": "Cut", + "Paste": "Paste", + "Undo Action": "Undo Action", + "Redo Action": "Redo Action", + "Copy Location Path": "Copy Location Path", + "Clear Recent List": "Clear Recent List", + "Open": "Open", + "Open in Terminal": "Open in Terminal", + "Open in VSCode": "Open in VSCode", + "New": "New", + "File": "File", + "Folder": "Folder", + "Unpin from Sidebar": "Unpin from Sidebar", + "Pin to Sidebar": "Pin to Sidebar", + "Compress to Zip": "Compress to Zip", + "Properties": "Properties", + "Rename": "Rename", + "Delete": "Delete", + "Restore": "Restore", + "Permanently Delete": "Permanently Delete", + "Open in New Tab": "Open in New Tab", + "Preview": "Preview", + "Restore all files": "Restore all files", + "Permanently delete all files": "Permanently delete all files", + "Restore these files": "Restore these files", + "Permanently delete these files": "Permanently delete these files", + "Calculate sub folder size": "Calculate sub folder size", + "Search": "Search", + "Minimize": "Minimize", + "Maximize": "Maximize", + "Exit (Ctrl + w)": "Exit (Ctrl + w)", + "Go Back (Alt + Left Arrow)": "Go Back (Alt + Left Arrow)", + "Go Forward (Alt + Right Arrow)": "Go Forward (Alt + Right Arrow)", + "Parent Directory (Alt + Up Arrow)": "Parent Directory (Alt + Up Arrow)", + "Reload (f5)": "Reload (f5)", + "Close Tab": "Close Tab" } diff --git a/src/Locales/de-DE.json b/src/Locales/de-DE.json index 6bebd62b..2da343d3 100644 --- a/src/Locales/de-DE.json +++ b/src/Locales/de-DE.json @@ -1,114 +1,114 @@ { - "Favorites": "Favoriten", - "Desktop": "Desktop", - "Documents": "Dokumente", - "Downloads": "Downloads", - "Pictures": "Bilder", - "Music": "Musik", - "Videos": "Videos", - "Icon": "Icon", - "Show hidden files": "Zeige versteckte Dateien", - "Files": "Dateien", - "Pendrives": "USB Sticks", - "Home": "Start", - "Recent": "Zuletzt", - "Trash": "Papierkorb", - "Drives": "Laufwerke", - "free of": "frei von", - "Settings": "Einstellungen", - "Appearance": "Erscheinungsbild", - "App Theme": "App Thema", - "Apply Shadow Effect": "Apply Shadow Effect", - "File Preview": "File Preview", - "Default File Layout": "Default File Layout", - "Show image as thumbnail": "Show image as thumbnail", - "Disabled": "Disabled", - "For small directory (recommended)": "For small directory (recommended)", - "Enable for all directory": "Enable for all directory", - "System Default": "Systemstandard", - "Automatically play video file as thumbnail (May consume high amount of RAM)": "Automatically play video file as thumbnail (May consume high amount of RAM)", - "Extract exe file icon and make it as the thumbnail (Turning it on might crashes Xplorer)": "Extract exe file icon and make it as the thumbnail (Turning it on might crashes Xplorer)", - "Preview image on hover": "Preview image on hover", - "Font Family": "Font Family", - "Font Size": "Font Size", - "Window Transparency": "Window Transparency", - "Transparent Effect": "Transparent Effect", - "Blur": "Blur", - "Acrylic": "Acrylic", - "Mica": "Mica", - "Vibrancy": "Vibrancy (MacOS)", - "None": "None", - "Transparent Sidebar": "Transparent Sidebar", - "Transparent Topbar": "Transparent Topbar", - "Transparent Workspace": "Transparent Workspace", - "Frame Style": "Frame Style", - "Default": "Default", - "Detect Drive Change": "Detect Drive Change", - "Automatically change preview file with selected file": "Automatically change preview file with selected file", - "Single/Double Click to open a file": "Single/Double Click to open a file", - "Double click to open items under sidebar section": "Double click to open items under sidebar section", - "Double click to open items under home section": "Double click to open items under home section", - "Double click to open files/folders": "Double click to open files/folders", - "Preference": "Präferenz", - "App Language": "App-Sprache", - "Files and Folders": "Dateien und Ordner", - "Hide hidden files": "Versteckte Dateien nicht anzeigen", - "Hide system files": "Hide system files", - "List and sort directories alongside files": "Verzeichnisse neben Dateien auflisten und sortieren", - "On startup": "On startup", - "New tab": "New tab", - "Continue previous session": "Continue previous session", - "Workspace": "Workspace", - "Show Info Bar": "Show Info Bar", - "About": "About", - "Layout Mode": "Layout Mode", - "Grid View (Large)": "Grid View (Large)", - "Grid View (Medium)": "Grid View (Medium)", - "Grid View (Small)": "Grid View (Small)", - "Detail View": "Detail View", - "Sort By": "Sort By", - "A-Z": "A-Z", - "Z-A": "Z-A", - "Last Modified": "Last Modified", - "First Modified": "First Modified", - "Size": "Size", - "Type": "Type", - "Reload": "Reload", - "Copy": "Copy", - "Cut": "Cut", - "Paste": "Paste", - "Undo Action": "Undo Action", - "Redo Action": "Redo Action", - "Copy Location Path": "Copy Location Path", - "Clear Recent List": "Clear Recent List", - "Open": "Open", - "Open in Terminal": "Open in Terminal", - "Open in VSCode": "Open in VSCode", - "New": "New", - "File": "File", - "Folder": "Folder", - "Unpin from Sidebar": "Unpin from Sidebar", - "Pin to Sidebar": "Pin to Sidebar", - "Compress to Zip": "Compress to Zip", - "Properties": "Properties", - "Rename": "Rename", - "Delete": "Delete", - "Restore": "Restore", - "Permanently Delete": "Permanently Delete", - "Open in New Tab": "Open in New Tab", - "Preview": "Preview", - "Restore all files": "Restore all files", - "Permanently delete all files": "Permanently delete all files", - "Restore these files": "Restore these files", - "Permanently delete these files": "Permanently delete these files", - "Calculate sub folder size": "Calculate sub folder size", - "Search": "Search", - "Minimize": "Minimize", - "Maximize": "Maximize", - "Exit (Ctrl + w)": "Exit (Ctrl + w)", - "Go Back (Alt + Left Arrow)": "Go Back (Alt + Left Arrow)", - "Go Forward (Alt + Right Arrow)": "Go Forward (Alt + Right Arrow)", - "Parent Directory (Alt + Up Arrow)": "Parent Directory (Alt + Up Arrow)", - "Reload (f5)": "Reload (f5)", - "Close Tab": "Close Tab" + "Favorites": "Favoriten", + "Desktop": "Desktop", + "Documents": "Dokumente", + "Downloads": "Downloads", + "Pictures": "Bilder", + "Music": "Musik", + "Videos": "Videos", + "Icon": "Icon", + "Show hidden files": "Zeige versteckte Dateien", + "Files": "Dateien", + "Pendrives": "USB Sticks", + "Home": "Start", + "Recent": "Zuletzt", + "Trash": "Papierkorb", + "Drives": "Laufwerke", + "free of": "frei von", + "Settings": "Einstellungen", + "Appearance": "Erscheinungsbild", + "App Theme": "App Thema", + "Apply Shadow Effect": "Apply Shadow Effect", + "File Preview": "File Preview", + "Default File Layout": "Default File Layout", + "Show image as thumbnail": "Show image as thumbnail", + "Disabled": "Disabled", + "For small directory (recommended)": "For small directory (recommended)", + "Enable for all directory": "Enable for all directory", + "System Default": "Systemstandard", + "Automatically play video file as thumbnail (May consume high amount of RAM)": "Automatically play video file as thumbnail (May consume high amount of RAM)", + "Extract exe file icon and make it as the thumbnail (Turning it on might crashes Xplorer)": "Extract exe file icon and make it as the thumbnail (Turning it on might crashes Xplorer)", + "Preview image on hover": "Preview image on hover", + "Font Family": "Font Family", + "Font Size": "Font Size", + "Window Transparency": "Window Transparency", + "Transparent Effect": "Transparent Effect", + "Blur": "Blur", + "Acrylic": "Acrylic", + "Mica": "Mica", + "Vibrancy": "Vibrancy (MacOS)", + "None": "None", + "Transparent Sidebar": "Transparent Sidebar", + "Transparent Topbar": "Transparent Topbar", + "Transparent Workspace": "Transparent Workspace", + "Frame Style": "Frame Style", + "Default": "Default", + "Detect Drive Change": "Detect Drive Change", + "Automatically change preview file with selected file": "Automatically change preview file with selected file", + "Single/Double Click to open a file": "Single/Double Click to open a file", + "Double click to open items under sidebar section": "Double click to open items under sidebar section", + "Double click to open items under home section": "Double click to open items under home section", + "Double click to open files/folders": "Double click to open files/folders", + "Preference": "Präferenz", + "App Language": "App-Sprache", + "Files and Folders": "Dateien und Ordner", + "Hide hidden files": "Versteckte Dateien nicht anzeigen", + "Hide system files": "Hide system files", + "List and sort directories alongside files": "Verzeichnisse neben Dateien auflisten und sortieren", + "On startup": "On startup", + "New tab": "New tab", + "Continue previous session": "Continue previous session", + "Workspace": "Workspace", + "Show Info Bar": "Show Info Bar", + "About": "About", + "Layout Mode": "Layout Mode", + "Grid View (Large)": "Grid View (Large)", + "Grid View (Medium)": "Grid View (Medium)", + "Grid View (Small)": "Grid View (Small)", + "Detail View": "Detail View", + "Sort By": "Sort By", + "A-Z": "A-Z", + "Z-A": "Z-A", + "Last Modified": "Last Modified", + "First Modified": "First Modified", + "Size": "Size", + "Type": "Type", + "Reload": "Reload", + "Copy": "Copy", + "Cut": "Cut", + "Paste": "Paste", + "Undo Action": "Undo Action", + "Redo Action": "Redo Action", + "Copy Location Path": "Copy Location Path", + "Clear Recent List": "Clear Recent List", + "Open": "Open", + "Open in Terminal": "Open in Terminal", + "Open in VSCode": "Open in VSCode", + "New": "New", + "File": "File", + "Folder": "Folder", + "Unpin from Sidebar": "Unpin from Sidebar", + "Pin to Sidebar": "Pin to Sidebar", + "Compress to Zip": "Compress to Zip", + "Properties": "Properties", + "Rename": "Rename", + "Delete": "Delete", + "Restore": "Restore", + "Permanently Delete": "Permanently Delete", + "Open in New Tab": "Open in New Tab", + "Preview": "Preview", + "Restore all files": "Restore all files", + "Permanently delete all files": "Permanently delete all files", + "Restore these files": "Restore these files", + "Permanently delete these files": "Permanently delete these files", + "Calculate sub folder size": "Calculate sub folder size", + "Search": "Search", + "Minimize": "Minimize", + "Maximize": "Maximize", + "Exit (Ctrl + w)": "Exit (Ctrl + w)", + "Go Back (Alt + Left Arrow)": "Go Back (Alt + Left Arrow)", + "Go Forward (Alt + Right Arrow)": "Go Forward (Alt + Right Arrow)", + "Parent Directory (Alt + Up Arrow)": "Parent Directory (Alt + Up Arrow)", + "Reload (f5)": "Reload (f5)", + "Close Tab": "Close Tab" } diff --git a/src/Locales/es-ES.json b/src/Locales/es-ES.json index d278ef99..953f0c6f 100644 --- a/src/Locales/es-ES.json +++ b/src/Locales/es-ES.json @@ -1,114 +1,114 @@ { - "Favorites": "Favoritos", - "Desktop": "Escritorio", - "Documents": "Documentos", - "Downloads": "Descargas", - "Pictures": "Imágenes", - "Music": "Música", - "Videos": "Vídeos", - "Icon": "Iconos", - "Show hidden files": "Mostrar archivos ocultos", - "Files": "Archivos", - "Pendrives": "Dispositivos extraíbles", - "Home": "Inicio", - "Recent": "Recientes", - "Trash": "Papelera", - "Drives": "Unidades", - "free of": "libre de", - "Settings": "Ajustes", - "Appearance": "Apariencia", - "App Theme": "Tema", - "Apply Shadow Effect": "Apply Shadow Effect", - "File Preview": "Vista previa del archivo", - "Default File Layout": "Diseño de archivos predeterminado", - "Show image as thumbnail": "Mostrar imagen como miniatura", - "Disabled": "Disabled", - "For small directory (recommended)": "For small directory (recommended)", - "Enable for all directory": "Enable for all directory", - "System Default": "Predeterminado del sistema", - "Automatically play video file as thumbnail (May consume high amount of RAM)": "Reproducir archivos de video automáticamente como miniatura (Puede consumir bastante RAM)", - "Extract exe file icon and make it as the thumbnail (Turning it on might crashes Xplorer)": "Extraer icono de archivo exe y convertir en miniatura (Activarlo puede detener Xplorer)", - "Preview image on hover": "Vista previa de la imagen al pasar el ratón", - "Font Family": "Fuente", - "Font Size": "Font Size", - "Window Transparency": "Transparencia de Ventana", - "Transparent Effect": "Efecto de transparencia", - "Blur": "Blur", - "Acrylic": "Acrylic", - "Mica": "Mica", - "Vibrancy": "Vibrancy (MacOS)", - "None": "None", - "Transparent Sidebar": "Barra lateral transparente", - "Transparent Topbar": "Barra superior transparente", - "Transparent Workspace": "Espacio de trabajo transparente", - "Frame Style": "Estilo del marco", - "Default": "Valor por defecto", - "Detect Drive Change": "Detectar cambio de unidad", - "Automatically change preview file with selected file": "Automatically change preview file with selected file", - "Single/Double Click to open a file": "Single/Double Click to open a file", - "Double click to open items under sidebar section": "Double click to open items under sidebar section", - "Double click to open items under home section": "Double click to open items under home section", - "Double click to open files/folders": "Double click to open files/folders", - "Preference": "Preferencia", - "App Language": "Idioma de la aplicación", - "Files and Folders": "Archivos y carpetas", - "Hide hidden files": "No mostrar archivos ocultos", - "Hide system files": "Hide system files", - "List and sort directories alongside files": "Listar y ordenar directorios junto con archivos", - "On startup": "Al iniciar", - "New tab": "New tab", - "Continue previous session": "Continue previous session", - "Workspace": "Área de trabajo", - "Show Info Bar": "Mostrar barra de información", - "About": "Acerca de", - "Layout Mode": "Modo de apariencia", - "Grid View (Large)": "Vista en cuadrícula (Grande)", - "Grid View (Medium)": "Vista en cuadrícula (Mediana)", - "Grid View (Small)": "Vista en cuadrícula (Pequeña)", - "Detail View": "Vista detallada", - "Sort By": "Ordenar por", - "A-Z": "A-Z", - "Z-A": "Z-A", - "Last Modified": "Modificación (desde el más reciente)", - "First Modified": "Recién modificados", - "Size": "Tamaño", - "Type": "Tipo", - "Reload": "Actualizar", - "Copy": "Copiar", - "Cut": "Cortar", - "Paste": "Pegar", - "Undo Action": "Deshacer acción", - "Redo Action": "Rehacer acción", - "Copy Location Path": "Copiar ruta", - "Clear Recent List": "Limpiar recientes", - "Open": "Open", - "Open in Terminal": "Abrir en Terminal", - "Open in VSCode": "Abrir en VSCode", - "New": "Nuevo", - "File": "Archivo", - "Folder": "Carpeta", - "Unpin from Sidebar": "Desanclar de la barra lateral", - "Pin to Sidebar": "Anclar a la barra lateral", - "Compress to Zip": "Compress to Zip", - "Properties": "Propiedades", - "Rename": "Renombrar", - "Delete": "Eliminar", - "Restore": "Restaurar", - "Permanently Delete": "Eliminar permanentemente", - "Open in New Tab": "Abrir en nueva pestaña", - "Preview": "Vista previa", - "Restore all files": "Restaurar todos los ficheros", - "Permanently delete all files": "Eliminar permanentemente todos los archivos", - "Restore these files": "Restaurar estos archivos", - "Permanently delete these files": "Eliminar permanentemente estos archivos", - "Calculate sub folder size": "Calculate sub folder size", - "Search": "Search", - "Minimize": "Minimize", - "Maximize": "Maximize", - "Exit (Ctrl + w)": "Exit (Ctrl + w)", - "Go Back (Alt + Left Arrow)": "Go Back (Alt + Left Arrow)", - "Go Forward (Alt + Right Arrow)": "Go Forward (Alt + Right Arrow)", - "Parent Directory (Alt + Up Arrow)": "Parent Directory (Alt + Up Arrow)", - "Reload (f5)": "Reload (f5)", - "Close Tab": "Close Tab" + "Favorites": "Favoritos", + "Desktop": "Escritorio", + "Documents": "Documentos", + "Downloads": "Descargas", + "Pictures": "Imágenes", + "Music": "Música", + "Videos": "Vídeos", + "Icon": "Iconos", + "Show hidden files": "Mostrar archivos ocultos", + "Files": "Archivos", + "Pendrives": "Dispositivos extraíbles", + "Home": "Inicio", + "Recent": "Recientes", + "Trash": "Papelera", + "Drives": "Unidades", + "free of": "libre de", + "Settings": "Ajustes", + "Appearance": "Apariencia", + "App Theme": "Tema", + "Apply Shadow Effect": "Apply Shadow Effect", + "File Preview": "Vista previa del archivo", + "Default File Layout": "Diseño de archivos predeterminado", + "Show image as thumbnail": "Mostrar imagen como miniatura", + "Disabled": "Disabled", + "For small directory (recommended)": "For small directory (recommended)", + "Enable for all directory": "Enable for all directory", + "System Default": "Predeterminado del sistema", + "Automatically play video file as thumbnail (May consume high amount of RAM)": "Reproducir archivos de video automáticamente como miniatura (Puede consumir bastante RAM)", + "Extract exe file icon and make it as the thumbnail (Turning it on might crashes Xplorer)": "Extraer icono de archivo exe y convertir en miniatura (Activarlo puede detener Xplorer)", + "Preview image on hover": "Vista previa de la imagen al pasar el ratón", + "Font Family": "Fuente", + "Font Size": "Font Size", + "Window Transparency": "Transparencia de Ventana", + "Transparent Effect": "Efecto de transparencia", + "Blur": "Blur", + "Acrylic": "Acrylic", + "Mica": "Mica", + "Vibrancy": "Vibrancy (MacOS)", + "None": "None", + "Transparent Sidebar": "Barra lateral transparente", + "Transparent Topbar": "Barra superior transparente", + "Transparent Workspace": "Espacio de trabajo transparente", + "Frame Style": "Estilo del marco", + "Default": "Valor por defecto", + "Detect Drive Change": "Detectar cambio de unidad", + "Automatically change preview file with selected file": "Automatically change preview file with selected file", + "Single/Double Click to open a file": "Single/Double Click to open a file", + "Double click to open items under sidebar section": "Double click to open items under sidebar section", + "Double click to open items under home section": "Double click to open items under home section", + "Double click to open files/folders": "Double click to open files/folders", + "Preference": "Preferencia", + "App Language": "Idioma de la aplicación", + "Files and Folders": "Archivos y carpetas", + "Hide hidden files": "No mostrar archivos ocultos", + "Hide system files": "Hide system files", + "List and sort directories alongside files": "Listar y ordenar directorios junto con archivos", + "On startup": "Al iniciar", + "New tab": "New tab", + "Continue previous session": "Continue previous session", + "Workspace": "Área de trabajo", + "Show Info Bar": "Mostrar barra de información", + "About": "Acerca de", + "Layout Mode": "Modo de apariencia", + "Grid View (Large)": "Vista en cuadrícula (Grande)", + "Grid View (Medium)": "Vista en cuadrícula (Mediana)", + "Grid View (Small)": "Vista en cuadrícula (Pequeña)", + "Detail View": "Vista detallada", + "Sort By": "Ordenar por", + "A-Z": "A-Z", + "Z-A": "Z-A", + "Last Modified": "Modificación (desde el más reciente)", + "First Modified": "Recién modificados", + "Size": "Tamaño", + "Type": "Tipo", + "Reload": "Actualizar", + "Copy": "Copiar", + "Cut": "Cortar", + "Paste": "Pegar", + "Undo Action": "Deshacer acción", + "Redo Action": "Rehacer acción", + "Copy Location Path": "Copiar ruta", + "Clear Recent List": "Limpiar recientes", + "Open": "Open", + "Open in Terminal": "Abrir en Terminal", + "Open in VSCode": "Abrir en VSCode", + "New": "Nuevo", + "File": "Archivo", + "Folder": "Carpeta", + "Unpin from Sidebar": "Desanclar de la barra lateral", + "Pin to Sidebar": "Anclar a la barra lateral", + "Compress to Zip": "Compress to Zip", + "Properties": "Propiedades", + "Rename": "Renombrar", + "Delete": "Eliminar", + "Restore": "Restaurar", + "Permanently Delete": "Eliminar permanentemente", + "Open in New Tab": "Abrir en nueva pestaña", + "Preview": "Vista previa", + "Restore all files": "Restaurar todos los ficheros", + "Permanently delete all files": "Eliminar permanentemente todos los archivos", + "Restore these files": "Restaurar estos archivos", + "Permanently delete these files": "Eliminar permanentemente estos archivos", + "Calculate sub folder size": "Calculate sub folder size", + "Search": "Search", + "Minimize": "Minimize", + "Maximize": "Maximize", + "Exit (Ctrl + w)": "Exit (Ctrl + w)", + "Go Back (Alt + Left Arrow)": "Go Back (Alt + Left Arrow)", + "Go Forward (Alt + Right Arrow)": "Go Forward (Alt + Right Arrow)", + "Parent Directory (Alt + Up Arrow)": "Parent Directory (Alt + Up Arrow)", + "Reload (f5)": "Reload (f5)", + "Close Tab": "Close Tab" } diff --git a/src/Locales/fr-FR.json b/src/Locales/fr-FR.json index 13cd3451..3beb41e2 100644 --- a/src/Locales/fr-FR.json +++ b/src/Locales/fr-FR.json @@ -1,114 +1,114 @@ { - "Favorites": "Favoris", - "Desktop": "Bureau", - "Documents": "Documents", - "Downloads": "Téléchargements", - "Pictures": "Photos", - "Music": "Musiques", - "Videos": "Vidéos", - "Icon": "Icône", - "Show hidden files": "Afficher les fichiers cachés", - "Files": "Fichiers", - "Pendrives": "Clés USB", - "Home": "Accueil", - "Recent": "Récent", - "Trash": "Poubelle", - "Drives": "Disques", - "free of": "libre de", - "Settings": "Paramètres", - "Appearance": "Apparence", - "App Theme": "Thème de l'appli", - "Apply Shadow Effect": "Appliquer l'effet d'ombre", - "File Preview": "Aperçu du fichier", - "Default File Layout": "Schéma de page par défaut", - "Show image as thumbnail": "Afficher l'image comme miniature", - "Disabled": "Disabled", - "For small directory (recommended)": "Pour les petits répertoires (recommandé)", - "Enable for all directory": "Activer pour tous les répertoires", - "System Default": "Défaut du système", - "Automatically play video file as thumbnail (May consume high amount of RAM)": "Lire automatiquement le fichier vidéo en miniature (peut consommer beaucoup de RAM)", - "Extract exe file icon and make it as the thumbnail (Turning it on might crashes Xplorer)": "Extraire l'icône du fichier exe et le faire en tant que miniature (l'activer peut faire planter Xplorer)", - "Preview image on hover": "Aperçu de l'image au survol", - "Font Family": "Famille de police", - "Font Size": "Font Size", - "Window Transparency": "Transparence de la Fenêtre", - "Transparent Effect": "Transparent Effect", - "Blur": "Blur", - "Acrylic": "Acrylic", - "Mica": "Mica", - "Vibrancy": "Vibrancy (MacOS)", - "None": "None", - "Transparent Sidebar": "Barre latérale transparente", - "Transparent Topbar": "Barre latérale transparente", - "Transparent Workspace": "Espace de travail transparent", - "Frame Style": "Style de cadre", - "Default": "Par défaut", - "Detect Drive Change": "Détecter le changement du disque dur", - "Automatically change preview file with selected file": "Automatically change preview file with selected file", - "Single/Double Click to open a file": "Single/Double Click to open a file", - "Double click to open items under sidebar section": "Double click to open items under sidebar section", - "Double click to open items under home section": "Double click to open items under home section", - "Double click to open files/folders": "Double click to open files/folders", - "Preference": "Préférences", - "App Language": "Langue de l'application", - "Files and Folders": "Fichiers et dossiers", - "Hide hidden files": "Masquer les fichiers cachés", - "Hide system files": "Cacher les fichiers système", - "List and sort directories alongside files": "Lister et trier les répertoires à côté des fichiers", - "On startup": "Au démarrage", - "New tab": "Nouvel onglet", - "Continue previous session": "Continue previous session", - "Workspace": "Espace de travail", - "Show Info Bar": "Afficher la barre d'info", - "About": "À propos", - "Layout Mode": "Mode d'affichage", - "Grid View (Large)": "Vue Grille (Large)", - "Grid View (Medium)": "Vue Grille (Moyenne)", - "Grid View (Small)": "Vue Grille (Petit)", - "Detail View": "Vue détaillée", - "Sort By": "Trier par", - "A-Z": "A-Z", - "Z-A": "Z-A", - "Last Modified": "Dernière Modification", - "First Modified": "Première modification", - "Size": "Taille", - "Type": "Type", - "Reload": "Redémarrer", - "Copy": "Copier", - "Cut": "Couper", - "Paste": "Coller", - "Undo Action": "Annuler l'action", - "Redo Action": "Refaire l'action", - "Copy Location Path": "Copier le chemin de l'emplacement", - "Clear Recent List": "Effacez l'historique récent", - "Open": "Ouvrir", - "Open in Terminal": "Ouvrir dans le Terminal", - "Open in VSCode": "Ouvrir dans VSCode", - "New": "Nouveau", - "File": "Fichier", - "Folder": "Dossier", - "Unpin from Sidebar": "Désépingler de la barre latérale", - "Pin to Sidebar": "Épingler à la barre latérale", - "Compress to Zip": "Compresser en Zip", - "Properties": "Proprietés", - "Rename": "Renommer", - "Delete": "Supprimer", - "Restore": "Restaurer", - "Permanently Delete": "Supprimer définitivement", - "Open in New Tab": "Ouvrir dans un nouvel onglet", - "Preview": "Aperçu", - "Restore all files": "Récupérer tous les fichiers", - "Permanently delete all files": "Supprimer définitivement tous les fichiers", - "Restore these files": "Restaurer ces fichiers", - "Permanently delete these files": "Supprimer définitivement ces fichiers", - "Calculate sub folder size": "Calculer la taille du sous-dossier", - "Search": "Chercher", - "Minimize": "Réduire", - "Maximize": "Maximiser", - "Exit (Ctrl + w)": "Quitter (Ctrl + w)", - "Go Back (Alt + Left Arrow)": "Retour en arrière (Alt + Left Arrow)", - "Go Forward (Alt + Right Arrow)": "Aller de l'avant (Alt + Right Arrow)", - "Parent Directory (Alt + Up Arrow)": "Dossier parent (Alt + Up Arrow)", - "Reload (f5)": "Recharger (f5)", - "Close Tab": "Fermer Tab" + "Favorites": "Favoris", + "Desktop": "Bureau", + "Documents": "Documents", + "Downloads": "Téléchargements", + "Pictures": "Photos", + "Music": "Musiques", + "Videos": "Vidéos", + "Icon": "Icône", + "Show hidden files": "Afficher les fichiers cachés", + "Files": "Fichiers", + "Pendrives": "Clés USB", + "Home": "Accueil", + "Recent": "Récent", + "Trash": "Poubelle", + "Drives": "Disques", + "free of": "libre de", + "Settings": "Paramètres", + "Appearance": "Apparence", + "App Theme": "Thème de l'appli", + "Apply Shadow Effect": "Appliquer l'effet d'ombre", + "File Preview": "Aperçu du fichier", + "Default File Layout": "Schéma de page par défaut", + "Show image as thumbnail": "Afficher l'image comme miniature", + "Disabled": "Disabled", + "For small directory (recommended)": "Pour les petits répertoires (recommandé)", + "Enable for all directory": "Activer pour tous les répertoires", + "System Default": "Défaut du système", + "Automatically play video file as thumbnail (May consume high amount of RAM)": "Lire automatiquement le fichier vidéo en miniature (peut consommer beaucoup de RAM)", + "Extract exe file icon and make it as the thumbnail (Turning it on might crashes Xplorer)": "Extraire l'icône du fichier exe et le faire en tant que miniature (l'activer peut faire planter Xplorer)", + "Preview image on hover": "Aperçu de l'image au survol", + "Font Family": "Famille de police", + "Font Size": "Font Size", + "Window Transparency": "Transparence de la Fenêtre", + "Transparent Effect": "Transparent Effect", + "Blur": "Blur", + "Acrylic": "Acrylic", + "Mica": "Mica", + "Vibrancy": "Vibrancy (MacOS)", + "None": "None", + "Transparent Sidebar": "Barre latérale transparente", + "Transparent Topbar": "Barre latérale transparente", + "Transparent Workspace": "Espace de travail transparent", + "Frame Style": "Style de cadre", + "Default": "Par défaut", + "Detect Drive Change": "Détecter le changement du disque dur", + "Automatically change preview file with selected file": "Automatically change preview file with selected file", + "Single/Double Click to open a file": "Single/Double Click to open a file", + "Double click to open items under sidebar section": "Double click to open items under sidebar section", + "Double click to open items under home section": "Double click to open items under home section", + "Double click to open files/folders": "Double click to open files/folders", + "Preference": "Préférences", + "App Language": "Langue de l'application", + "Files and Folders": "Fichiers et dossiers", + "Hide hidden files": "Masquer les fichiers cachés", + "Hide system files": "Cacher les fichiers système", + "List and sort directories alongside files": "Lister et trier les répertoires à côté des fichiers", + "On startup": "Au démarrage", + "New tab": "Nouvel onglet", + "Continue previous session": "Continue previous session", + "Workspace": "Espace de travail", + "Show Info Bar": "Afficher la barre d'info", + "About": "À propos", + "Layout Mode": "Mode d'affichage", + "Grid View (Large)": "Vue Grille (Large)", + "Grid View (Medium)": "Vue Grille (Moyenne)", + "Grid View (Small)": "Vue Grille (Petit)", + "Detail View": "Vue détaillée", + "Sort By": "Trier par", + "A-Z": "A-Z", + "Z-A": "Z-A", + "Last Modified": "Dernière Modification", + "First Modified": "Première modification", + "Size": "Taille", + "Type": "Type", + "Reload": "Redémarrer", + "Copy": "Copier", + "Cut": "Couper", + "Paste": "Coller", + "Undo Action": "Annuler l'action", + "Redo Action": "Refaire l'action", + "Copy Location Path": "Copier le chemin de l'emplacement", + "Clear Recent List": "Effacez l'historique récent", + "Open": "Ouvrir", + "Open in Terminal": "Ouvrir dans le Terminal", + "Open in VSCode": "Ouvrir dans VSCode", + "New": "Nouveau", + "File": "Fichier", + "Folder": "Dossier", + "Unpin from Sidebar": "Désépingler de la barre latérale", + "Pin to Sidebar": "Épingler à la barre latérale", + "Compress to Zip": "Compresser en Zip", + "Properties": "Proprietés", + "Rename": "Renommer", + "Delete": "Supprimer", + "Restore": "Restaurer", + "Permanently Delete": "Supprimer définitivement", + "Open in New Tab": "Ouvrir dans un nouvel onglet", + "Preview": "Aperçu", + "Restore all files": "Récupérer tous les fichiers", + "Permanently delete all files": "Supprimer définitivement tous les fichiers", + "Restore these files": "Restaurer ces fichiers", + "Permanently delete these files": "Supprimer définitivement ces fichiers", + "Calculate sub folder size": "Calculer la taille du sous-dossier", + "Search": "Chercher", + "Minimize": "Réduire", + "Maximize": "Maximiser", + "Exit (Ctrl + w)": "Quitter (Ctrl + w)", + "Go Back (Alt + Left Arrow)": "Retour en arrière (Alt + Left Arrow)", + "Go Forward (Alt + Right Arrow)": "Aller de l'avant (Alt + Right Arrow)", + "Parent Directory (Alt + Up Arrow)": "Dossier parent (Alt + Up Arrow)", + "Reload (f5)": "Recharger (f5)", + "Close Tab": "Fermer Tab" } diff --git a/src/Locales/hr-HR.json b/src/Locales/hr-HR.json index 0c3c1136..8581d24d 100644 --- a/src/Locales/hr-HR.json +++ b/src/Locales/hr-HR.json @@ -1,114 +1,114 @@ { - "Favorites": "Favoriti", - "Desktop": "Radna površina", - "Documents": "Dokumenti", - "Downloads": "Preuzimanja", - "Pictures": "Slike", - "Music": "Glazba", - "Videos": "Videozapisi", - "Icon": "Ikona", - "Show hidden files": "Prikaži skrivene datoteke", - "Files": "Datoteke", - "Pendrives": "Pogoni", - "Home": "Početna", - "Recent": "Nedavno", - "Trash": "Smeće", - "Drives": "Diskovi", - "free of": "slobodno od", - "Settings": "Postavke", - "Appearance": "Izgled", - "App Theme": "Tema aplikacije", - "Apply Shadow Effect": "Apply Shadow Effect", - "File Preview": "File Preview", - "Default File Layout": "Default File Layout", - "Show image as thumbnail": "Show image as thumbnail", - "Disabled": "Disabled", - "For small directory (recommended)": "For small directory (recommended)", - "Enable for all directory": "Enable for all directory", - "System Default": "Zadana postavka sustava", - "Automatically play video file as thumbnail (May consume high amount of RAM)": "Automatically play video file as thumbnail (May consume high amount of RAM)", - "Extract exe file icon and make it as the thumbnail (Turning it on might crashes Xplorer)": "Izvadi ikonu exe datoteke i uključi je kao sličicu (Uključivanje može srušiti Xplorer)", - "Preview image on hover": "Preview image on hover", - "Font Family": "Font Family", - "Font Size": "Font Size", - "Window Transparency": "Window Transparency", - "Transparent Effect": "Transparent Effect", - "Blur": "Blur", - "Acrylic": "Acrylic", - "Mica": "Mica", - "Vibrancy": "Vibrancy (MacOS)", - "None": "None", - "Transparent Sidebar": "Transparent Sidebar", - "Transparent Topbar": "Transparent Topbar", - "Transparent Workspace": "Transparent Workspace", - "Frame Style": "Frame Style", - "Default": "Default", - "Detect Drive Change": "Detect Drive Change", - "Automatically change preview file with selected file": "Automatically change preview file with selected file", - "Single/Double Click to open a file": "Single/Double Click to open a file", - "Double click to open items under sidebar section": "Double click to open items under sidebar section", - "Double click to open items under home section": "Double click to open items under home section", - "Double click to open files/folders": "Double click to open files/folders", - "Preference": "Preference", - "App Language": "Jezik aplikacije", - "Files and Folders": "Datoteke i Mape", - "Hide hidden files": "Sakrij skrivene datoteke", - "Hide system files": "Hide system files", - "List and sort directories alongside files": "Prikaži i sortiraj mape uz datoteke", - "On startup": "On startup", - "New tab": "New tab", - "Continue previous session": "Continue previous session", - "Workspace": "Workspace", - "Show Info Bar": "Show Info Bar", - "About": "O", - "Layout Mode": "Način izgleda", - "Grid View (Large)": "Prikaz u obliku velike rešetke", - "Grid View (Medium)": "Prikaz u obliku rešetke", - "Grid View (Small)": "Prikaz u obliku male rešetke", - "Detail View": "Detaljan prikaz", - "Sort By": "Sortiraj po", - "A-Z": "A-Z", - "Z-A": "Z-A", - "Last Modified": "Zadnji put modificirano", - "First Modified": "Prvi put modificirano", - "Size": "Veličina", - "Type": "Tip", - "Reload": "Ponovno učitaj", - "Copy": "Kopiraj", - "Cut": "Izreži", - "Paste": "Zalijepi", - "Undo Action": "Poništi", - "Redo Action": "Ponovi", - "Copy Location Path": "Kopiraj lokaciju", - "Clear Recent List": "Clear Recent List", - "Open": "Open", - "Open in Terminal": "Open in Terminal", - "Open in VSCode": "Open in VSCode", - "New": "New", - "File": "File", - "Folder": "Folder", - "Unpin from Sidebar": "Unpin from Sidebar", - "Pin to Sidebar": "Pin to Sidebar", - "Compress to Zip": "Compress to Zip", - "Properties": "Properties", - "Rename": "Rename", - "Delete": "Delete", - "Restore": "Restore", - "Permanently Delete": "Permanently Delete", - "Open in New Tab": "Open in New Tab", - "Preview": "Preview", - "Restore all files": "Restore all files", - "Permanently delete all files": "Permanently delete all files", - "Restore these files": "Restore these files", - "Permanently delete these files": "Permanently delete these files", - "Calculate sub folder size": "Calculate sub folder size", - "Search": "Search", - "Minimize": "Minimize", - "Maximize": "Maximize", - "Exit (Ctrl + w)": "Exit (Ctrl + w)", - "Go Back (Alt + Left Arrow)": "Go Back (Alt + Left Arrow)", - "Go Forward (Alt + Right Arrow)": "Go Forward (Alt + Right Arrow)", - "Parent Directory (Alt + Up Arrow)": "Parent Directory (Alt + Up Arrow)", - "Reload (f5)": "Reload (f5)", - "Close Tab": "Close Tab" + "Favorites": "Favoriti", + "Desktop": "Radna površina", + "Documents": "Dokumenti", + "Downloads": "Preuzimanja", + "Pictures": "Slike", + "Music": "Glazba", + "Videos": "Videozapisi", + "Icon": "Ikona", + "Show hidden files": "Prikaži skrivene datoteke", + "Files": "Datoteke", + "Pendrives": "Pogoni", + "Home": "Početna", + "Recent": "Nedavno", + "Trash": "Smeće", + "Drives": "Diskovi", + "free of": "slobodno od", + "Settings": "Postavke", + "Appearance": "Izgled", + "App Theme": "Tema aplikacije", + "Apply Shadow Effect": "Apply Shadow Effect", + "File Preview": "File Preview", + "Default File Layout": "Default File Layout", + "Show image as thumbnail": "Show image as thumbnail", + "Disabled": "Disabled", + "For small directory (recommended)": "For small directory (recommended)", + "Enable for all directory": "Enable for all directory", + "System Default": "Zadana postavka sustava", + "Automatically play video file as thumbnail (May consume high amount of RAM)": "Automatically play video file as thumbnail (May consume high amount of RAM)", + "Extract exe file icon and make it as the thumbnail (Turning it on might crashes Xplorer)": "Izvadi ikonu exe datoteke i uključi je kao sličicu (Uključivanje može srušiti Xplorer)", + "Preview image on hover": "Preview image on hover", + "Font Family": "Font Family", + "Font Size": "Font Size", + "Window Transparency": "Window Transparency", + "Transparent Effect": "Transparent Effect", + "Blur": "Blur", + "Acrylic": "Acrylic", + "Mica": "Mica", + "Vibrancy": "Vibrancy (MacOS)", + "None": "None", + "Transparent Sidebar": "Transparent Sidebar", + "Transparent Topbar": "Transparent Topbar", + "Transparent Workspace": "Transparent Workspace", + "Frame Style": "Frame Style", + "Default": "Default", + "Detect Drive Change": "Detect Drive Change", + "Automatically change preview file with selected file": "Automatically change preview file with selected file", + "Single/Double Click to open a file": "Single/Double Click to open a file", + "Double click to open items under sidebar section": "Double click to open items under sidebar section", + "Double click to open items under home section": "Double click to open items under home section", + "Double click to open files/folders": "Double click to open files/folders", + "Preference": "Preference", + "App Language": "Jezik aplikacije", + "Files and Folders": "Datoteke i Mape", + "Hide hidden files": "Sakrij skrivene datoteke", + "Hide system files": "Hide system files", + "List and sort directories alongside files": "Prikaži i sortiraj mape uz datoteke", + "On startup": "On startup", + "New tab": "New tab", + "Continue previous session": "Continue previous session", + "Workspace": "Workspace", + "Show Info Bar": "Show Info Bar", + "About": "O", + "Layout Mode": "Način izgleda", + "Grid View (Large)": "Prikaz u obliku velike rešetke", + "Grid View (Medium)": "Prikaz u obliku rešetke", + "Grid View (Small)": "Prikaz u obliku male rešetke", + "Detail View": "Detaljan prikaz", + "Sort By": "Sortiraj po", + "A-Z": "A-Z", + "Z-A": "Z-A", + "Last Modified": "Zadnji put modificirano", + "First Modified": "Prvi put modificirano", + "Size": "Veličina", + "Type": "Tip", + "Reload": "Ponovno učitaj", + "Copy": "Kopiraj", + "Cut": "Izreži", + "Paste": "Zalijepi", + "Undo Action": "Poništi", + "Redo Action": "Ponovi", + "Copy Location Path": "Kopiraj lokaciju", + "Clear Recent List": "Clear Recent List", + "Open": "Open", + "Open in Terminal": "Open in Terminal", + "Open in VSCode": "Open in VSCode", + "New": "New", + "File": "File", + "Folder": "Folder", + "Unpin from Sidebar": "Unpin from Sidebar", + "Pin to Sidebar": "Pin to Sidebar", + "Compress to Zip": "Compress to Zip", + "Properties": "Properties", + "Rename": "Rename", + "Delete": "Delete", + "Restore": "Restore", + "Permanently Delete": "Permanently Delete", + "Open in New Tab": "Open in New Tab", + "Preview": "Preview", + "Restore all files": "Restore all files", + "Permanently delete all files": "Permanently delete all files", + "Restore these files": "Restore these files", + "Permanently delete these files": "Permanently delete these files", + "Calculate sub folder size": "Calculate sub folder size", + "Search": "Search", + "Minimize": "Minimize", + "Maximize": "Maximize", + "Exit (Ctrl + w)": "Exit (Ctrl + w)", + "Go Back (Alt + Left Arrow)": "Go Back (Alt + Left Arrow)", + "Go Forward (Alt + Right Arrow)": "Go Forward (Alt + Right Arrow)", + "Parent Directory (Alt + Up Arrow)": "Parent Directory (Alt + Up Arrow)", + "Reload (f5)": "Reload (f5)", + "Close Tab": "Close Tab" } diff --git a/src/Locales/id-ID.json b/src/Locales/id-ID.json index f4f2ca88..408a470b 100644 --- a/src/Locales/id-ID.json +++ b/src/Locales/id-ID.json @@ -1,114 +1,114 @@ { - "Favorites": "Favorit", - "Desktop": "Desktop", - "Documents": "Dokumen", - "Downloads": "Unduhan", - "Pictures": "Gambar", - "Music": "Musik", - "Videos": "Video", - "Icon": "Ikon", - "Show hidden files": "Tampilkan berkas tersembunyi ", - "Files": "Berkas", - "Pendrives": "Flashdisk", - "Home": "Beranda", - "Recent": "Terkini", - "Trash": "Tong Sampah", - "Drives": "Disk", - "free of": "bebas dari", - "Settings": "Setelan", - "Appearance": "Tampilan", - "App Theme": "Tema Aplikasi", - "Apply Shadow Effect": "Apply Shadow Effect", - "File Preview": "Pratinjau File", - "Default File Layout": "Tata Letak Bawaan", - "Show image as thumbnail": "Tampilkan berkas gambar sebagai thumbnail", - "Disabled": "Disabled", - "For small directory (recommended)": "For small directory (recommended)", - "Enable for all directory": "Enable for all directory", - "System Default": "Bawaan Sistem", - "Automatically play video file as thumbnail (May consume high amount of RAM)": "Putar berkas video sebagai thumbnail video (Dapat memakan RAM dalam jumlah besar)", - "Extract exe file icon and make it as the thumbnail (Turning it on might crashes Xplorer)": "Ekstrak icon dari file exe dan membuatnya sebagai thumbnail (menyalakannya mungkin dapat merusak Xplorer)", - "Preview image on hover": "Pratinjau gambar saat mengarahkan kursor", - "Font Family": "Jenis Huruf", - "Font Size": "Font Size", - "Window Transparency": "Transparansi Jendela", - "Transparent Effect": "Efek Transparan", - "Blur": "Blur", - "Acrylic": "Acrylic", - "Mica": "Mica", - "Vibrancy": "Vibrancy (MacOS)", - "None": "None", - "Transparent Sidebar": "Bilah Samping Transparan", - "Transparent Topbar": "Bilah Atas Transparan", - "Transparent Workspace": "Ruang Kerja Transparan", - "Frame Style": "Gaya Bingkai", - "Default": "Bawaan", - "Detect Drive Change": "Deteksi Perubahan Perangkat", - "Automatically change preview file with selected file": "Automatically change preview file with selected file", - "Single/Double Click to open a file": "Single/Double Click to open a file", - "Double click to open items under sidebar section": "Double click to open items under sidebar section", - "Double click to open items under home section": "Double click to open items under home section", - "Double click to open files/folders": "Double click to open files/folders", - "Preference": "Preferensi", - "App Language": "Bahasa Aplikasi", - "Files and Folders": "File dan Folder", - "Hide hidden files": "Sembunyikan berkas tersembunyi", - "Hide system files": "Hide system files", - "List and sort directories alongside files": "Tampilkan dan susun direktori bersama dengan berkas", - "On startup": "Pada startup", - "New tab": "New tab", - "Continue previous session": "Continue previous session", - "Workspace": "Ruang Kerja", - "Show Info Bar": "Tampilkan Bilah Informasi", - "About": "Tentang", - "Layout Mode": "Mode Tata Letak", - "Grid View (Large)": "Tampilan Grid (Besar)", - "Grid View (Medium)": "Tampilan Grid (Sedang)", - "Grid View (Small)": "Tampilan Grid (Kecil)", - "Detail View": "Tampilan Detail", - "Sort By": "Sortir Dengan", - "A-Z": "A-Z", - "Z-A": "Z-A", - "Last Modified": "Terakhir Kali Dimodifikasi", - "First Modified": "Pertama Dimodifikasi", - "Size": "Ukuran", - "Type": "Tipe", - "Reload": "Segarkan", - "Copy": "Salin", - "Cut": "Potong", - "Paste": "Tempel", - "Undo Action": "Batalkan Tindakan", - "Redo Action": "Lakukan Ulang", - "Copy Location Path": "Salin Lokasi", - "Clear Recent List": "Hapus Daftar Belakangan Ini", - "Open": "Open", - "Open in Terminal": "Buka di Terminal", - "Open in VSCode": "Buka di VSCode", - "New": "Baru", - "File": "Berkas", - "Folder": "Direktori", - "Unpin from Sidebar": "Unpin dari Sidebar", - "Pin to Sidebar": "Pin ke Sidebar", - "Compress to Zip": "Compress to Zip", - "Properties": "Properti", - "Rename": "Ganti Nama", - "Delete": "Hapus", - "Restore": "Pulihkan", - "Permanently Delete": "Hapus Secara Permanen", - "Open in New Tab": "Buka di Tab Baru", - "Preview": "Pratinjau", - "Restore all files": "Pulihkan semua file", - "Permanently delete all files": "Hapus seluruh berkas secara permanen", - "Restore these files": "Pulihkan berkas tersebut", - "Permanently delete these files": "Hapus berkas tersebut secara permanen", - "Calculate sub folder size": "Calculate sub folder size", - "Search": "Search", - "Minimize": "Minimize", - "Maximize": "Maximize", - "Exit (Ctrl + w)": "Exit (Ctrl + w)", - "Go Back (Alt + Left Arrow)": "Go Back (Alt + Left Arrow)", - "Go Forward (Alt + Right Arrow)": "Go Forward (Alt + Right Arrow)", - "Parent Directory (Alt + Up Arrow)": "Parent Directory (Alt + Up Arrow)", - "Reload (f5)": "Reload (f5)", - "Close Tab": "Close Tab" + "Favorites": "Favorit", + "Desktop": "Desktop", + "Documents": "Dokumen", + "Downloads": "Unduhan", + "Pictures": "Gambar", + "Music": "Musik", + "Videos": "Video", + "Icon": "Ikon", + "Show hidden files": "Tampilkan berkas tersembunyi ", + "Files": "Berkas", + "Pendrives": "Flashdisk", + "Home": "Beranda", + "Recent": "Terkini", + "Trash": "Tong Sampah", + "Drives": "Disk", + "free of": "bebas dari", + "Settings": "Setelan", + "Appearance": "Tampilan", + "App Theme": "Tema Aplikasi", + "Apply Shadow Effect": "Apply Shadow Effect", + "File Preview": "Pratinjau File", + "Default File Layout": "Tata Letak Bawaan", + "Show image as thumbnail": "Tampilkan berkas gambar sebagai thumbnail", + "Disabled": "Disabled", + "For small directory (recommended)": "For small directory (recommended)", + "Enable for all directory": "Enable for all directory", + "System Default": "Bawaan Sistem", + "Automatically play video file as thumbnail (May consume high amount of RAM)": "Putar berkas video sebagai thumbnail video (Dapat memakan RAM dalam jumlah besar)", + "Extract exe file icon and make it as the thumbnail (Turning it on might crashes Xplorer)": "Ekstrak icon dari file exe dan membuatnya sebagai thumbnail (menyalakannya mungkin dapat merusak Xplorer)", + "Preview image on hover": "Pratinjau gambar saat mengarahkan kursor", + "Font Family": "Jenis Huruf", + "Font Size": "Font Size", + "Window Transparency": "Transparansi Jendela", + "Transparent Effect": "Efek Transparan", + "Blur": "Blur", + "Acrylic": "Acrylic", + "Mica": "Mica", + "Vibrancy": "Vibrancy (MacOS)", + "None": "None", + "Transparent Sidebar": "Bilah Samping Transparan", + "Transparent Topbar": "Bilah Atas Transparan", + "Transparent Workspace": "Ruang Kerja Transparan", + "Frame Style": "Gaya Bingkai", + "Default": "Bawaan", + "Detect Drive Change": "Deteksi Perubahan Perangkat", + "Automatically change preview file with selected file": "Automatically change preview file with selected file", + "Single/Double Click to open a file": "Single/Double Click to open a file", + "Double click to open items under sidebar section": "Double click to open items under sidebar section", + "Double click to open items under home section": "Double click to open items under home section", + "Double click to open files/folders": "Double click to open files/folders", + "Preference": "Preferensi", + "App Language": "Bahasa Aplikasi", + "Files and Folders": "File dan Folder", + "Hide hidden files": "Sembunyikan berkas tersembunyi", + "Hide system files": "Hide system files", + "List and sort directories alongside files": "Tampilkan dan susun direktori bersama dengan berkas", + "On startup": "Pada startup", + "New tab": "New tab", + "Continue previous session": "Continue previous session", + "Workspace": "Ruang Kerja", + "Show Info Bar": "Tampilkan Bilah Informasi", + "About": "Tentang", + "Layout Mode": "Mode Tata Letak", + "Grid View (Large)": "Tampilan Grid (Besar)", + "Grid View (Medium)": "Tampilan Grid (Sedang)", + "Grid View (Small)": "Tampilan Grid (Kecil)", + "Detail View": "Tampilan Detail", + "Sort By": "Sortir Dengan", + "A-Z": "A-Z", + "Z-A": "Z-A", + "Last Modified": "Terakhir Kali Dimodifikasi", + "First Modified": "Pertama Dimodifikasi", + "Size": "Ukuran", + "Type": "Tipe", + "Reload": "Segarkan", + "Copy": "Salin", + "Cut": "Potong", + "Paste": "Tempel", + "Undo Action": "Batalkan Tindakan", + "Redo Action": "Lakukan Ulang", + "Copy Location Path": "Salin Lokasi", + "Clear Recent List": "Hapus Daftar Belakangan Ini", + "Open": "Open", + "Open in Terminal": "Buka di Terminal", + "Open in VSCode": "Buka di VSCode", + "New": "Baru", + "File": "Berkas", + "Folder": "Direktori", + "Unpin from Sidebar": "Unpin dari Sidebar", + "Pin to Sidebar": "Pin ke Sidebar", + "Compress to Zip": "Compress to Zip", + "Properties": "Properti", + "Rename": "Ganti Nama", + "Delete": "Hapus", + "Restore": "Pulihkan", + "Permanently Delete": "Hapus Secara Permanen", + "Open in New Tab": "Buka di Tab Baru", + "Preview": "Pratinjau", + "Restore all files": "Pulihkan semua file", + "Permanently delete all files": "Hapus seluruh berkas secara permanen", + "Restore these files": "Pulihkan berkas tersebut", + "Permanently delete these files": "Hapus berkas tersebut secara permanen", + "Calculate sub folder size": "Calculate sub folder size", + "Search": "Search", + "Minimize": "Minimize", + "Maximize": "Maximize", + "Exit (Ctrl + w)": "Exit (Ctrl + w)", + "Go Back (Alt + Left Arrow)": "Go Back (Alt + Left Arrow)", + "Go Forward (Alt + Right Arrow)": "Go Forward (Alt + Right Arrow)", + "Parent Directory (Alt + Up Arrow)": "Parent Directory (Alt + Up Arrow)", + "Reload (f5)": "Reload (f5)", + "Close Tab": "Close Tab" } diff --git a/src/Locales/index.json b/src/Locales/index.json index 8f8405e5..77bfe02e 100644 --- a/src/Locales/index.json +++ b/src/Locales/index.json @@ -1,22 +1,22 @@ { - "availableLanguages": { - "عربي": "ar-SA", - "German": "de-DE", - "Español": "es-ES", - "English": "en-US", - "Français": "fr-FR", - "Hrvatska": "hr-HR", - "Bahasa Indonesia": "id-ID", - "Italiano": "it-IT", - "日本語": "ja-JP", - "한국어": "ko-KR", - "Bahasa Melayu": "ms-MY", - "Polish": "pl-PL", - "Portuguese, Brazilian": "pt-BR", - "Русский": "ru-RU", - "Türkçe": "tr-TR", - "Українська": "uk-UA", - "中文 (简体)": "zh-CN", - "中文 (繁體)": "zh-TW" - } + "availableLanguages": { + "عربي": "ar-SA", + "German": "de-DE", + "Español": "es-ES", + "English": "en-US", + "Français": "fr-FR", + "Hrvatska": "hr-HR", + "Bahasa Indonesia": "id-ID", + "Italiano": "it-IT", + "日本語": "ja-JP", + "한국어": "ko-KR", + "Bahasa Melayu": "ms-MY", + "Polish": "pl-PL", + "Portuguese, Brazilian": "pt-BR", + "Русский": "ru-RU", + "Türkçe": "tr-TR", + "Українська": "uk-UA", + "中文 (简体)": "zh-CN", + "中文 (繁體)": "zh-TW" + } } diff --git a/src/Locales/it-IT.json b/src/Locales/it-IT.json index d395c88b..b7ab730e 100644 --- a/src/Locales/it-IT.json +++ b/src/Locales/it-IT.json @@ -1,114 +1,114 @@ { - "Favorites": "Preferiti", - "Desktop": "Desktop", - "Documents": "Documenti", - "Downloads": "Downloads", - "Pictures": "Immagini", - "Music": "Musica", - "Videos": "Video", - "Icon": "Icona", - "Show hidden files": "Mostra file nascosti", - "Files": "File", - "Pendrives": "Pendrives", - "Home": "Home", - "Recent": "Recenti", - "Trash": "Cestino", - "Drives": "Unità", - "free of": "liberi da", - "Settings": "Impostazioni", - "Appearance": "Aspetto", - "App Theme": "Tema App", - "Apply Shadow Effect": "Applicare l'Effetto Ombra", - "File Preview": "Anteprima dei file", - "Default File Layout": "Layout di file predefinito", - "Show image as thumbnail": "Mostra immagine come miniatura", - "Disabled": "Disattivato", - "For small directory (recommended)": "Per directory piccole (consigliato)", - "Enable for all directory": "Abilita per tutte le directory", - "System Default": "Predefinito di Sistema", - "Automatically play video file as thumbnail (May consume high amount of RAM)": "Riproduci automaticamente il file video come miniatura (può consumare una grande quantità di RAM)", - "Extract exe file icon and make it as the thumbnail (Turning it on might crashes Xplorer)": "Estrarre l'icona del file exe e renderlo come la miniatura (abilitarlo potrebbe mandare Xplorer in crash)", - "Preview image on hover": "Anteprima immagine al passaggio con mouse", - "Font Family": "Famiglia di font", - "Font Size": "Dimensione del Carattere", - "Window Transparency": "Trasparenza della Finestra", - "Transparent Effect": "Effetto Trasparente", - "Blur": "Sfocatura", - "Acrylic": "Acrylic", - "Mica": "Mica", - "Vibrancy": "Vibrancy (MacOS)", - "None": "Nessuna", - "Transparent Sidebar": "Barra Laterale Trasparente", - "Transparent Topbar": "Barra Superiore Trasparente", - "Transparent Workspace": "Workspace Trasparente", - "Frame Style": "Stile Frame", - "Default": "Predefinito", - "Detect Drive Change": "Rileva Cambi di Unità", - "Automatically change preview file with selected file": "Cambia automaticamente il file di anteprima con il file selezionato", - "Single/Double Click to open a file": "Clic singolo/doppio per aprire un file", - "Double click to open items under sidebar section": "Doppio clic per aprire gli elementi nella sezione della barra laterale", - "Double click to open items under home section": "Doppio clic per aprire gli oggetti nella sezione home", - "Double click to open files/folders": "Doppio clic per aprire file/cartelle", - "Preference": "Preferenza", - "App Language": "Lingua Dell'Applicazione", - "Files and Folders": "File e cartelle", - "Hide hidden files": "Non visualizzare file nascosti", - "Hide system files": "Nascondi File Di Sistema", - "List and sort directories alongside files": "Elenca e ordina le directory insieme ai file", - "On startup": "All'avvio", - "New tab": "Nuova scheda", - "Continue previous session": "Riprendi la sessione precedente", - "Workspace": "Workspace", - "Show Info Bar": "Mostra la barra delle Info", - "About": "Info su", - "Layout Mode": "Modalità di visualizzazione", - "Grid View (Large)": "Dimensione della visualizzazione a griglia(Grande)", - "Grid View (Medium)": "Dimensione della visualizzazione a griglia(Media)", - "Grid View (Small)": "Dimensione della visualizzazione a griglia(Piccola)", - "Detail View": "Vista Dettagliata", - "Sort By": "Ordina per", - "A-Z": "A-Z", - "Z-A": "Z-A", - "Last Modified": "Ultima modifica", - "First Modified": "Prima modifica", - "Size": "Dimensione", - "Type": "Tipo", - "Reload": "Ricarica", - "Copy": "Copia", - "Cut": "Taglia", - "Paste": "Incolla", - "Undo Action": "Annulla Azione", - "Redo Action": "Ripeti Azione", - "Copy Location Path": "Copia percorso", - "Clear Recent List": "Cancella Lista Recenti", - "Open": "Apri", - "Open in Terminal": "Apri nel terminale", - "Open in VSCode": "Apri in vscode", - "New": "Nuovo", - "File": "File", - "Folder": "Cartella", - "Unpin from Sidebar": "Sblocca dalla barra laterale", - "Pin to Sidebar": "Fissa sulla barra laterale", - "Compress to Zip": "Comprimi in file Zip", - "Properties": "Proprietà", - "Rename": "Rinomina", - "Delete": "Elimina", - "Restore": "Ripristina", - "Permanently Delete": "Elimina Definitivamente", - "Open in New Tab": "Apri in nuova scheda", - "Preview": "Anteprima", - "Restore all files": "Ripristina tutti i file", - "Permanently delete all files": "Elimina definitivamente tutti i file", - "Restore these files": "Ripristina questi file", - "Permanently delete these files": "Elimina definitivamente questi file", - "Calculate sub folder size": "Calcola la dimensione della sottocartella", - "Search": "Cerca", - "Minimize": "Minimizza", - "Maximize": "Massimizza", - "Exit (Ctrl + w)": "Esci (Ctrl + w)", - "Go Back (Alt + Left Arrow)": "Torna Indietro (Alt + Freccia Sinistra)", - "Go Forward (Alt + Right Arrow)": "Vai Avanti (Alt + Freccia Destra)", - "Parent Directory (Alt + Up Arrow)": "Cartella Superiore (Alt + Freccia Su)", - "Reload (f5)": "Ricarica (f5)", - "Close Tab": "Chiudi la scheda" + "Favorites": "Preferiti", + "Desktop": "Desktop", + "Documents": "Documenti", + "Downloads": "Downloads", + "Pictures": "Immagini", + "Music": "Musica", + "Videos": "Video", + "Icon": "Icona", + "Show hidden files": "Mostra file nascosti", + "Files": "File", + "Pendrives": "Pendrives", + "Home": "Home", + "Recent": "Recenti", + "Trash": "Cestino", + "Drives": "Unità", + "free of": "liberi da", + "Settings": "Impostazioni", + "Appearance": "Aspetto", + "App Theme": "Tema App", + "Apply Shadow Effect": "Applicare l'Effetto Ombra", + "File Preview": "Anteprima dei file", + "Default File Layout": "Layout di file predefinito", + "Show image as thumbnail": "Mostra immagine come miniatura", + "Disabled": "Disattivato", + "For small directory (recommended)": "Per directory piccole (consigliato)", + "Enable for all directory": "Abilita per tutte le directory", + "System Default": "Predefinito di Sistema", + "Automatically play video file as thumbnail (May consume high amount of RAM)": "Riproduci automaticamente il file video come miniatura (può consumare una grande quantità di RAM)", + "Extract exe file icon and make it as the thumbnail (Turning it on might crashes Xplorer)": "Estrarre l'icona del file exe e renderlo come la miniatura (abilitarlo potrebbe mandare Xplorer in crash)", + "Preview image on hover": "Anteprima immagine al passaggio con mouse", + "Font Family": "Famiglia di font", + "Font Size": "Dimensione del Carattere", + "Window Transparency": "Trasparenza della Finestra", + "Transparent Effect": "Effetto Trasparente", + "Blur": "Sfocatura", + "Acrylic": "Acrylic", + "Mica": "Mica", + "Vibrancy": "Vibrancy (MacOS)", + "None": "Nessuna", + "Transparent Sidebar": "Barra Laterale Trasparente", + "Transparent Topbar": "Barra Superiore Trasparente", + "Transparent Workspace": "Workspace Trasparente", + "Frame Style": "Stile Frame", + "Default": "Predefinito", + "Detect Drive Change": "Rileva Cambi di Unità", + "Automatically change preview file with selected file": "Cambia automaticamente il file di anteprima con il file selezionato", + "Single/Double Click to open a file": "Clic singolo/doppio per aprire un file", + "Double click to open items under sidebar section": "Doppio clic per aprire gli elementi nella sezione della barra laterale", + "Double click to open items under home section": "Doppio clic per aprire gli oggetti nella sezione home", + "Double click to open files/folders": "Doppio clic per aprire file/cartelle", + "Preference": "Preferenza", + "App Language": "Lingua Dell'Applicazione", + "Files and Folders": "File e cartelle", + "Hide hidden files": "Non visualizzare file nascosti", + "Hide system files": "Nascondi File Di Sistema", + "List and sort directories alongside files": "Elenca e ordina le directory insieme ai file", + "On startup": "All'avvio", + "New tab": "Nuova scheda", + "Continue previous session": "Riprendi la sessione precedente", + "Workspace": "Workspace", + "Show Info Bar": "Mostra la barra delle Info", + "About": "Info su", + "Layout Mode": "Modalità di visualizzazione", + "Grid View (Large)": "Dimensione della visualizzazione a griglia(Grande)", + "Grid View (Medium)": "Dimensione della visualizzazione a griglia(Media)", + "Grid View (Small)": "Dimensione della visualizzazione a griglia(Piccola)", + "Detail View": "Vista Dettagliata", + "Sort By": "Ordina per", + "A-Z": "A-Z", + "Z-A": "Z-A", + "Last Modified": "Ultima modifica", + "First Modified": "Prima modifica", + "Size": "Dimensione", + "Type": "Tipo", + "Reload": "Ricarica", + "Copy": "Copia", + "Cut": "Taglia", + "Paste": "Incolla", + "Undo Action": "Annulla Azione", + "Redo Action": "Ripeti Azione", + "Copy Location Path": "Copia percorso", + "Clear Recent List": "Cancella Lista Recenti", + "Open": "Apri", + "Open in Terminal": "Apri nel terminale", + "Open in VSCode": "Apri in vscode", + "New": "Nuovo", + "File": "File", + "Folder": "Cartella", + "Unpin from Sidebar": "Sblocca dalla barra laterale", + "Pin to Sidebar": "Fissa sulla barra laterale", + "Compress to Zip": "Comprimi in file Zip", + "Properties": "Proprietà", + "Rename": "Rinomina", + "Delete": "Elimina", + "Restore": "Ripristina", + "Permanently Delete": "Elimina Definitivamente", + "Open in New Tab": "Apri in nuova scheda", + "Preview": "Anteprima", + "Restore all files": "Ripristina tutti i file", + "Permanently delete all files": "Elimina definitivamente tutti i file", + "Restore these files": "Ripristina questi file", + "Permanently delete these files": "Elimina definitivamente questi file", + "Calculate sub folder size": "Calcola la dimensione della sottocartella", + "Search": "Cerca", + "Minimize": "Minimizza", + "Maximize": "Massimizza", + "Exit (Ctrl + w)": "Esci (Ctrl + w)", + "Go Back (Alt + Left Arrow)": "Torna Indietro (Alt + Freccia Sinistra)", + "Go Forward (Alt + Right Arrow)": "Vai Avanti (Alt + Freccia Destra)", + "Parent Directory (Alt + Up Arrow)": "Cartella Superiore (Alt + Freccia Su)", + "Reload (f5)": "Ricarica (f5)", + "Close Tab": "Chiudi la scheda" } diff --git a/src/Locales/ja-JP.json b/src/Locales/ja-JP.json index b766ba00..4cc2672a 100644 --- a/src/Locales/ja-JP.json +++ b/src/Locales/ja-JP.json @@ -1,114 +1,114 @@ { - "Favorites": "お気に入り", - "Desktop": "デスクトップ", - "Documents": "ドキュメント", - "Downloads": "ダウンロード", - "Pictures": "写真", - "Music": "音楽", - "Videos": "ビデオ", - "Icon": "アイコン", - "Show hidden files": "隠しファイルを表示", - "Files": "ファイル", - "Pendrives": "USBメモリ", - "Home": "ホーム", - "Recent": "最近", - "Trash": "ゴミ箱", - "Drives": "ドライブ", - "free of": "利用可能なサイズ", - "Settings": "設定", - "Appearance": "外観", - "App Theme": "テーマ", - "Apply Shadow Effect": "Apply Shadow Effect", - "File Preview": "ファイルプレビュー", - "Default File Layout": "デフォルトのレイアウト", - "Show image as thumbnail": "画像をサムネイルとして表示", - "Disabled": "Disabled", - "For small directory (recommended)": "For small directory (recommended)", - "Enable for all directory": "Enable for all directory", - "System Default": "システムの設定と同じ", - "Automatically play video file as thumbnail (May consume high amount of RAM)": "サムネイルとしてビデオファイルを自動的に再生する(RAMを大量消費する可能性があります)", - "Extract exe file icon and make it as the thumbnail (Turning it on might crashes Xplorer)": "Exeファイルのアイコンを抽出してサムネイルにする (Xplorerがクラッシュする可能性があります)", - "Preview image on hover": "ホバーで画像をプレビュー", - "Font Family": "フォントファミリー", - "Font Size": "Font Size", - "Window Transparency": "ウィンドウの透明度", - "Transparent Effect": "Transparent Effect", - "Blur": "Blur", - "Acrylic": "Acrylic", - "Mica": "Mica", - "Vibrancy": "Vibrancy (MacOS)", - "None": "None", - "Transparent Sidebar": "透明なサイドバー", - "Transparent Topbar": "透明なトップバー", - "Transparent Workspace": "透明なワークスペース", - "Frame Style": "フレームスタイル", - "Default": "ディフォルト", - "Detect Drive Change": "ドライブの変更を検出する", - "Automatically change preview file with selected file": "Automatically change preview file with selected file", - "Single/Double Click to open a file": "Single/Double Click to open a file", - "Double click to open items under sidebar section": "Double click to open items under sidebar section", - "Double click to open items under home section": "Double click to open items under home section", - "Double click to open files/folders": "Double click to open files/folders", - "Preference": "設定", - "App Language": "言語", - "Files and Folders": "ファイルとフォルダ", - "Hide hidden files": "隠されたファイルを隠す", - "Hide system files": "Hide system files", - "List and sort directories alongside files": "ファイルと一緒にディレクトリをリストとソートする", - "On startup": "起動時", - "New tab": "New tab", - "Continue previous session": "Continue previous session", - "Workspace": "ワークスペース", - "Show Info Bar": "Show Info Bar", - "About": "xplorer について", - "Layout Mode": "レイアウトモード", - "Grid View (Large)": "グリッドビュー (大)", - "Grid View (Medium)": "グリッドビュー (中)", - "Grid View (Small)": "グリッドビュー (小)", - "Detail View": "詳細ビュー", - "Sort By": "ソート", - "A-Z": "A~Z", - "Z-A": "Z~A", - "Last Modified": "最新変更", - "First Modified": "最新変更", - "Size": "サイズ", - "Type": "タイプ", - "Reload": "リロード", - "Copy": "コピー", - "Cut": "カット", - "Paste": "ペースト", - "Undo Action": "元に戻す", - "Redo Action": "やり直しアクション", - "Copy Location Path": "場所のパスをコピー", - "Clear Recent List": "最近訪問したリストを消去", - "Open": "Open", - "Open in Terminal": "ターミナルで開く", - "Open in VSCode": "VSCodeで開く", - "New": "新しい", - "File": "ファイル", - "Folder": "フォルダー", - "Unpin from Sidebar": "サイドバーからピン留めを解除", - "Pin to Sidebar": "サイドバーにピン留め", - "Compress to Zip": "Compress to Zip", - "Properties": "プロパティ", - "Rename": "名前変更", - "Delete": "削除", - "Restore": "復元", - "Permanently Delete": "完全に削除", - "Open in New Tab": "新しいタブで開く", - "Preview": "プレビュー", - "Restore all files": "すべてのファイルを復元", - "Permanently delete all files": "すべてを完全に削除", - "Restore these files": "すべてを復元", - "Permanently delete these files": "すべてを完全に削除", - "Calculate sub folder size": "Calculate sub folder size", - "Search": "Search", - "Minimize": "Minimize", - "Maximize": "Maximize", - "Exit (Ctrl + w)": "Exit (Ctrl + w)", - "Go Back (Alt + Left Arrow)": "Go Back (Alt + Left Arrow)", - "Go Forward (Alt + Right Arrow)": "Go Forward (Alt + Right Arrow)", - "Parent Directory (Alt + Up Arrow)": "Parent Directory (Alt + Up Arrow)", - "Reload (f5)": "Reload (f5)", - "Close Tab": "Close Tab" + "Favorites": "お気に入り", + "Desktop": "デスクトップ", + "Documents": "ドキュメント", + "Downloads": "ダウンロード", + "Pictures": "写真", + "Music": "音楽", + "Videos": "ビデオ", + "Icon": "アイコン", + "Show hidden files": "隠しファイルを表示", + "Files": "ファイル", + "Pendrives": "USBメモリ", + "Home": "ホーム", + "Recent": "最近", + "Trash": "ゴミ箱", + "Drives": "ドライブ", + "free of": "利用可能なサイズ", + "Settings": "設定", + "Appearance": "外観", + "App Theme": "テーマ", + "Apply Shadow Effect": "Apply Shadow Effect", + "File Preview": "ファイルプレビュー", + "Default File Layout": "デフォルトのレイアウト", + "Show image as thumbnail": "画像をサムネイルとして表示", + "Disabled": "Disabled", + "For small directory (recommended)": "For small directory (recommended)", + "Enable for all directory": "Enable for all directory", + "System Default": "システムの設定と同じ", + "Automatically play video file as thumbnail (May consume high amount of RAM)": "サムネイルとしてビデオファイルを自動的に再生する(RAMを大量消費する可能性があります)", + "Extract exe file icon and make it as the thumbnail (Turning it on might crashes Xplorer)": "Exeファイルのアイコンを抽出してサムネイルにする (Xplorerがクラッシュする可能性があります)", + "Preview image on hover": "ホバーで画像をプレビュー", + "Font Family": "フォントファミリー", + "Font Size": "Font Size", + "Window Transparency": "ウィンドウの透明度", + "Transparent Effect": "Transparent Effect", + "Blur": "Blur", + "Acrylic": "Acrylic", + "Mica": "Mica", + "Vibrancy": "Vibrancy (MacOS)", + "None": "None", + "Transparent Sidebar": "透明なサイドバー", + "Transparent Topbar": "透明なトップバー", + "Transparent Workspace": "透明なワークスペース", + "Frame Style": "フレームスタイル", + "Default": "ディフォルト", + "Detect Drive Change": "ドライブの変更を検出する", + "Automatically change preview file with selected file": "Automatically change preview file with selected file", + "Single/Double Click to open a file": "Single/Double Click to open a file", + "Double click to open items under sidebar section": "Double click to open items under sidebar section", + "Double click to open items under home section": "Double click to open items under home section", + "Double click to open files/folders": "Double click to open files/folders", + "Preference": "設定", + "App Language": "言語", + "Files and Folders": "ファイルとフォルダ", + "Hide hidden files": "隠されたファイルを隠す", + "Hide system files": "Hide system files", + "List and sort directories alongside files": "ファイルと一緒にディレクトリをリストとソートする", + "On startup": "起動時", + "New tab": "New tab", + "Continue previous session": "Continue previous session", + "Workspace": "ワークスペース", + "Show Info Bar": "Show Info Bar", + "About": "xplorer について", + "Layout Mode": "レイアウトモード", + "Grid View (Large)": "グリッドビュー (大)", + "Grid View (Medium)": "グリッドビュー (中)", + "Grid View (Small)": "グリッドビュー (小)", + "Detail View": "詳細ビュー", + "Sort By": "ソート", + "A-Z": "A~Z", + "Z-A": "Z~A", + "Last Modified": "最新変更", + "First Modified": "最新変更", + "Size": "サイズ", + "Type": "タイプ", + "Reload": "リロード", + "Copy": "コピー", + "Cut": "カット", + "Paste": "ペースト", + "Undo Action": "元に戻す", + "Redo Action": "やり直しアクション", + "Copy Location Path": "場所のパスをコピー", + "Clear Recent List": "最近訪問したリストを消去", + "Open": "Open", + "Open in Terminal": "ターミナルで開く", + "Open in VSCode": "VSCodeで開く", + "New": "新しい", + "File": "ファイル", + "Folder": "フォルダー", + "Unpin from Sidebar": "サイドバーからピン留めを解除", + "Pin to Sidebar": "サイドバーにピン留め", + "Compress to Zip": "Compress to Zip", + "Properties": "プロパティ", + "Rename": "名前変更", + "Delete": "削除", + "Restore": "復元", + "Permanently Delete": "完全に削除", + "Open in New Tab": "新しいタブで開く", + "Preview": "プレビュー", + "Restore all files": "すべてのファイルを復元", + "Permanently delete all files": "すべてを完全に削除", + "Restore these files": "すべてを復元", + "Permanently delete these files": "すべてを完全に削除", + "Calculate sub folder size": "Calculate sub folder size", + "Search": "Search", + "Minimize": "Minimize", + "Maximize": "Maximize", + "Exit (Ctrl + w)": "Exit (Ctrl + w)", + "Go Back (Alt + Left Arrow)": "Go Back (Alt + Left Arrow)", + "Go Forward (Alt + Right Arrow)": "Go Forward (Alt + Right Arrow)", + "Parent Directory (Alt + Up Arrow)": "Parent Directory (Alt + Up Arrow)", + "Reload (f5)": "Reload (f5)", + "Close Tab": "Close Tab" } diff --git a/src/Locales/ko-KR.json b/src/Locales/ko-KR.json index 6d11dcf1..2248aa91 100644 --- a/src/Locales/ko-KR.json +++ b/src/Locales/ko-KR.json @@ -1,114 +1,114 @@ { - "Favorites": "즐겨찾기", - "Desktop": "바탕 화면", - "Documents": "문서", - "Downloads": "다운로드", - "Pictures": "사진", - "Music": "음악", - "Videos": "동영상", - "Icon": "아이콘", - "Show hidden files": "숨김 파일 표시", - "Files": "파일", - "Pendrives": "USB 드라이브", - "Home": "홈", - "Recent": "최근 사용", - "Trash": "휴지통", - "Drives": "드라이브", - "free of": "사용 가능, 전체", - "Settings": "설정", - "Appearance": "Appearance", - "App Theme": "App Theme", - "Apply Shadow Effect": "Apply Shadow Effect", - "File Preview": "File Preview", - "Default File Layout": "Default File Layout", - "Show image as thumbnail": "Show image as thumbnail", - "Disabled": "Disabled", - "For small directory (recommended)": "For small directory (recommended)", - "Enable for all directory": "Enable for all directory", - "System Default": "System Default", - "Automatically play video file as thumbnail (May consume high amount of RAM)": "Automatically play video file as thumbnail (May consume high amount of RAM)", - "Extract exe file icon and make it as the thumbnail (Turning it on might crashes Xplorer)": "Extract exe file icon and make it as the thumbnail (Turning it on might crashes Xplorer)", - "Preview image on hover": "Preview image on hover", - "Font Family": "Font Family", - "Font Size": "Font Size", - "Window Transparency": "Window Transparency", - "Transparent Effect": "Transparent Effect", - "Blur": "Blur", - "Acrylic": "Acrylic", - "Mica": "Mica", - "Vibrancy": "Vibrancy (MacOS)", - "None": "None", - "Transparent Sidebar": "Transparent Sidebar", - "Transparent Topbar": "Transparent Topbar", - "Transparent Workspace": "Transparent Workspace", - "Frame Style": "Frame Style", - "Default": "Default", - "Detect Drive Change": "Detect Drive Change", - "Automatically change preview file with selected file": "Automatically change preview file with selected file", - "Single/Double Click to open a file": "Single/Double Click to open a file", - "Double click to open items under sidebar section": "Double click to open items under sidebar section", - "Double click to open items under home section": "Double click to open items under home section", - "Double click to open files/folders": "Double click to open files/folders", - "Preference": "Preference", - "App Language": "App Language", - "Files and Folders": "Files and Folders", - "Hide hidden files": "Hide hidden files", - "Hide system files": "Hide system files", - "List and sort directories alongside files": "List and sort directories alongside files", - "On startup": "On startup", - "New tab": "New tab", - "Continue previous session": "Continue previous session", - "Workspace": "Workspace", - "Show Info Bar": "Show Info Bar", - "About": "About", - "Layout Mode": "Layout Mode", - "Grid View (Large)": "Grid View (Large)", - "Grid View (Medium)": "Grid View (Medium)", - "Grid View (Small)": "Grid View (Small)", - "Detail View": "Detail View", - "Sort By": "Sort By", - "A-Z": "A-Z", - "Z-A": "Z-A", - "Last Modified": "Last Modified", - "First Modified": "First Modified", - "Size": "Size", - "Type": "Type", - "Reload": "Reload", - "Copy": "Copy", - "Cut": "Cut", - "Paste": "Paste", - "Undo Action": "Undo Action", - "Redo Action": "Redo Action", - "Copy Location Path": "Copy Location Path", - "Clear Recent List": "Clear Recent List", - "Open": "Open", - "Open in Terminal": "Open in Terminal", - "Open in VSCode": "Open in VSCode", - "New": "New", - "File": "File", - "Folder": "Folder", - "Unpin from Sidebar": "Unpin from Sidebar", - "Pin to Sidebar": "Pin to Sidebar", - "Compress to Zip": "Compress to Zip", - "Properties": "Properties", - "Rename": "Rename", - "Delete": "Delete", - "Restore": "Restore", - "Permanently Delete": "Permanently Delete", - "Open in New Tab": "Open in New Tab", - "Preview": "Preview", - "Restore all files": "Restore all files", - "Permanently delete all files": "Permanently delete all files", - "Restore these files": "Restore these files", - "Permanently delete these files": "Permanently delete these files", - "Calculate sub folder size": "Calculate sub folder size", - "Search": "Search", - "Minimize": "Minimize", - "Maximize": "Maximize", - "Exit (Ctrl + w)": "Exit (Ctrl + w)", - "Go Back (Alt + Left Arrow)": "Go Back (Alt + Left Arrow)", - "Go Forward (Alt + Right Arrow)": "Go Forward (Alt + Right Arrow)", - "Parent Directory (Alt + Up Arrow)": "Parent Directory (Alt + Up Arrow)", - "Reload (f5)": "Reload (f5)", - "Close Tab": "Close Tab" + "Favorites": "즐겨찾기", + "Desktop": "바탕 화면", + "Documents": "문서", + "Downloads": "다운로드", + "Pictures": "사진", + "Music": "음악", + "Videos": "동영상", + "Icon": "아이콘", + "Show hidden files": "숨김 파일 표시", + "Files": "파일", + "Pendrives": "USB 드라이브", + "Home": "홈", + "Recent": "최근 사용", + "Trash": "휴지통", + "Drives": "드라이브", + "free of": "사용 가능, 전체", + "Settings": "설정", + "Appearance": "Appearance", + "App Theme": "App Theme", + "Apply Shadow Effect": "Apply Shadow Effect", + "File Preview": "File Preview", + "Default File Layout": "Default File Layout", + "Show image as thumbnail": "Show image as thumbnail", + "Disabled": "Disabled", + "For small directory (recommended)": "For small directory (recommended)", + "Enable for all directory": "Enable for all directory", + "System Default": "System Default", + "Automatically play video file as thumbnail (May consume high amount of RAM)": "Automatically play video file as thumbnail (May consume high amount of RAM)", + "Extract exe file icon and make it as the thumbnail (Turning it on might crashes Xplorer)": "Extract exe file icon and make it as the thumbnail (Turning it on might crashes Xplorer)", + "Preview image on hover": "Preview image on hover", + "Font Family": "Font Family", + "Font Size": "Font Size", + "Window Transparency": "Window Transparency", + "Transparent Effect": "Transparent Effect", + "Blur": "Blur", + "Acrylic": "Acrylic", + "Mica": "Mica", + "Vibrancy": "Vibrancy (MacOS)", + "None": "None", + "Transparent Sidebar": "Transparent Sidebar", + "Transparent Topbar": "Transparent Topbar", + "Transparent Workspace": "Transparent Workspace", + "Frame Style": "Frame Style", + "Default": "Default", + "Detect Drive Change": "Detect Drive Change", + "Automatically change preview file with selected file": "Automatically change preview file with selected file", + "Single/Double Click to open a file": "Single/Double Click to open a file", + "Double click to open items under sidebar section": "Double click to open items under sidebar section", + "Double click to open items under home section": "Double click to open items under home section", + "Double click to open files/folders": "Double click to open files/folders", + "Preference": "Preference", + "App Language": "App Language", + "Files and Folders": "Files and Folders", + "Hide hidden files": "Hide hidden files", + "Hide system files": "Hide system files", + "List and sort directories alongside files": "List and sort directories alongside files", + "On startup": "On startup", + "New tab": "New tab", + "Continue previous session": "Continue previous session", + "Workspace": "Workspace", + "Show Info Bar": "Show Info Bar", + "About": "About", + "Layout Mode": "Layout Mode", + "Grid View (Large)": "Grid View (Large)", + "Grid View (Medium)": "Grid View (Medium)", + "Grid View (Small)": "Grid View (Small)", + "Detail View": "Detail View", + "Sort By": "Sort By", + "A-Z": "A-Z", + "Z-A": "Z-A", + "Last Modified": "Last Modified", + "First Modified": "First Modified", + "Size": "Size", + "Type": "Type", + "Reload": "Reload", + "Copy": "Copy", + "Cut": "Cut", + "Paste": "Paste", + "Undo Action": "Undo Action", + "Redo Action": "Redo Action", + "Copy Location Path": "Copy Location Path", + "Clear Recent List": "Clear Recent List", + "Open": "Open", + "Open in Terminal": "Open in Terminal", + "Open in VSCode": "Open in VSCode", + "New": "New", + "File": "File", + "Folder": "Folder", + "Unpin from Sidebar": "Unpin from Sidebar", + "Pin to Sidebar": "Pin to Sidebar", + "Compress to Zip": "Compress to Zip", + "Properties": "Properties", + "Rename": "Rename", + "Delete": "Delete", + "Restore": "Restore", + "Permanently Delete": "Permanently Delete", + "Open in New Tab": "Open in New Tab", + "Preview": "Preview", + "Restore all files": "Restore all files", + "Permanently delete all files": "Permanently delete all files", + "Restore these files": "Restore these files", + "Permanently delete these files": "Permanently delete these files", + "Calculate sub folder size": "Calculate sub folder size", + "Search": "Search", + "Minimize": "Minimize", + "Maximize": "Maximize", + "Exit (Ctrl + w)": "Exit (Ctrl + w)", + "Go Back (Alt + Left Arrow)": "Go Back (Alt + Left Arrow)", + "Go Forward (Alt + Right Arrow)": "Go Forward (Alt + Right Arrow)", + "Parent Directory (Alt + Up Arrow)": "Parent Directory (Alt + Up Arrow)", + "Reload (f5)": "Reload (f5)", + "Close Tab": "Close Tab" } diff --git a/src/Locales/ms-MY.json b/src/Locales/ms-MY.json index 2bf3b11f..07ff7a77 100644 --- a/src/Locales/ms-MY.json +++ b/src/Locales/ms-MY.json @@ -1,114 +1,114 @@ { - "Favorites": "Kegemaran", - "Desktop": "Desktop", - "Documents": "Dokumen", - "Downloads": "Muat turun", - "Pictures": "Gambar", - "Music": "Muzik", - "Videos": "Video", - "Icon": "Ikon", - "Show hidden files": "Tayang fail tersembunyi", - "Files": "Fail", - "Pendrives": "Pemacu kilat", - "Home": "Laman utama", - "Recent": "Terkini", - "Trash": "Tong Sampah", - "Drives": "Pemacu Keras", - "free of": "bebas dari", - "Settings": "Tetapan", - "Appearance": "Appearance", - "App Theme": "App Theme", - "Apply Shadow Effect": "Apply Shadow Effect", - "File Preview": "File Preview", - "Default File Layout": "Default File Layout", - "Show image as thumbnail": "Show image as thumbnail", - "Disabled": "Disabled", - "For small directory (recommended)": "For small directory (recommended)", - "Enable for all directory": "Enable for all directory", - "System Default": "System Default", - "Automatically play video file as thumbnail (May consume high amount of RAM)": "Automatically play video file as thumbnail (May consume high amount of RAM)", - "Extract exe file icon and make it as the thumbnail (Turning it on might crashes Xplorer)": "Extract exe file icon and make it as the thumbnail (Turning it on might crashes Xplorer)", - "Preview image on hover": "Preview image on hover", - "Font Family": "Font Family", - "Font Size": "Font Size", - "Window Transparency": "Window Transparency", - "Transparent Effect": "Transparent Effect", - "Blur": "Blur", - "Acrylic": "Acrylic", - "Mica": "Mica", - "Vibrancy": "Vibrancy (MacOS)", - "None": "None", - "Transparent Sidebar": "Transparent Sidebar", - "Transparent Topbar": "Transparent Topbar", - "Transparent Workspace": "Transparent Workspace", - "Frame Style": "Frame Style", - "Default": "Default", - "Detect Drive Change": "Detect Drive Change", - "Automatically change preview file with selected file": "Automatically change preview file with selected file", - "Single/Double Click to open a file": "Single/Double Click to open a file", - "Double click to open items under sidebar section": "Double click to open items under sidebar section", - "Double click to open items under home section": "Double click to open items under home section", - "Double click to open files/folders": "Double click to open files/folders", - "Preference": "Preference", - "App Language": "App Language", - "Files and Folders": "Files and Folders", - "Hide hidden files": "Hide hidden files", - "Hide system files": "Hide system files", - "List and sort directories alongside files": "List and sort directories alongside files", - "On startup": "On startup", - "New tab": "New tab", - "Continue previous session": "Continue previous session", - "Workspace": "Workspace", - "Show Info Bar": "Show Info Bar", - "About": "About", - "Layout Mode": "Layout Mode", - "Grid View (Large)": "Grid View (Large)", - "Grid View (Medium)": "Grid View (Medium)", - "Grid View (Small)": "Grid View (Small)", - "Detail View": "Detail View", - "Sort By": "Sort By", - "A-Z": "A-Z", - "Z-A": "Z-A", - "Last Modified": "Last Modified", - "First Modified": "First Modified", - "Size": "Size", - "Type": "Type", - "Reload": "Reload", - "Copy": "Copy", - "Cut": "Cut", - "Paste": "Paste", - "Undo Action": "Undo Action", - "Redo Action": "Redo Action", - "Copy Location Path": "Copy Location Path", - "Clear Recent List": "Clear Recent List", - "Open": "Open", - "Open in Terminal": "Open in Terminal", - "Open in VSCode": "Open in VSCode", - "New": "New", - "File": "File", - "Folder": "Folder", - "Unpin from Sidebar": "Unpin from Sidebar", - "Pin to Sidebar": "Pin to Sidebar", - "Compress to Zip": "Compress to Zip", - "Properties": "Properties", - "Rename": "Rename", - "Delete": "Delete", - "Restore": "Restore", - "Permanently Delete": "Permanently Delete", - "Open in New Tab": "Open in New Tab", - "Preview": "Preview", - "Restore all files": "Restore all files", - "Permanently delete all files": "Permanently delete all files", - "Restore these files": "Restore these files", - "Permanently delete these files": "Permanently delete these files", - "Calculate sub folder size": "Calculate sub folder size", - "Search": "Search", - "Minimize": "Minimize", - "Maximize": "Maximize", - "Exit (Ctrl + w)": "Exit (Ctrl + w)", - "Go Back (Alt + Left Arrow)": "Go Back (Alt + Left Arrow)", - "Go Forward (Alt + Right Arrow)": "Go Forward (Alt + Right Arrow)", - "Parent Directory (Alt + Up Arrow)": "Parent Directory (Alt + Up Arrow)", - "Reload (f5)": "Reload (f5)", - "Close Tab": "Close Tab" + "Favorites": "Kegemaran", + "Desktop": "Desktop", + "Documents": "Dokumen", + "Downloads": "Muat turun", + "Pictures": "Gambar", + "Music": "Muzik", + "Videos": "Video", + "Icon": "Ikon", + "Show hidden files": "Tayang fail tersembunyi", + "Files": "Fail", + "Pendrives": "Pemacu kilat", + "Home": "Laman utama", + "Recent": "Terkini", + "Trash": "Tong Sampah", + "Drives": "Pemacu Keras", + "free of": "bebas dari", + "Settings": "Tetapan", + "Appearance": "Appearance", + "App Theme": "App Theme", + "Apply Shadow Effect": "Apply Shadow Effect", + "File Preview": "File Preview", + "Default File Layout": "Default File Layout", + "Show image as thumbnail": "Show image as thumbnail", + "Disabled": "Disabled", + "For small directory (recommended)": "For small directory (recommended)", + "Enable for all directory": "Enable for all directory", + "System Default": "System Default", + "Automatically play video file as thumbnail (May consume high amount of RAM)": "Automatically play video file as thumbnail (May consume high amount of RAM)", + "Extract exe file icon and make it as the thumbnail (Turning it on might crashes Xplorer)": "Extract exe file icon and make it as the thumbnail (Turning it on might crashes Xplorer)", + "Preview image on hover": "Preview image on hover", + "Font Family": "Font Family", + "Font Size": "Font Size", + "Window Transparency": "Window Transparency", + "Transparent Effect": "Transparent Effect", + "Blur": "Blur", + "Acrylic": "Acrylic", + "Mica": "Mica", + "Vibrancy": "Vibrancy (MacOS)", + "None": "None", + "Transparent Sidebar": "Transparent Sidebar", + "Transparent Topbar": "Transparent Topbar", + "Transparent Workspace": "Transparent Workspace", + "Frame Style": "Frame Style", + "Default": "Default", + "Detect Drive Change": "Detect Drive Change", + "Automatically change preview file with selected file": "Automatically change preview file with selected file", + "Single/Double Click to open a file": "Single/Double Click to open a file", + "Double click to open items under sidebar section": "Double click to open items under sidebar section", + "Double click to open items under home section": "Double click to open items under home section", + "Double click to open files/folders": "Double click to open files/folders", + "Preference": "Preference", + "App Language": "App Language", + "Files and Folders": "Files and Folders", + "Hide hidden files": "Hide hidden files", + "Hide system files": "Hide system files", + "List and sort directories alongside files": "List and sort directories alongside files", + "On startup": "On startup", + "New tab": "New tab", + "Continue previous session": "Continue previous session", + "Workspace": "Workspace", + "Show Info Bar": "Show Info Bar", + "About": "About", + "Layout Mode": "Layout Mode", + "Grid View (Large)": "Grid View (Large)", + "Grid View (Medium)": "Grid View (Medium)", + "Grid View (Small)": "Grid View (Small)", + "Detail View": "Detail View", + "Sort By": "Sort By", + "A-Z": "A-Z", + "Z-A": "Z-A", + "Last Modified": "Last Modified", + "First Modified": "First Modified", + "Size": "Size", + "Type": "Type", + "Reload": "Reload", + "Copy": "Copy", + "Cut": "Cut", + "Paste": "Paste", + "Undo Action": "Undo Action", + "Redo Action": "Redo Action", + "Copy Location Path": "Copy Location Path", + "Clear Recent List": "Clear Recent List", + "Open": "Open", + "Open in Terminal": "Open in Terminal", + "Open in VSCode": "Open in VSCode", + "New": "New", + "File": "File", + "Folder": "Folder", + "Unpin from Sidebar": "Unpin from Sidebar", + "Pin to Sidebar": "Pin to Sidebar", + "Compress to Zip": "Compress to Zip", + "Properties": "Properties", + "Rename": "Rename", + "Delete": "Delete", + "Restore": "Restore", + "Permanently Delete": "Permanently Delete", + "Open in New Tab": "Open in New Tab", + "Preview": "Preview", + "Restore all files": "Restore all files", + "Permanently delete all files": "Permanently delete all files", + "Restore these files": "Restore these files", + "Permanently delete these files": "Permanently delete these files", + "Calculate sub folder size": "Calculate sub folder size", + "Search": "Search", + "Minimize": "Minimize", + "Maximize": "Maximize", + "Exit (Ctrl + w)": "Exit (Ctrl + w)", + "Go Back (Alt + Left Arrow)": "Go Back (Alt + Left Arrow)", + "Go Forward (Alt + Right Arrow)": "Go Forward (Alt + Right Arrow)", + "Parent Directory (Alt + Up Arrow)": "Parent Directory (Alt + Up Arrow)", + "Reload (f5)": "Reload (f5)", + "Close Tab": "Close Tab" } diff --git a/src/Locales/pl-PL.json b/src/Locales/pl-PL.json index 7c8958ba..0ce09bd8 100644 --- a/src/Locales/pl-PL.json +++ b/src/Locales/pl-PL.json @@ -1,114 +1,114 @@ { - "Favorites": "Ulubione", - "Desktop": "Pulpit", - "Documents": "Dokumenty", - "Downloads": "Pobrane", - "Pictures": "Obrazy", - "Music": "Muzyka", - "Videos": "Filmy", - "Icon": "Ikona", - "Show hidden files": "Pokaż ukryte pliki", - "Files": "Pliki", - "Pendrives": "Pendrive-y", - "Home": "Strona główna", - "Recent": "Ostatnie", - "Trash": "Kosz", - "Drives": "Dyski", - "free of": "wolne z", - "Settings": "Ustawienia", - "Appearance": "Wygląd", - "App Theme": "Motyw aplikacji", - "Apply Shadow Effect": "Apply Shadow Effect", - "File Preview": "Podgląd pliku", - "Default File Layout": "Domyślny układ pliku", - "Show image as thumbnail": "Pokaż obraz jako miniaturkę", - "Disabled": "Disabled", - "For small directory (recommended)": "For small directory (recommended)", - "Enable for all directory": "Enable for all directory", - "System Default": "Domyślne systemowe", - "Automatically play video file as thumbnail (May consume high amount of RAM)": "Automatycznie odtwarzaj plik wideo jako miniaturkę (może zużywać dużą ilość RAM)", - "Extract exe file icon and make it as the thumbnail (Turning it on might crashes Xplorer)": "Wyodrębnij ikonę pliku exe i ustaw ją jako miniaturkę (włączenie jej może spowodować awarię Xplorer)", - "Preview image on hover": "Podejrzyj plik po najechaniu", - "Font Family": "Rodzina czcionek", - "Font Size": "Font Size", - "Window Transparency": "Przezroczystość okna", - "Transparent Effect": "Transparent Effect", - "Blur": "Blur", - "Acrylic": "Acrylic", - "Mica": "Mica", - "Vibrancy": "Vibrancy (MacOS)", - "None": "None", - "Transparent Sidebar": "Przezroczysty pasek boczny", - "Transparent Topbar": "Przezroczysty pasek górny", - "Transparent Workspace": "Przezroczysty obszar roboczy", - "Frame Style": "Styl ramki", - "Default": "Domyślne", - "Detect Drive Change": "Wykryj zmianę dysku", - "Automatically change preview file with selected file": "Automatically change preview file with selected file", - "Single/Double Click to open a file": "Single/Double Click to open a file", - "Double click to open items under sidebar section": "Double click to open items under sidebar section", - "Double click to open items under home section": "Double click to open items under home section", - "Double click to open files/folders": "Double click to open files/folders", - "Preference": "Preferencje", - "App Language": "Język aplikacji", - "Files and Folders": "Pliki i foldery", - "Hide hidden files": "Nie pokazuj ukrytych plików", - "Hide system files": "Hide system files", - "List and sort directories alongside files": "Listuj i sortuj katalogi wraz z plikami", - "On startup": "Przy uruchamianiu", - "New tab": "New tab", - "Continue previous session": "Continue previous session", - "Workspace": "Przestrzeń robocza", - "Show Info Bar": "Pokaż pasek informacyjny", - "About": "O programie", - "Layout Mode": "Układ", - "Grid View (Large)": "Widok siatki (duży)", - "Grid View (Medium)": "Widok siatki (średni)", - "Grid View (Small)": "Widok siatki (mały)", - "Detail View": "Widok szczegółowy", - "Sort By": "Sortuj według", - "A-Z": "A-Z", - "Z-A": "Z-A", - "Last Modified": "Ostatnio modyfikowany", - "First Modified": "Pierwszy zmodyfikowany", - "Size": "Rozmiar", - "Type": "Rodzaj", - "Reload": "Odśwież", - "Copy": "Kopiuj", - "Cut": "Wytnij", - "Paste": "Wklej", - "Undo Action": "Cofnij", - "Redo Action": "Wykonaj ponownie", - "Copy Location Path": "Kopiuj ścieżkę lokalizacji", - "Clear Recent List": "Wyczyść listę ostatnio używanych", - "Open": "Open", - "Open in Terminal": "Otwórz w terminalu", - "Open in VSCode": "Otwórz w VSCode", - "New": "Nowy", - "File": "Plik", - "Folder": "Folder", - "Unpin from Sidebar": "Odepnij z paska bocznego", - "Pin to Sidebar": "Przypnij do paska bocznego", - "Compress to Zip": "Compress to Zip", - "Properties": "Właściwości", - "Rename": "Zmień nazwę", - "Delete": "Usuń", - "Restore": "Przywróć", - "Permanently Delete": "Usuń trwale", - "Open in New Tab": "Otwórz w nowej karcie", - "Preview": "Podgląd", - "Restore all files": "Przywróć wszystkie pliki", - "Permanently delete all files": "Trwale usuń wszystkie pliki", - "Restore these files": "Przywróć te pliki", - "Permanently delete these files": "Trwale usuń te pliki", - "Calculate sub folder size": "Calculate sub folder size", - "Search": "Search", - "Minimize": "Minimize", - "Maximize": "Maximize", - "Exit (Ctrl + w)": "Exit (Ctrl + w)", - "Go Back (Alt + Left Arrow)": "Go Back (Alt + Left Arrow)", - "Go Forward (Alt + Right Arrow)": "Go Forward (Alt + Right Arrow)", - "Parent Directory (Alt + Up Arrow)": "Parent Directory (Alt + Up Arrow)", - "Reload (f5)": "Reload (f5)", - "Close Tab": "Close Tab" + "Favorites": "Ulubione", + "Desktop": "Pulpit", + "Documents": "Dokumenty", + "Downloads": "Pobrane", + "Pictures": "Obrazy", + "Music": "Muzyka", + "Videos": "Filmy", + "Icon": "Ikona", + "Show hidden files": "Pokaż ukryte pliki", + "Files": "Pliki", + "Pendrives": "Pendrive-y", + "Home": "Strona główna", + "Recent": "Ostatnie", + "Trash": "Kosz", + "Drives": "Dyski", + "free of": "wolne z", + "Settings": "Ustawienia", + "Appearance": "Wygląd", + "App Theme": "Motyw aplikacji", + "Apply Shadow Effect": "Apply Shadow Effect", + "File Preview": "Podgląd pliku", + "Default File Layout": "Domyślny układ pliku", + "Show image as thumbnail": "Pokaż obraz jako miniaturkę", + "Disabled": "Disabled", + "For small directory (recommended)": "For small directory (recommended)", + "Enable for all directory": "Enable for all directory", + "System Default": "Domyślne systemowe", + "Automatically play video file as thumbnail (May consume high amount of RAM)": "Automatycznie odtwarzaj plik wideo jako miniaturkę (może zużywać dużą ilość RAM)", + "Extract exe file icon and make it as the thumbnail (Turning it on might crashes Xplorer)": "Wyodrębnij ikonę pliku exe i ustaw ją jako miniaturkę (włączenie jej może spowodować awarię Xplorer)", + "Preview image on hover": "Podejrzyj plik po najechaniu", + "Font Family": "Rodzina czcionek", + "Font Size": "Font Size", + "Window Transparency": "Przezroczystość okna", + "Transparent Effect": "Transparent Effect", + "Blur": "Blur", + "Acrylic": "Acrylic", + "Mica": "Mica", + "Vibrancy": "Vibrancy (MacOS)", + "None": "None", + "Transparent Sidebar": "Przezroczysty pasek boczny", + "Transparent Topbar": "Przezroczysty pasek górny", + "Transparent Workspace": "Przezroczysty obszar roboczy", + "Frame Style": "Styl ramki", + "Default": "Domyślne", + "Detect Drive Change": "Wykryj zmianę dysku", + "Automatically change preview file with selected file": "Automatically change preview file with selected file", + "Single/Double Click to open a file": "Single/Double Click to open a file", + "Double click to open items under sidebar section": "Double click to open items under sidebar section", + "Double click to open items under home section": "Double click to open items under home section", + "Double click to open files/folders": "Double click to open files/folders", + "Preference": "Preferencje", + "App Language": "Język aplikacji", + "Files and Folders": "Pliki i foldery", + "Hide hidden files": "Nie pokazuj ukrytych plików", + "Hide system files": "Hide system files", + "List and sort directories alongside files": "Listuj i sortuj katalogi wraz z plikami", + "On startup": "Przy uruchamianiu", + "New tab": "New tab", + "Continue previous session": "Continue previous session", + "Workspace": "Przestrzeń robocza", + "Show Info Bar": "Pokaż pasek informacyjny", + "About": "O programie", + "Layout Mode": "Układ", + "Grid View (Large)": "Widok siatki (duży)", + "Grid View (Medium)": "Widok siatki (średni)", + "Grid View (Small)": "Widok siatki (mały)", + "Detail View": "Widok szczegółowy", + "Sort By": "Sortuj według", + "A-Z": "A-Z", + "Z-A": "Z-A", + "Last Modified": "Ostatnio modyfikowany", + "First Modified": "Pierwszy zmodyfikowany", + "Size": "Rozmiar", + "Type": "Rodzaj", + "Reload": "Odśwież", + "Copy": "Kopiuj", + "Cut": "Wytnij", + "Paste": "Wklej", + "Undo Action": "Cofnij", + "Redo Action": "Wykonaj ponownie", + "Copy Location Path": "Kopiuj ścieżkę lokalizacji", + "Clear Recent List": "Wyczyść listę ostatnio używanych", + "Open": "Open", + "Open in Terminal": "Otwórz w terminalu", + "Open in VSCode": "Otwórz w VSCode", + "New": "Nowy", + "File": "Plik", + "Folder": "Folder", + "Unpin from Sidebar": "Odepnij z paska bocznego", + "Pin to Sidebar": "Przypnij do paska bocznego", + "Compress to Zip": "Compress to Zip", + "Properties": "Właściwości", + "Rename": "Zmień nazwę", + "Delete": "Usuń", + "Restore": "Przywróć", + "Permanently Delete": "Usuń trwale", + "Open in New Tab": "Otwórz w nowej karcie", + "Preview": "Podgląd", + "Restore all files": "Przywróć wszystkie pliki", + "Permanently delete all files": "Trwale usuń wszystkie pliki", + "Restore these files": "Przywróć te pliki", + "Permanently delete these files": "Trwale usuń te pliki", + "Calculate sub folder size": "Calculate sub folder size", + "Search": "Search", + "Minimize": "Minimize", + "Maximize": "Maximize", + "Exit (Ctrl + w)": "Exit (Ctrl + w)", + "Go Back (Alt + Left Arrow)": "Go Back (Alt + Left Arrow)", + "Go Forward (Alt + Right Arrow)": "Go Forward (Alt + Right Arrow)", + "Parent Directory (Alt + Up Arrow)": "Parent Directory (Alt + Up Arrow)", + "Reload (f5)": "Reload (f5)", + "Close Tab": "Close Tab" } diff --git a/src/Locales/pt-BR.json b/src/Locales/pt-BR.json index 438cfff1..fc943cea 100644 --- a/src/Locales/pt-BR.json +++ b/src/Locales/pt-BR.json @@ -1,114 +1,114 @@ { - "Favorites": "Favoritos", - "Desktop": "Área de Trabalho", - "Documents": "Documentos", - "Downloads": "Downloads", - "Pictures": "Imagens", - "Music": "Músicas", - "Videos": "Vídeos", - "Icon": "Ícones", - "Show hidden files": "Mostrar arquivos ocultos", - "Files": "Arquivos", - "Pendrives": "Pendrives", - "Home": "Página inicial", - "Recent": "Recentes", - "Trash": "Lixeira", - "Drives": "Unidades", - "free of": "livre de", - "Settings": "Configurações", - "Appearance": "Aparência", - "App Theme": "Tema do Aplicativo", - "Apply Shadow Effect": "Apply Shadow Effect", - "File Preview": "Visualização do arquivo", - "Default File Layout": "Layout de arquivo padrão", - "Show image as thumbnail": "Mostrar imagem em miniatura", - "Disabled": "Disabled", - "For small directory (recommended)": "For small directory (recommended)", - "Enable for all directory": "Enable for all directory", - "System Default": "Padrão do Sistema", - "Automatically play video file as thumbnail (May consume high amount of RAM)": "Reproduzir automaticamente arquivo de video como miniatura (Pode consumir muita RAM)", - "Extract exe file icon and make it as the thumbnail (Turning it on might crashes Xplorer)": "Extrair icone do arquivo exe e transformar em miniatura (Ligar isso pode travar o Xplorer)", - "Preview image on hover": "Visualizar imagem ao passar o mouse", - "Font Family": "Família de fontes", - "Font Size": "Font Size", - "Window Transparency": "Janela Transparente", - "Transparent Effect": "Efeito Transparente", - "Blur": "Blur", - "Acrylic": "Acrylic", - "Mica": "Mica", - "Vibrancy": "Vibrancy (MacOS)", - "None": "None", - "Transparent Sidebar": "Barra Lateral Transparente", - "Transparent Topbar": "Barra Superior Transparente", - "Transparent Workspace": "Espaço de Trabalho Transparente", - "Frame Style": "Estilo de frame", - "Default": "Padrão", - "Detect Drive Change": "Detectar Mudança de Unidade", - "Automatically change preview file with selected file": "Automatically change preview file with selected file", - "Single/Double Click to open a file": "Single/Double Click to open a file", - "Double click to open items under sidebar section": "Double click to open items under sidebar section", - "Double click to open items under home section": "Double click to open items under home section", - "Double click to open files/folders": "Double click to open files/folders", - "Preference": "Preferência", - "App Language": "Idioma do Aplicativo", - "Files and Folders": "Arquivos e Pastas", - "Hide hidden files": "Esconder arquivos ocultos", - "Hide system files": "Hide system files", - "List and sort directories alongside files": "Listar e ordenar diretórios juntamente com arquivos", - "On startup": "Na inicialização", - "New tab": "New tab", - "Continue previous session": "Continue previous session", - "Workspace": "Espaço de Trabalho", - "Show Info Bar": "Mostrar Barra de Informação", - "About": "Sobre", - "Layout Mode": "Modo de Layout", - "Grid View (Large)": "Visualização em Grade (Grande)", - "Grid View (Medium)": "Visualização em Grade (Médio)", - "Grid View (Small)": "Visualização em Grade (Pequeno)", - "Detail View": "Visualização Detalhada", - "Sort By": "Ordenar por", - "A-Z": "A-Z", - "Z-A": "Z-A", - "Last Modified": "Última Modificação", - "First Modified": "Primeira Modificação", - "Size": "Tamanho", - "Type": "Tipo", - "Reload": "Recarregar", - "Copy": "Copiar", - "Cut": "Cortar", - "Paste": "Colar", - "Undo Action": "Desfazer Ação", - "Redo Action": "Refazer Ação", - "Copy Location Path": "Copiar Caminho de localização", - "Clear Recent List": "Limpar Lista Recentes", - "Open": "Open", - "Open in Terminal": "Abrir no Terminal", - "Open in VSCode": "Abrir no VSCode", - "New": "Novo", - "File": "Arquivo", - "Folder": "Pasta", - "Unpin from Sidebar": "Desfixar da Barra Lateral", - "Pin to Sidebar": "Fixar na Barra Lateral", - "Compress to Zip": "Compress to Zip", - "Properties": "Propriedades", - "Rename": "Renomear", - "Delete": "Deletar", - "Restore": "Restaurar", - "Permanently Delete": "Deletar Permanentemente", - "Open in New Tab": "Abrir em Nova Aba", - "Preview": "Pré-visualizar", - "Restore all files": "Restaurar todos os arquivos", - "Permanently delete all files": "Deletar permanentemente todos os arquivos", - "Restore these files": "Restaurar esses arquivos", - "Permanently delete these files": "Deletar permanentemente esses arquivos", - "Calculate sub folder size": "Calculate sub folder size", - "Search": "Search", - "Minimize": "Minimize", - "Maximize": "Maximize", - "Exit (Ctrl + w)": "Exit (Ctrl + w)", - "Go Back (Alt + Left Arrow)": "Go Back (Alt + Left Arrow)", - "Go Forward (Alt + Right Arrow)": "Go Forward (Alt + Right Arrow)", - "Parent Directory (Alt + Up Arrow)": "Parent Directory (Alt + Up Arrow)", - "Reload (f5)": "Reload (f5)", - "Close Tab": "Close Tab" + "Favorites": "Favoritos", + "Desktop": "Área de Trabalho", + "Documents": "Documentos", + "Downloads": "Downloads", + "Pictures": "Imagens", + "Music": "Músicas", + "Videos": "Vídeos", + "Icon": "Ícones", + "Show hidden files": "Mostrar arquivos ocultos", + "Files": "Arquivos", + "Pendrives": "Pendrives", + "Home": "Página inicial", + "Recent": "Recentes", + "Trash": "Lixeira", + "Drives": "Unidades", + "free of": "livre de", + "Settings": "Configurações", + "Appearance": "Aparência", + "App Theme": "Tema do Aplicativo", + "Apply Shadow Effect": "Apply Shadow Effect", + "File Preview": "Visualização do arquivo", + "Default File Layout": "Layout de arquivo padrão", + "Show image as thumbnail": "Mostrar imagem em miniatura", + "Disabled": "Disabled", + "For small directory (recommended)": "For small directory (recommended)", + "Enable for all directory": "Enable for all directory", + "System Default": "Padrão do Sistema", + "Automatically play video file as thumbnail (May consume high amount of RAM)": "Reproduzir automaticamente arquivo de video como miniatura (Pode consumir muita RAM)", + "Extract exe file icon and make it as the thumbnail (Turning it on might crashes Xplorer)": "Extrair icone do arquivo exe e transformar em miniatura (Ligar isso pode travar o Xplorer)", + "Preview image on hover": "Visualizar imagem ao passar o mouse", + "Font Family": "Família de fontes", + "Font Size": "Font Size", + "Window Transparency": "Janela Transparente", + "Transparent Effect": "Efeito Transparente", + "Blur": "Blur", + "Acrylic": "Acrylic", + "Mica": "Mica", + "Vibrancy": "Vibrancy (MacOS)", + "None": "None", + "Transparent Sidebar": "Barra Lateral Transparente", + "Transparent Topbar": "Barra Superior Transparente", + "Transparent Workspace": "Espaço de Trabalho Transparente", + "Frame Style": "Estilo de frame", + "Default": "Padrão", + "Detect Drive Change": "Detectar Mudança de Unidade", + "Automatically change preview file with selected file": "Automatically change preview file with selected file", + "Single/Double Click to open a file": "Single/Double Click to open a file", + "Double click to open items under sidebar section": "Double click to open items under sidebar section", + "Double click to open items under home section": "Double click to open items under home section", + "Double click to open files/folders": "Double click to open files/folders", + "Preference": "Preferência", + "App Language": "Idioma do Aplicativo", + "Files and Folders": "Arquivos e Pastas", + "Hide hidden files": "Esconder arquivos ocultos", + "Hide system files": "Hide system files", + "List and sort directories alongside files": "Listar e ordenar diretórios juntamente com arquivos", + "On startup": "Na inicialização", + "New tab": "New tab", + "Continue previous session": "Continue previous session", + "Workspace": "Espaço de Trabalho", + "Show Info Bar": "Mostrar Barra de Informação", + "About": "Sobre", + "Layout Mode": "Modo de Layout", + "Grid View (Large)": "Visualização em Grade (Grande)", + "Grid View (Medium)": "Visualização em Grade (Médio)", + "Grid View (Small)": "Visualização em Grade (Pequeno)", + "Detail View": "Visualização Detalhada", + "Sort By": "Ordenar por", + "A-Z": "A-Z", + "Z-A": "Z-A", + "Last Modified": "Última Modificação", + "First Modified": "Primeira Modificação", + "Size": "Tamanho", + "Type": "Tipo", + "Reload": "Recarregar", + "Copy": "Copiar", + "Cut": "Cortar", + "Paste": "Colar", + "Undo Action": "Desfazer Ação", + "Redo Action": "Refazer Ação", + "Copy Location Path": "Copiar Caminho de localização", + "Clear Recent List": "Limpar Lista Recentes", + "Open": "Open", + "Open in Terminal": "Abrir no Terminal", + "Open in VSCode": "Abrir no VSCode", + "New": "Novo", + "File": "Arquivo", + "Folder": "Pasta", + "Unpin from Sidebar": "Desfixar da Barra Lateral", + "Pin to Sidebar": "Fixar na Barra Lateral", + "Compress to Zip": "Compress to Zip", + "Properties": "Propriedades", + "Rename": "Renomear", + "Delete": "Deletar", + "Restore": "Restaurar", + "Permanently Delete": "Deletar Permanentemente", + "Open in New Tab": "Abrir em Nova Aba", + "Preview": "Pré-visualizar", + "Restore all files": "Restaurar todos os arquivos", + "Permanently delete all files": "Deletar permanentemente todos os arquivos", + "Restore these files": "Restaurar esses arquivos", + "Permanently delete these files": "Deletar permanentemente esses arquivos", + "Calculate sub folder size": "Calculate sub folder size", + "Search": "Search", + "Minimize": "Minimize", + "Maximize": "Maximize", + "Exit (Ctrl + w)": "Exit (Ctrl + w)", + "Go Back (Alt + Left Arrow)": "Go Back (Alt + Left Arrow)", + "Go Forward (Alt + Right Arrow)": "Go Forward (Alt + Right Arrow)", + "Parent Directory (Alt + Up Arrow)": "Parent Directory (Alt + Up Arrow)", + "Reload (f5)": "Reload (f5)", + "Close Tab": "Close Tab" } diff --git a/src/Locales/ru-RU.json b/src/Locales/ru-RU.json index 3cd1d5a7..fb1e5e6e 100644 --- a/src/Locales/ru-RU.json +++ b/src/Locales/ru-RU.json @@ -1,114 +1,114 @@ { - "Favorites": "Избранное", - "Desktop": "Рабочий стол", - "Documents": "Документы", - "Downloads": "Загрузки", - "Pictures": "Изображения", - "Music": "Музыка", - "Videos": "Видео", - "Icon": "Иконка", - "Show hidden files": "Показать скрытые файлы", - "Files": "Файлы", - "Pendrives": "Флеш-накопители", - "Home": "Главная", - "Recent": "Недавнее", - "Trash": "Корзина", - "Drives": "Устройства и диски", - "free of": "свободно из", - "Settings": "Настройки", - "Appearance": "Внешний вид", - "App Theme": "Тема приложения", - "Apply Shadow Effect": "Apply Shadow Effect", - "File Preview": "Предпросмотр файла", - "Default File Layout": "Макет по умолчанию", - "Show image as thumbnail": "Показывать миниатюры изображений", - "Disabled": "Disabled", - "For small directory (recommended)": "For small directory (recommended)", - "Enable for all directory": "Enable for all directory", - "System Default": "По умолчанию", - "Automatically play video file as thumbnail (May consume high amount of RAM)": "Автоматически воспроизводить превью видеофайла (Может потреблять больше ОЗУ)", - "Extract exe file icon and make it as the thumbnail (Turning it on might crashes Xplorer)": "Сделать превью из извлеченной иконки .exe файла (может привести к вылету Xplorer)", - "Preview image on hover": "Предпросмотр картинки при наведении", - "Font Family": "Шрифт", - "Font Size": "Font Size", - "Window Transparency": "Прозрачность окна", - "Transparent Effect": "Эффект прозрачности", - "Blur": "Blur", - "Acrylic": "Acrylic", - "Mica": "Mica", - "Vibrancy": "Vibrancy (MacOS)", - "None": "None", - "Transparent Sidebar": "Прозрачная боковая панель", - "Transparent Topbar": "Прозрачная верхняя панель", - "Transparent Workspace": "Прозрачная область", - "Frame Style": "Стиль рамки", - "Default": "По умолчанию", - "Detect Drive Change": "Обнаружить изменения дисков", - "Automatically change preview file with selected file": "Automatically change preview file with selected file", - "Single/Double Click to open a file": "Single/Double Click to open a file", - "Double click to open items under sidebar section": "Double click to open items under sidebar section", - "Double click to open items under home section": "Double click to open items under home section", - "Double click to open files/folders": "Double click to open files/folders", - "Preference": "Предпочтение", - "App Language": "Язык приложения", - "Files and Folders": "Файлы и Папки", - "Hide hidden files": "Не отображать скрытые файлы", - "Hide system files": "Hide system files", - "List and sort directories alongside files": "Показывать и сортировать папки наравне с файлами", - "On startup": "При запуске", - "New tab": "New tab", - "Continue previous session": "Continue previous session", - "Workspace": "Рабочая область", - "Show Info Bar": "Показать панель информации", - "About": "О программе", - "Layout Mode": "Режим Разметки", - "Grid View (Large)": "Большие значки", - "Grid View (Medium)": "Обычные значки", - "Grid View (Small)": "Маленькие значки", - "Detail View": "Подробный вид", - "Sort By": "Сортировать по", - "A-Z": "A-Z", - "Z-A": "Z-A", - "Last Modified": "Последнее изменение", - "First Modified": "Первое изменение", - "Size": "Размер", - "Type": "Тип", - "Reload": "Обновить", - "Copy": "Копировать", - "Cut": "Вырезать", - "Paste": "Вставить", - "Undo Action": "Отменить действие", - "Redo Action": "Повторить действие", - "Copy Location Path": "Скопировать путь", - "Clear Recent List": "Очистить список недавних", - "Open": "Open", - "Open in Terminal": "Открыть в терминале", - "Open in VSCode": "Открыть в VS Code", - "New": "Создать", - "File": "Файл", - "Folder": "Папка", - "Unpin from Sidebar": "Открепить от боковой панели", - "Pin to Sidebar": "Закрепить в боковой панели", - "Compress to Zip": "Compress to Zip", - "Properties": "Свойства", - "Rename": "Переименовать", - "Delete": "Удалить", - "Restore": "Восстановить", - "Permanently Delete": "Удалить навсегда", - "Open in New Tab": "Открыть в новой вкладке", - "Preview": "Предпросмотр", - "Restore all files": "Восстановить все файлы", - "Permanently delete all files": "Удалить все файлы навсегда", - "Restore these files": "Восстановить эти файлы", - "Permanently delete these files": "Удалить эти файлы навсегда", - "Calculate sub folder size": "Calculate sub folder size", - "Search": "Search", - "Minimize": "Minimize", - "Maximize": "Maximize", - "Exit (Ctrl + w)": "Exit (Ctrl + w)", - "Go Back (Alt + Left Arrow)": "Go Back (Alt + Left Arrow)", - "Go Forward (Alt + Right Arrow)": "Go Forward (Alt + Right Arrow)", - "Parent Directory (Alt + Up Arrow)": "Parent Directory (Alt + Up Arrow)", - "Reload (f5)": "Reload (f5)", - "Close Tab": "Close Tab" + "Favorites": "Избранное", + "Desktop": "Рабочий стол", + "Documents": "Документы", + "Downloads": "Загрузки", + "Pictures": "Изображения", + "Music": "Музыка", + "Videos": "Видео", + "Icon": "Иконка", + "Show hidden files": "Показать скрытые файлы", + "Files": "Файлы", + "Pendrives": "Флеш-накопители", + "Home": "Главная", + "Recent": "Недавнее", + "Trash": "Корзина", + "Drives": "Устройства и диски", + "free of": "свободно из", + "Settings": "Настройки", + "Appearance": "Внешний вид", + "App Theme": "Тема приложения", + "Apply Shadow Effect": "Apply Shadow Effect", + "File Preview": "Предпросмотр файла", + "Default File Layout": "Макет по умолчанию", + "Show image as thumbnail": "Показывать миниатюры изображений", + "Disabled": "Disabled", + "For small directory (recommended)": "For small directory (recommended)", + "Enable for all directory": "Enable for all directory", + "System Default": "По умолчанию", + "Automatically play video file as thumbnail (May consume high amount of RAM)": "Автоматически воспроизводить превью видеофайла (Может потреблять больше ОЗУ)", + "Extract exe file icon and make it as the thumbnail (Turning it on might crashes Xplorer)": "Сделать превью из извлеченной иконки .exe файла (может привести к вылету Xplorer)", + "Preview image on hover": "Предпросмотр картинки при наведении", + "Font Family": "Шрифт", + "Font Size": "Font Size", + "Window Transparency": "Прозрачность окна", + "Transparent Effect": "Эффект прозрачности", + "Blur": "Blur", + "Acrylic": "Acrylic", + "Mica": "Mica", + "Vibrancy": "Vibrancy (MacOS)", + "None": "None", + "Transparent Sidebar": "Прозрачная боковая панель", + "Transparent Topbar": "Прозрачная верхняя панель", + "Transparent Workspace": "Прозрачная область", + "Frame Style": "Стиль рамки", + "Default": "По умолчанию", + "Detect Drive Change": "Обнаружить изменения дисков", + "Automatically change preview file with selected file": "Automatically change preview file with selected file", + "Single/Double Click to open a file": "Single/Double Click to open a file", + "Double click to open items under sidebar section": "Double click to open items under sidebar section", + "Double click to open items under home section": "Double click to open items under home section", + "Double click to open files/folders": "Double click to open files/folders", + "Preference": "Предпочтение", + "App Language": "Язык приложения", + "Files and Folders": "Файлы и Папки", + "Hide hidden files": "Не отображать скрытые файлы", + "Hide system files": "Hide system files", + "List and sort directories alongside files": "Показывать и сортировать папки наравне с файлами", + "On startup": "При запуске", + "New tab": "New tab", + "Continue previous session": "Continue previous session", + "Workspace": "Рабочая область", + "Show Info Bar": "Показать панель информации", + "About": "О программе", + "Layout Mode": "Режим Разметки", + "Grid View (Large)": "Большие значки", + "Grid View (Medium)": "Обычные значки", + "Grid View (Small)": "Маленькие значки", + "Detail View": "Подробный вид", + "Sort By": "Сортировать по", + "A-Z": "A-Z", + "Z-A": "Z-A", + "Last Modified": "Последнее изменение", + "First Modified": "Первое изменение", + "Size": "Размер", + "Type": "Тип", + "Reload": "Обновить", + "Copy": "Копировать", + "Cut": "Вырезать", + "Paste": "Вставить", + "Undo Action": "Отменить действие", + "Redo Action": "Повторить действие", + "Copy Location Path": "Скопировать путь", + "Clear Recent List": "Очистить список недавних", + "Open": "Open", + "Open in Terminal": "Открыть в терминале", + "Open in VSCode": "Открыть в VS Code", + "New": "Создать", + "File": "Файл", + "Folder": "Папка", + "Unpin from Sidebar": "Открепить от боковой панели", + "Pin to Sidebar": "Закрепить в боковой панели", + "Compress to Zip": "Compress to Zip", + "Properties": "Свойства", + "Rename": "Переименовать", + "Delete": "Удалить", + "Restore": "Восстановить", + "Permanently Delete": "Удалить навсегда", + "Open in New Tab": "Открыть в новой вкладке", + "Preview": "Предпросмотр", + "Restore all files": "Восстановить все файлы", + "Permanently delete all files": "Удалить все файлы навсегда", + "Restore these files": "Восстановить эти файлы", + "Permanently delete these files": "Удалить эти файлы навсегда", + "Calculate sub folder size": "Calculate sub folder size", + "Search": "Search", + "Minimize": "Minimize", + "Maximize": "Maximize", + "Exit (Ctrl + w)": "Exit (Ctrl + w)", + "Go Back (Alt + Left Arrow)": "Go Back (Alt + Left Arrow)", + "Go Forward (Alt + Right Arrow)": "Go Forward (Alt + Right Arrow)", + "Parent Directory (Alt + Up Arrow)": "Parent Directory (Alt + Up Arrow)", + "Reload (f5)": "Reload (f5)", + "Close Tab": "Close Tab" } diff --git a/src/Locales/tr-TR.json b/src/Locales/tr-TR.json index 20a6a2ee..b64b151d 100644 --- a/src/Locales/tr-TR.json +++ b/src/Locales/tr-TR.json @@ -1,114 +1,114 @@ { - "Favorites": "Sık Kullanılanlar", - "Desktop": "Masaüstü", - "Documents": "Belgeler", - "Downloads": "İndirilenler", - "Pictures": "Resimler", - "Music": "Müzik", - "Videos": "Videolar", - "Icon": "İkon", - "Show hidden files": "Gizli dosyaları göster", - "Files": "Dosyalar", - "Pendrives": "Flash Diskler", - "Home": "Giriş", - "Recent": "Son Kullanılanlar", - "Trash": "Çöp", - "Drives": "Sürücüler", - "free of": "serbest", - "Settings": "Ayarlar", - "Appearance": "Görünüm", - "App Theme": "Uygulama Teması", - "Apply Shadow Effect": "Gölge Efektini Uygula", - "File Preview": "Dosya Önizleme", - "Default File Layout": "Varsayılan Dosya Düzeni", - "Show image as thumbnail": "Görüntüyü küçük resim olarak göster", - "Disabled": "Devre dışı", - "For small directory (recommended)": "Küçük dizinler için (önerilir)", - "Enable for all directory": "Tüm dizinler için etkinleştir", - "System Default": "Sistem Varsayılanı", - "Automatically play video file as thumbnail (May consume high amount of RAM)": "Video dosyasını otomatik olarak küçük boyutta oynatır (Yüksek miktarda RAM tüketebilir)", - "Extract exe file icon and make it as the thumbnail (Turning it on might crashes Xplorer)": "Exe dosyası simgesini çıkarın ve küçük resim haline getirin (Xplorer'ın çökmesine neden olabilir)", - "Preview image on hover": "Üzerine geldiğinde önizle", - "Font Family": "Yazı Tipi Ailesi", - "Font Size": "Font Boyutu", - "Window Transparency": "Pencere Saydamlığı", - "Transparent Effect": "Saydamlık Efektleri", - "Blur": "Blur", - "Acrylic": "Acrylic", - "Mica": "Mica", - "Vibrancy": "Vibrancy (MacOS)", - "None": "None", - "Transparent Sidebar": "Saydam Hızlı Erişim", - "Transparent Topbar": "Saydam Üst Çubuk", - "Transparent Workspace": "Saydam Çalışma Alanı", - "Frame Style": "Çerçeve Stili", - "Default": "Varsayılan", - "Detect Drive Change": "Sürücü Değişikliğini Algıla", - "Automatically change preview file with selected file": "Önizleme dosyasını seçilen dosya ile otomatik olarak değiştir", - "Single/Double Click to open a file": "Bir dosyayı açmak için Tek/Çift Tıklama", - "Double click to open items under sidebar section": "Kenar çubuğu bölümündeki öğeleri açmak için çift tıklayın", - "Double click to open items under home section": "Ana bölüm altındaki öğeleri açmak için çift tıklayın", - "Double click to open files/folders": "Dosyaları/Klasörleri açmak için çift tıklayın", - "Preference": "Tercih", - "App Language": "Uygulama Dili", - "Files and Folders": "Dosyalar ve Klasörler", - "Hide hidden files": "Gizli dosyaları gösterme", - "Hide system files": "Sistem dosyalarını gizle", - "List and sort directories alongside files": "Dizinleri dosyalarla listeleyin ve sıralayın", - "On startup": "Başlangıçta Başlat", - "New tab": "Yeni Sekme", - "Continue previous session": "Önceki oturuma devam et", - "Workspace": "Çalışma Alanı", - "Show Info Bar": "Bilgi Çubuğunu Göster", - "About": "Hakkında", - "Layout Mode": "Düzen Modu", - "Grid View (Large)": "Tablo Görünümü (Büyük)", - "Grid View (Medium)": "Tablo Görünümü (Orta)", - "Grid View (Small)": "Tablo Görünümü (Küçük)", - "Detail View": "Ayrıntılı Görünüm", - "Sort By": "Sırala", - "A-Z": "A-Z", - "Z-A": "Z-A", - "Last Modified": "Son Değiştirme", - "First Modified": "İlk Değiştirme", - "Size": "Boyut", - "Type": "Tür", - "Reload": "Yeniden Yükle", - "Copy": "Kopyala", - "Cut": "Kes", - "Paste": "Yapıştır", - "Undo Action": "Geri Al", - "Redo Action": "Yinele", - "Copy Location Path": "Adresi Kopyala", - "Clear Recent List": "Son Kullanılanlar Listesini Temizle", - "Open": "Open", - "Open in Terminal": "Terminal'de Aç", - "Open in VSCode": "VSCode'da Aç", - "New": "Yeni", - "File": "Dosya", - "Folder": "Klasör", - "Unpin from Sidebar": "Hızlı Erişimden Kaldır", - "Pin to Sidebar": "Hızlı Erişime Sabitle", - "Compress to Zip": "Zip Olarak Sıkıştır", - "Properties": "Özellikler", - "Rename": "Yeniden Adlandır", - "Delete": "Sil", - "Restore": "Geri Yükle", - "Permanently Delete": "Kalıcı Olarak Sil", - "Open in New Tab": "Yeni Sekmede Aç", - "Preview": "Önizleme", - "Restore all files": "Tüm dosyaları geri yükle", - "Permanently delete all files": "Tüm dosyaları kalıcı olarak sil", - "Restore these files": "Dosyaları geri yükle", - "Permanently delete these files": "Dosyaları kalıcı olarak silin", - "Calculate sub folder size": "Alt klasör boyutunu hesapla", - "Search": "Arama", - "Minimize": "Minimize", - "Maximize": "Maximize", - "Exit (Ctrl + w)": "Çıkış (Ctrl + w)", - "Go Back (Alt + Left Arrow)": "Geri (Alt + Left Arrow)", - "Go Forward (Alt + Right Arrow)": "İleri (Alt + Right Arrow)", - "Parent Directory (Alt + Up Arrow)": "İçeren Klasör (Alt + Up Arrow)", - "Reload (f5)": "Yeniden Yükle (f5)", - "Close Tab": "Sekmeyi Kapat" + "Favorites": "Sık Kullanılanlar", + "Desktop": "Masaüstü", + "Documents": "Belgeler", + "Downloads": "İndirilenler", + "Pictures": "Resimler", + "Music": "Müzik", + "Videos": "Videolar", + "Icon": "İkon", + "Show hidden files": "Gizli dosyaları göster", + "Files": "Dosyalar", + "Pendrives": "Flash Diskler", + "Home": "Giriş", + "Recent": "Son Kullanılanlar", + "Trash": "Çöp", + "Drives": "Sürücüler", + "free of": "serbest", + "Settings": "Ayarlar", + "Appearance": "Görünüm", + "App Theme": "Uygulama Teması", + "Apply Shadow Effect": "Gölge Efektini Uygula", + "File Preview": "Dosya Önizleme", + "Default File Layout": "Varsayılan Dosya Düzeni", + "Show image as thumbnail": "Görüntüyü küçük resim olarak göster", + "Disabled": "Devre dışı", + "For small directory (recommended)": "Küçük dizinler için (önerilir)", + "Enable for all directory": "Tüm dizinler için etkinleştir", + "System Default": "Sistem Varsayılanı", + "Automatically play video file as thumbnail (May consume high amount of RAM)": "Video dosyasını otomatik olarak küçük boyutta oynatır (Yüksek miktarda RAM tüketebilir)", + "Extract exe file icon and make it as the thumbnail (Turning it on might crashes Xplorer)": "Exe dosyası simgesini çıkarın ve küçük resim haline getirin (Xplorer'ın çökmesine neden olabilir)", + "Preview image on hover": "Üzerine geldiğinde önizle", + "Font Family": "Yazı Tipi Ailesi", + "Font Size": "Font Boyutu", + "Window Transparency": "Pencere Saydamlığı", + "Transparent Effect": "Saydamlık Efektleri", + "Blur": "Blur", + "Acrylic": "Acrylic", + "Mica": "Mica", + "Vibrancy": "Vibrancy (MacOS)", + "None": "None", + "Transparent Sidebar": "Saydam Hızlı Erişim", + "Transparent Topbar": "Saydam Üst Çubuk", + "Transparent Workspace": "Saydam Çalışma Alanı", + "Frame Style": "Çerçeve Stili", + "Default": "Varsayılan", + "Detect Drive Change": "Sürücü Değişikliğini Algıla", + "Automatically change preview file with selected file": "Önizleme dosyasını seçilen dosya ile otomatik olarak değiştir", + "Single/Double Click to open a file": "Bir dosyayı açmak için Tek/Çift Tıklama", + "Double click to open items under sidebar section": "Kenar çubuğu bölümündeki öğeleri açmak için çift tıklayın", + "Double click to open items under home section": "Ana bölüm altındaki öğeleri açmak için çift tıklayın", + "Double click to open files/folders": "Dosyaları/Klasörleri açmak için çift tıklayın", + "Preference": "Tercih", + "App Language": "Uygulama Dili", + "Files and Folders": "Dosyalar ve Klasörler", + "Hide hidden files": "Gizli dosyaları gösterme", + "Hide system files": "Sistem dosyalarını gizle", + "List and sort directories alongside files": "Dizinleri dosyalarla listeleyin ve sıralayın", + "On startup": "Başlangıçta Başlat", + "New tab": "Yeni Sekme", + "Continue previous session": "Önceki oturuma devam et", + "Workspace": "Çalışma Alanı", + "Show Info Bar": "Bilgi Çubuğunu Göster", + "About": "Hakkında", + "Layout Mode": "Düzen Modu", + "Grid View (Large)": "Tablo Görünümü (Büyük)", + "Grid View (Medium)": "Tablo Görünümü (Orta)", + "Grid View (Small)": "Tablo Görünümü (Küçük)", + "Detail View": "Ayrıntılı Görünüm", + "Sort By": "Sırala", + "A-Z": "A-Z", + "Z-A": "Z-A", + "Last Modified": "Son Değiştirme", + "First Modified": "İlk Değiştirme", + "Size": "Boyut", + "Type": "Tür", + "Reload": "Yeniden Yükle", + "Copy": "Kopyala", + "Cut": "Kes", + "Paste": "Yapıştır", + "Undo Action": "Geri Al", + "Redo Action": "Yinele", + "Copy Location Path": "Adresi Kopyala", + "Clear Recent List": "Son Kullanılanlar Listesini Temizle", + "Open": "Open", + "Open in Terminal": "Terminal'de Aç", + "Open in VSCode": "VSCode'da Aç", + "New": "Yeni", + "File": "Dosya", + "Folder": "Klasör", + "Unpin from Sidebar": "Hızlı Erişimden Kaldır", + "Pin to Sidebar": "Hızlı Erişime Sabitle", + "Compress to Zip": "Zip Olarak Sıkıştır", + "Properties": "Özellikler", + "Rename": "Yeniden Adlandır", + "Delete": "Sil", + "Restore": "Geri Yükle", + "Permanently Delete": "Kalıcı Olarak Sil", + "Open in New Tab": "Yeni Sekmede Aç", + "Preview": "Önizleme", + "Restore all files": "Tüm dosyaları geri yükle", + "Permanently delete all files": "Tüm dosyaları kalıcı olarak sil", + "Restore these files": "Dosyaları geri yükle", + "Permanently delete these files": "Dosyaları kalıcı olarak silin", + "Calculate sub folder size": "Alt klasör boyutunu hesapla", + "Search": "Arama", + "Minimize": "Minimize", + "Maximize": "Maximize", + "Exit (Ctrl + w)": "Çıkış (Ctrl + w)", + "Go Back (Alt + Left Arrow)": "Geri (Alt + Left Arrow)", + "Go Forward (Alt + Right Arrow)": "İleri (Alt + Right Arrow)", + "Parent Directory (Alt + Up Arrow)": "İçeren Klasör (Alt + Up Arrow)", + "Reload (f5)": "Yeniden Yükle (f5)", + "Close Tab": "Sekmeyi Kapat" } diff --git a/src/Locales/uk-UA.json b/src/Locales/uk-UA.json index 6d820904..f7d681d3 100644 --- a/src/Locales/uk-UA.json +++ b/src/Locales/uk-UA.json @@ -1,114 +1,114 @@ { - "Favorites": "Вибране", - "Desktop": "Робочий стіл", - "Documents": "Документи", - "Downloads": "Завантаження", - "Pictures": "Картинки", - "Music": "Музика", - "Videos": "Відео", - "Icon": "Значок", - "Show hidden files": "Показати приховані файли", - "Files": "Файли", - "Pendrives": "Флешки", - "Home": "Домашня директорія", - "Recent": "Останні", - "Trash": "Кошик", - "Drives": "Кошик", - "free of": "вільно з", - "Settings": "Налаштування", - "Appearance": "Зовнішній вигляд", - "App Theme": "Тема програми", - "Apply Shadow Effect": "Apply Shadow Effect", - "File Preview": "File Preview", - "Default File Layout": "Default File Layout", - "Show image as thumbnail": "Show image as thumbnail", - "Disabled": "Disabled", - "For small directory (recommended)": "For small directory (recommended)", - "Enable for all directory": "Enable for all directory", - "System Default": "За замовчуванням", - "Automatically play video file as thumbnail (May consume high amount of RAM)": "Automatically play video file as thumbnail (May consume high amount of RAM)", - "Extract exe file icon and make it as the thumbnail (Turning it on might crashes Xplorer)": "Extract exe file icon and make it as the thumbnail (Turning it on might crashes Xplorer)", - "Preview image on hover": "Preview image on hover", - "Font Family": "Font Family", - "Font Size": "Font Size", - "Window Transparency": "Window Transparency", - "Transparent Effect": "Transparent Effect", - "Blur": "Blur", - "Acrylic": "Acrylic", - "Mica": "Mica", - "Vibrancy": "Vibrancy (MacOS)", - "None": "None", - "Transparent Sidebar": "Transparent Sidebar", - "Transparent Topbar": "Transparent Topbar", - "Transparent Workspace": "Transparent Workspace", - "Frame Style": "Frame Style", - "Default": "Default", - "Detect Drive Change": "Detect Drive Change", - "Automatically change preview file with selected file": "Automatically change preview file with selected file", - "Single/Double Click to open a file": "Single/Double Click to open a file", - "Double click to open items under sidebar section": "Double click to open items under sidebar section", - "Double click to open items under home section": "Double click to open items under home section", - "Double click to open files/folders": "Double click to open files/folders", - "Preference": "Preference", - "App Language": "Мова програми", - "Files and Folders": "Файли та папки", - "Hide hidden files": "Сховати приховані файли", - "Hide system files": "Hide system files", - "List and sort directories alongside files": "Список та сортування каталогів поряд з файлами", - "On startup": "On startup", - "New tab": "New tab", - "Continue previous session": "Continue previous session", - "Workspace": "Workspace", - "Show Info Bar": "Show Info Bar", - "About": "About", - "Layout Mode": "Layout Mode", - "Grid View (Large)": "Grid View (Large)", - "Grid View (Medium)": "Grid View (Medium)", - "Grid View (Small)": "Grid View (Small)", - "Detail View": "Detail View", - "Sort By": "Sort By", - "A-Z": "A-Z", - "Z-A": "Z-A", - "Last Modified": "Last Modified", - "First Modified": "First Modified", - "Size": "Size", - "Type": "Type", - "Reload": "Reload", - "Copy": "Copy", - "Cut": "Cut", - "Paste": "Paste", - "Undo Action": "Undo Action", - "Redo Action": "Redo Action", - "Copy Location Path": "Copy Location Path", - "Clear Recent List": "Clear Recent List", - "Open": "Open", - "Open in Terminal": "Open in Terminal", - "Open in VSCode": "Open in VSCode", - "New": "New", - "File": "File", - "Folder": "Folder", - "Unpin from Sidebar": "Unpin from Sidebar", - "Pin to Sidebar": "Pin to Sidebar", - "Compress to Zip": "Compress to Zip", - "Properties": "Properties", - "Rename": "Rename", - "Delete": "Delete", - "Restore": "Restore", - "Permanently Delete": "Permanently Delete", - "Open in New Tab": "Open in New Tab", - "Preview": "Preview", - "Restore all files": "Restore all files", - "Permanently delete all files": "Permanently delete all files", - "Restore these files": "Restore these files", - "Permanently delete these files": "Permanently delete these files", - "Calculate sub folder size": "Calculate sub folder size", - "Search": "Search", - "Minimize": "Minimize", - "Maximize": "Maximize", - "Exit (Ctrl + w)": "Exit (Ctrl + w)", - "Go Back (Alt + Left Arrow)": "Go Back (Alt + Left Arrow)", - "Go Forward (Alt + Right Arrow)": "Go Forward (Alt + Right Arrow)", - "Parent Directory (Alt + Up Arrow)": "Parent Directory (Alt + Up Arrow)", - "Reload (f5)": "Reload (f5)", - "Close Tab": "Close Tab" + "Favorites": "Вибране", + "Desktop": "Робочий стіл", + "Documents": "Документи", + "Downloads": "Завантаження", + "Pictures": "Картинки", + "Music": "Музика", + "Videos": "Відео", + "Icon": "Значок", + "Show hidden files": "Показати приховані файли", + "Files": "Файли", + "Pendrives": "Флешки", + "Home": "Домашня директорія", + "Recent": "Останні", + "Trash": "Кошик", + "Drives": "Кошик", + "free of": "вільно з", + "Settings": "Налаштування", + "Appearance": "Зовнішній вигляд", + "App Theme": "Тема програми", + "Apply Shadow Effect": "Apply Shadow Effect", + "File Preview": "File Preview", + "Default File Layout": "Default File Layout", + "Show image as thumbnail": "Show image as thumbnail", + "Disabled": "Disabled", + "For small directory (recommended)": "For small directory (recommended)", + "Enable for all directory": "Enable for all directory", + "System Default": "За замовчуванням", + "Automatically play video file as thumbnail (May consume high amount of RAM)": "Automatically play video file as thumbnail (May consume high amount of RAM)", + "Extract exe file icon and make it as the thumbnail (Turning it on might crashes Xplorer)": "Extract exe file icon and make it as the thumbnail (Turning it on might crashes Xplorer)", + "Preview image on hover": "Preview image on hover", + "Font Family": "Font Family", + "Font Size": "Font Size", + "Window Transparency": "Window Transparency", + "Transparent Effect": "Transparent Effect", + "Blur": "Blur", + "Acrylic": "Acrylic", + "Mica": "Mica", + "Vibrancy": "Vibrancy (MacOS)", + "None": "None", + "Transparent Sidebar": "Transparent Sidebar", + "Transparent Topbar": "Transparent Topbar", + "Transparent Workspace": "Transparent Workspace", + "Frame Style": "Frame Style", + "Default": "Default", + "Detect Drive Change": "Detect Drive Change", + "Automatically change preview file with selected file": "Automatically change preview file with selected file", + "Single/Double Click to open a file": "Single/Double Click to open a file", + "Double click to open items under sidebar section": "Double click to open items under sidebar section", + "Double click to open items under home section": "Double click to open items under home section", + "Double click to open files/folders": "Double click to open files/folders", + "Preference": "Preference", + "App Language": "Мова програми", + "Files and Folders": "Файли та папки", + "Hide hidden files": "Сховати приховані файли", + "Hide system files": "Hide system files", + "List and sort directories alongside files": "Список та сортування каталогів поряд з файлами", + "On startup": "On startup", + "New tab": "New tab", + "Continue previous session": "Continue previous session", + "Workspace": "Workspace", + "Show Info Bar": "Show Info Bar", + "About": "About", + "Layout Mode": "Layout Mode", + "Grid View (Large)": "Grid View (Large)", + "Grid View (Medium)": "Grid View (Medium)", + "Grid View (Small)": "Grid View (Small)", + "Detail View": "Detail View", + "Sort By": "Sort By", + "A-Z": "A-Z", + "Z-A": "Z-A", + "Last Modified": "Last Modified", + "First Modified": "First Modified", + "Size": "Size", + "Type": "Type", + "Reload": "Reload", + "Copy": "Copy", + "Cut": "Cut", + "Paste": "Paste", + "Undo Action": "Undo Action", + "Redo Action": "Redo Action", + "Copy Location Path": "Copy Location Path", + "Clear Recent List": "Clear Recent List", + "Open": "Open", + "Open in Terminal": "Open in Terminal", + "Open in VSCode": "Open in VSCode", + "New": "New", + "File": "File", + "Folder": "Folder", + "Unpin from Sidebar": "Unpin from Sidebar", + "Pin to Sidebar": "Pin to Sidebar", + "Compress to Zip": "Compress to Zip", + "Properties": "Properties", + "Rename": "Rename", + "Delete": "Delete", + "Restore": "Restore", + "Permanently Delete": "Permanently Delete", + "Open in New Tab": "Open in New Tab", + "Preview": "Preview", + "Restore all files": "Restore all files", + "Permanently delete all files": "Permanently delete all files", + "Restore these files": "Restore these files", + "Permanently delete these files": "Permanently delete these files", + "Calculate sub folder size": "Calculate sub folder size", + "Search": "Search", + "Minimize": "Minimize", + "Maximize": "Maximize", + "Exit (Ctrl + w)": "Exit (Ctrl + w)", + "Go Back (Alt + Left Arrow)": "Go Back (Alt + Left Arrow)", + "Go Forward (Alt + Right Arrow)": "Go Forward (Alt + Right Arrow)", + "Parent Directory (Alt + Up Arrow)": "Parent Directory (Alt + Up Arrow)", + "Reload (f5)": "Reload (f5)", + "Close Tab": "Close Tab" } diff --git a/src/Locales/zh-CN.json b/src/Locales/zh-CN.json index 31fccc18..cfca31a8 100644 --- a/src/Locales/zh-CN.json +++ b/src/Locales/zh-CN.json @@ -1,114 +1,114 @@ { - "Favorites": "收藏", - "Desktop": "桌面", - "Documents": "文档", - "Downloads": "下载", - "Pictures": "图片", - "Music": "音乐", - "Videos": "视频", - "Icon": "图标", - "Show hidden files": "显示隐藏文件", - "Files": "文件", - "Pendrives": "移动存储", - "Home": "主页", - "Recent": "最近", - "Trash": "垃圾", - "Drives": "硬盘", - "free of": "可用,共", - "Settings": "设置", - "Appearance": "外观", - "App Theme": "主题", - "Apply Shadow Effect": "Apply Shadow Effect", - "File Preview": "文件预览", - "Default File Layout": "默认布局", - "Show image as thumbnail": "以缩略图形式显示图像", - "Disabled": "Disabled", - "For small directory (recommended)": "For small directory (recommended)", - "Enable for all directory": "Enable for all directory", - "System Default": "系统默认", - "Automatically play video file as thumbnail (May consume high amount of RAM)": "图标自动展示视频 (可能占用较大内存)", - "Extract exe file icon and make it as the thumbnail (Turning it on might crashes Xplorer)": "解压缩文件图标并将其作为缩略图(打开它可能将把 Xplorer 崩溃)", - "Preview image on hover": "悬停时预览图像", - "Font Family": "字体系列", - "Font Size": "Font Size", - "Window Transparency": "窗口透明", - "Transparent Effect": "透明特效", - "Blur": "Blur", - "Acrylic": "Acrylic", - "Mica": "Mica", - "Vibrancy": "Vibrancy (MacOS)", - "None": "None", - "Transparent Sidebar": "透明侧边栏", - "Transparent Topbar": "透明顶栏", - "Transparent Workspace": "透明工作区", - "Frame Style": "框架样式", - "Default": "默认", - "Detect Drive Change": "检测驱动器更改", - "Automatically change preview file with selected file": "Automatically change preview file with selected file", - "Single/Double Click to open a file": "Single/Double Click to open a file", - "Double click to open items under sidebar section": "Double click to open items under sidebar section", - "Double click to open items under home section": "Double click to open items under home section", - "Double click to open files/folders": "Double click to open files/folders", - "Preference": "设置", - "App Language": "语言", - "Files and Folders": "文件和文件夹", - "Hide hidden files": "隐藏文件", - "Hide system files": "Hide system files", - "List and sort directories alongside files": "展开文件同时排序", - "On startup": "启动时", - "New tab": "New tab", - "Continue previous session": "Continue previous session", - "Workspace": "工作区", - "Show Info Bar": "显示信息栏", - "About": "关于我们", - "Layout Mode": "布局模式", - "Grid View (Large)": "以大缩略图显示", - "Grid View (Medium)": "以正常缩略图显示", - "Grid View (Small)": "以小缩略图显示", - "Detail View": "展示详情", - "Sort By": "排序方式", - "A-Z": "A-Z", - "Z-A": "Z-A", - "Last Modified": "最后修改", - "First Modified": "最先修改", - "Size": "大小", - "Type": "类型", - "Reload": "刷新", - "Copy": "复制", - "Cut": "剪切", - "Paste": "粘贴", - "Undo Action": "撤销", - "Redo Action": "重做", - "Copy Location Path": "复制文件路径", - "Clear Recent List": "清除最近使用列表", - "Open": "Open", - "Open in Terminal": "在控制台打开", - "Open in VSCode": "在VSCode中打开", - "New": "新建", - "File": "文件", - "Folder": "文件夹", - "Unpin from Sidebar": "从快速访问栏取消", - "Pin to Sidebar": "固定到快速访问栏", - "Compress to Zip": "Compress to Zip", - "Properties": "属性", - "Rename": "重命名", - "Delete": "删除", - "Restore": "保存", - "Permanently Delete": "永久删除", - "Open in New Tab": "在新的标签页打开", - "Preview": "预览", - "Restore all files": "还原所有文件", - "Permanently delete all files": "永久删除所有文件", - "Restore these files": "还原这些文件", - "Permanently delete these files": "永久删除所有文件", - "Calculate sub folder size": "Calculate sub folder size", - "Search": "Search", - "Minimize": "Minimize", - "Maximize": "Maximize", - "Exit (Ctrl + w)": "Exit (Ctrl + w)", - "Go Back (Alt + Left Arrow)": "Go Back (Alt + Left Arrow)", - "Go Forward (Alt + Right Arrow)": "Go Forward (Alt + Right Arrow)", - "Parent Directory (Alt + Up Arrow)": "Parent Directory (Alt + Up Arrow)", - "Reload (f5)": "Reload (f5)", - "Close Tab": "Close Tab" + "Favorites": "收藏", + "Desktop": "桌面", + "Documents": "文档", + "Downloads": "下载", + "Pictures": "图片", + "Music": "音乐", + "Videos": "视频", + "Icon": "图标", + "Show hidden files": "显示隐藏文件", + "Files": "文件", + "Pendrives": "移动存储", + "Home": "主页", + "Recent": "最近", + "Trash": "垃圾", + "Drives": "硬盘", + "free of": "可用,共", + "Settings": "设置", + "Appearance": "外观", + "App Theme": "主题", + "Apply Shadow Effect": "Apply Shadow Effect", + "File Preview": "文件预览", + "Default File Layout": "默认布局", + "Show image as thumbnail": "以缩略图形式显示图像", + "Disabled": "Disabled", + "For small directory (recommended)": "For small directory (recommended)", + "Enable for all directory": "Enable for all directory", + "System Default": "系统默认", + "Automatically play video file as thumbnail (May consume high amount of RAM)": "图标自动展示视频 (可能占用较大内存)", + "Extract exe file icon and make it as the thumbnail (Turning it on might crashes Xplorer)": "解压缩文件图标并将其作为缩略图(打开它可能将把 Xplorer 崩溃)", + "Preview image on hover": "悬停时预览图像", + "Font Family": "字体系列", + "Font Size": "Font Size", + "Window Transparency": "窗口透明", + "Transparent Effect": "透明特效", + "Blur": "Blur", + "Acrylic": "Acrylic", + "Mica": "Mica", + "Vibrancy": "Vibrancy (MacOS)", + "None": "None", + "Transparent Sidebar": "透明侧边栏", + "Transparent Topbar": "透明顶栏", + "Transparent Workspace": "透明工作区", + "Frame Style": "框架样式", + "Default": "默认", + "Detect Drive Change": "检测驱动器更改", + "Automatically change preview file with selected file": "Automatically change preview file with selected file", + "Single/Double Click to open a file": "Single/Double Click to open a file", + "Double click to open items under sidebar section": "Double click to open items under sidebar section", + "Double click to open items under home section": "Double click to open items under home section", + "Double click to open files/folders": "Double click to open files/folders", + "Preference": "设置", + "App Language": "语言", + "Files and Folders": "文件和文件夹", + "Hide hidden files": "隐藏文件", + "Hide system files": "Hide system files", + "List and sort directories alongside files": "展开文件同时排序", + "On startup": "启动时", + "New tab": "New tab", + "Continue previous session": "Continue previous session", + "Workspace": "工作区", + "Show Info Bar": "显示信息栏", + "About": "关于我们", + "Layout Mode": "布局模式", + "Grid View (Large)": "以大缩略图显示", + "Grid View (Medium)": "以正常缩略图显示", + "Grid View (Small)": "以小缩略图显示", + "Detail View": "展示详情", + "Sort By": "排序方式", + "A-Z": "A-Z", + "Z-A": "Z-A", + "Last Modified": "最后修改", + "First Modified": "最先修改", + "Size": "大小", + "Type": "类型", + "Reload": "刷新", + "Copy": "复制", + "Cut": "剪切", + "Paste": "粘贴", + "Undo Action": "撤销", + "Redo Action": "重做", + "Copy Location Path": "复制文件路径", + "Clear Recent List": "清除最近使用列表", + "Open": "Open", + "Open in Terminal": "在控制台打开", + "Open in VSCode": "在VSCode中打开", + "New": "新建", + "File": "文件", + "Folder": "文件夹", + "Unpin from Sidebar": "从快速访问栏取消", + "Pin to Sidebar": "固定到快速访问栏", + "Compress to Zip": "Compress to Zip", + "Properties": "属性", + "Rename": "重命名", + "Delete": "删除", + "Restore": "保存", + "Permanently Delete": "永久删除", + "Open in New Tab": "在新的标签页打开", + "Preview": "预览", + "Restore all files": "还原所有文件", + "Permanently delete all files": "永久删除所有文件", + "Restore these files": "还原这些文件", + "Permanently delete these files": "永久删除所有文件", + "Calculate sub folder size": "Calculate sub folder size", + "Search": "Search", + "Minimize": "Minimize", + "Maximize": "Maximize", + "Exit (Ctrl + w)": "Exit (Ctrl + w)", + "Go Back (Alt + Left Arrow)": "Go Back (Alt + Left Arrow)", + "Go Forward (Alt + Right Arrow)": "Go Forward (Alt + Right Arrow)", + "Parent Directory (Alt + Up Arrow)": "Parent Directory (Alt + Up Arrow)", + "Reload (f5)": "Reload (f5)", + "Close Tab": "Close Tab" } diff --git a/src/Locales/zh-TW.json b/src/Locales/zh-TW.json index c8f3450f..cf3c548f 100644 --- a/src/Locales/zh-TW.json +++ b/src/Locales/zh-TW.json @@ -1,114 +1,114 @@ { - "Favorites": "我的最愛", - "Desktop": "桌面", - "Documents": "文件", - "Downloads": "下載", - "Pictures": "圖片", - "Music": "音樂", - "Videos": "影片", - "Icon": "圖示", - "Show hidden files": "顯示隱藏的檔案", - "Files": "檔案", - "Pendrives": "外接儲存空間", - "Home": "主頁", - "Recent": "最近紀錄", - "Trash": "垃圾桶", - "Drives": "磁碟機", - "free of": "可用, 共", - "Settings": "設定", - "Appearance": "外觀", - "App Theme": "主題", - "Apply Shadow Effect": "Apply Shadow Effect", - "File Preview": "預覽檔案", - "Default File Layout": "預設排列方式", - "Show image as thumbnail": "以縮圖顯示", - "Disabled": "Disabled", - "For small directory (recommended)": "For small directory (recommended)", - "Enable for all directory": "Enable for all directory", - "System Default": "系統預設", - "Automatically play video file as thumbnail (May consume high amount of RAM)": "自動預覽影片 (可能佔用較多記憶體)", - "Extract exe file icon and make it as the thumbnail (Turning it on might crashes Xplorer)": "解壓縮檔案圖示並將其作為縮圖(打開它可能會讓 Xplorer 無法正常運作)", - "Preview image on hover": "懸停時預覽圖片", - "Font Family": "字體", - "Font Size": "Font Size", - "Window Transparency": "視窗透明", - "Transparent Effect": "透明效果", - "Blur": "Blur", - "Acrylic": "Acrylic", - "Mica": "Mica", - "Vibrancy": "Vibrancy (MacOS)", - "None": "None", - "Transparent Sidebar": "透明側邊欄", - "Transparent Topbar": "頂部透明", - "Transparent Workspace": "透明工作區", - "Frame Style": "外框樣式", - "Default": "預設值", - "Detect Drive Change": "偵測磁碟機變更", - "Automatically change preview file with selected file": "Automatically change preview file with selected file", - "Single/Double Click to open a file": "Single/Double Click to open a file", - "Double click to open items under sidebar section": "Double click to open items under sidebar section", - "Double click to open items under home section": "Double click to open items under home section", - "Double click to open files/folders": "Double click to open files/folders", - "Preference": "偏好選項", - "App Language": "語言", - "Files and Folders": "檔案與資料夾", - "Hide hidden files": "不顯示隱藏的檔案", - "Hide system files": "Hide system files", - "List and sort directories alongside files": "展開文件同時排序", - "On startup": "於啟動時", - "New tab": "New tab", - "Continue previous session": "Continue previous session", - "Workspace": "工作區", - "Show Info Bar": "顯示資訊欄", - "About": "關於", - "Layout Mode": "檢視模式", - "Grid View (Large)": "網格排列 (大)", - "Grid View (Medium)": "網格排列 (中)", - "Grid View (Small)": "網格排列 (小)", - "Detail View": "詳細資料", - "Sort By": "排序方式", - "A-Z": "遞增排序", - "Z-A": "遞減排序", - "Last Modified": "最後修改時間", - "First Modified": "首次修改時間", - "Size": "檔案大小", - "Type": "類型", - "Reload": "重整", - "Copy": "複製", - "Cut": "剪下", - "Paste": "貼上", - "Undo Action": "復原", - "Redo Action": "重做動作", - "Copy Location Path": "複製路徑", - "Clear Recent List": "清除最近的歷史紀錄", - "Open": "Open", - "Open in Terminal": "在終端機開啟", - "Open in VSCode": "在 VSCode 中開啟", - "New": "新增", - "File": "檔案", - "Folder": "資料夾", - "Unpin from Sidebar": "取消側欄釘選", - "Pin to Sidebar": "釘選至側欄", - "Compress to Zip": "Compress to Zip", - "Properties": "屬性", - "Rename": "重新命名", - "Delete": "刪除", - "Restore": "還原", - "Permanently Delete": "永久刪除", - "Open in New Tab": "在新分頁開啟", - "Preview": "預覽", - "Restore all files": "還原所有檔案", - "Permanently delete all files": "永久刪除所有檔案", - "Restore these files": "還原選取的檔案", - "Permanently delete these files": "永久刪除選取的檔案", - "Calculate sub folder size": "Calculate sub folder size", - "Search": "Search", - "Minimize": "Minimize", - "Maximize": "Maximize", - "Exit (Ctrl + w)": "Exit (Ctrl + w)", - "Go Back (Alt + Left Arrow)": "Go Back (Alt + Left Arrow)", - "Go Forward (Alt + Right Arrow)": "Go Forward (Alt + Right Arrow)", - "Parent Directory (Alt + Up Arrow)": "Parent Directory (Alt + Up Arrow)", - "Reload (f5)": "Reload (f5)", - "Close Tab": "Close Tab" + "Favorites": "我的最愛", + "Desktop": "桌面", + "Documents": "文件", + "Downloads": "下載", + "Pictures": "圖片", + "Music": "音樂", + "Videos": "影片", + "Icon": "圖示", + "Show hidden files": "顯示隱藏的檔案", + "Files": "檔案", + "Pendrives": "外接儲存空間", + "Home": "主頁", + "Recent": "最近紀錄", + "Trash": "垃圾桶", + "Drives": "磁碟機", + "free of": "可用, 共", + "Settings": "設定", + "Appearance": "外觀", + "App Theme": "主題", + "Apply Shadow Effect": "Apply Shadow Effect", + "File Preview": "預覽檔案", + "Default File Layout": "預設排列方式", + "Show image as thumbnail": "以縮圖顯示", + "Disabled": "Disabled", + "For small directory (recommended)": "For small directory (recommended)", + "Enable for all directory": "Enable for all directory", + "System Default": "系統預設", + "Automatically play video file as thumbnail (May consume high amount of RAM)": "自動預覽影片 (可能佔用較多記憶體)", + "Extract exe file icon and make it as the thumbnail (Turning it on might crashes Xplorer)": "解壓縮檔案圖示並將其作為縮圖(打開它可能會讓 Xplorer 無法正常運作)", + "Preview image on hover": "懸停時預覽圖片", + "Font Family": "字體", + "Font Size": "Font Size", + "Window Transparency": "視窗透明", + "Transparent Effect": "透明效果", + "Blur": "Blur", + "Acrylic": "Acrylic", + "Mica": "Mica", + "Vibrancy": "Vibrancy (MacOS)", + "None": "None", + "Transparent Sidebar": "透明側邊欄", + "Transparent Topbar": "頂部透明", + "Transparent Workspace": "透明工作區", + "Frame Style": "外框樣式", + "Default": "預設值", + "Detect Drive Change": "偵測磁碟機變更", + "Automatically change preview file with selected file": "Automatically change preview file with selected file", + "Single/Double Click to open a file": "Single/Double Click to open a file", + "Double click to open items under sidebar section": "Double click to open items under sidebar section", + "Double click to open items under home section": "Double click to open items under home section", + "Double click to open files/folders": "Double click to open files/folders", + "Preference": "偏好選項", + "App Language": "語言", + "Files and Folders": "檔案與資料夾", + "Hide hidden files": "不顯示隱藏的檔案", + "Hide system files": "Hide system files", + "List and sort directories alongside files": "展開文件同時排序", + "On startup": "於啟動時", + "New tab": "New tab", + "Continue previous session": "Continue previous session", + "Workspace": "工作區", + "Show Info Bar": "顯示資訊欄", + "About": "關於", + "Layout Mode": "檢視模式", + "Grid View (Large)": "網格排列 (大)", + "Grid View (Medium)": "網格排列 (中)", + "Grid View (Small)": "網格排列 (小)", + "Detail View": "詳細資料", + "Sort By": "排序方式", + "A-Z": "遞增排序", + "Z-A": "遞減排序", + "Last Modified": "最後修改時間", + "First Modified": "首次修改時間", + "Size": "檔案大小", + "Type": "類型", + "Reload": "重整", + "Copy": "複製", + "Cut": "剪下", + "Paste": "貼上", + "Undo Action": "復原", + "Redo Action": "重做動作", + "Copy Location Path": "複製路徑", + "Clear Recent List": "清除最近的歷史紀錄", + "Open": "Open", + "Open in Terminal": "在終端機開啟", + "Open in VSCode": "在 VSCode 中開啟", + "New": "新增", + "File": "檔案", + "Folder": "資料夾", + "Unpin from Sidebar": "取消側欄釘選", + "Pin to Sidebar": "釘選至側欄", + "Compress to Zip": "Compress to Zip", + "Properties": "屬性", + "Rename": "重新命名", + "Delete": "刪除", + "Restore": "還原", + "Permanently Delete": "永久刪除", + "Open in New Tab": "在新分頁開啟", + "Preview": "預覽", + "Restore all files": "還原所有檔案", + "Permanently delete all files": "永久刪除所有檔案", + "Restore these files": "還原選取的檔案", + "Permanently delete these files": "永久刪除選取的檔案", + "Calculate sub folder size": "Calculate sub folder size", + "Search": "Search", + "Minimize": "Minimize", + "Maximize": "Maximize", + "Exit (Ctrl + w)": "Exit (Ctrl + w)", + "Go Back (Alt + Left Arrow)": "Go Back (Alt + Left Arrow)", + "Go Forward (Alt + Right Arrow)": "Go Forward (Alt + Right Arrow)", + "Parent Directory (Alt + Up Arrow)": "Parent Directory (Alt + Up Arrow)", + "Reload (f5)": "Reload (f5)", + "Close Tab": "Close Tab" } diff --git a/src/Service/app.ts b/src/Service/app.ts index ff805adf..a1085db5 100644 --- a/src/Service/app.ts +++ b/src/Service/app.ts @@ -1,55 +1,57 @@ -import { GET_AVAILABLE_FONTS_ENDPOINT } from '../Util/constants'; -import isTauri from '../Util/is-tauri'; -import Storage from './storage'; +import { GET_AVAILABLE_FONTS_ENDPOINT } from "../Util/constants"; +import isTauri from "../Util/is-tauri"; +import Storage from "./storage"; let _vscodeInstalled: boolean | undefined; const isVSCodeInstalled = async (): Promise => { - if (!isTauri) return false; - const { invoke } = require('@tauri-apps/api'); - const storedUtils = await Storage.get('utils'); - if (storedUtils?.vscodeInstalled === undefined) { - if (_vscodeInstalled === undefined) { - _vscodeInstalled = await invoke('check_vscode_installed'); - storedUtils.vscodeInstalled = _vscodeInstalled; - Storage.set('utils', storedUtils); - } - } else _vscodeInstalled = storedUtils.vscodeInstalled; - return _vscodeInstalled; + if (!isTauri) return false; + const { invoke } = require("@tauri-apps/api"); + const storedUtils = await Storage.get("utils"); + if (storedUtils?.vscodeInstalled === undefined) { + if (_vscodeInstalled === undefined) { + _vscodeInstalled = await invoke("check_vscode_installed"); + storedUtils.vscodeInstalled = _vscodeInstalled; + Storage.set("utils", storedUtils); + } + } else _vscodeInstalled = storedUtils.vscodeInstalled; + return _vscodeInstalled; }; const getAvailableFonts = async (): Promise => { - if (isTauri) { - const { invoke } = require('@tauri-apps/api'); - return await invoke('get_available_fonts'); - } else { - const fonts = await (await fetch(GET_AVAILABLE_FONTS_ENDPOINT, { method: 'GET' })).json(); - return fonts; - } + if (isTauri) { + const { invoke } = require("@tauri-apps/api"); + return await invoke("get_available_fonts"); + } else { + const fonts = await (await fetch(GET_AVAILABLE_FONTS_ENDPOINT, { method: "GET" })).json(); + return fonts; + } }; let listened = false; const listenStylesheetChange = async (cb: (stylesheet: JSON) => void): Promise => { - if (!isTauri) return; - if (!listened) { - const { getCurrent } = require('@tauri-apps/api/window'); - const { invoke } = require('@tauri-apps/api'); - invoke('listen_stylesheet_change'); - // eslint-disable-next-line @typescript-eslint/no-explicit-any - getCurrent().listen('stylesheet_changes', (e: any) => { - cb(e.payload as JSON); - }); - listened = true; - } + if (!isTauri) return; + if (!listened) { + const { getCurrent } = require("@tauri-apps/api/window"); + const { invoke } = require("@tauri-apps/api"); + invoke("listen_stylesheet_change"); + // eslint-disable-next-line @typescript-eslint/no-explicit-any + getCurrent().listen("stylesheet_changes", (e: any) => { + cb(e.payload as JSON); + }); + listened = true; + } }; -const changeTransparentEffect = async (transparentEffect: 'blur' | 'acrylic' | 'none'): Promise => { - if (!isTauri) return; - const { invoke } = require('@tauri-apps/api'); - return await invoke('change_transparent_effect', { effect: transparentEffect }); +const changeTransparentEffect = async (transparentEffect: "blur" | "acrylic" | "none"): Promise => { + if (!isTauri) return; + const { invoke } = require("@tauri-apps/api"); + return await invoke("change_transparent_effect", { + effect: transparentEffect, + }); }; const enableShadowEffect = async (shadowEffect: boolean): Promise => { - if (!isTauri) return; - const { invoke } = require('@tauri-apps/api'); - return await invoke('enable_shadow_effect', { effect: shadowEffect }); + if (!isTauri) return; + const { invoke } = require("@tauri-apps/api"); + return await invoke("enable_shadow_effect", { effect: shadowEffect }); }; export { isVSCodeInstalled, getAvailableFonts, changeTransparentEffect, listenStylesheetChange, enableShadowEffect }; diff --git a/src/Service/cli.ts b/src/Service/cli.ts index 2bd0701a..55eb9a23 100644 --- a/src/Service/cli.ts +++ b/src/Service/cli.ts @@ -1,17 +1,17 @@ -import isTauri from '../Util/is-tauri'; +import isTauri from "../Util/is-tauri"; interface CliArgsReturnType { - dirs: string[]; - is_reveal: boolean; - custom_style_sheet: JSON; + dirs: string[]; + is_reveal: boolean; + custom_style_sheet: JSON; } const CLIInformations = async (): Promise => { - if (!isTauri) - return { - dirs: [], - is_reveal: false, - custom_style_sheet: {} as JSON, - }; - const { invoke } = require('@tauri-apps/api'); - return (await invoke('get_cli_args')) as CliArgsReturnType; + if (!isTauri) + return { + dirs: [], + is_reveal: false, + custom_style_sheet: {} as JSON, + }; + const { invoke } = require("@tauri-apps/api"); + return (await invoke("get_cli_args")) as CliArgsReturnType; }; export default CLIInformations; diff --git a/src/Service/clipboard.ts b/src/Service/clipboard.ts index 43028c7b..205f28ab 100644 --- a/src/Service/clipboard.ts +++ b/src/Service/clipboard.ts @@ -1,4 +1,4 @@ -import isTauri from '../Util/is-tauri'; +import isTauri from "../Util/is-tauri"; /** * Write text into clipboard @@ -6,12 +6,12 @@ import isTauri from '../Util/is-tauri'; * @returns {void} */ const writeTextToClipboard = async (text: string): Promise => { - if (isTauri) { - const { clipboard } = require('@tauri-apps/api'); - return await clipboard.writeText(text); - } else { - return await navigator.clipboard.writeText(text); - } + if (isTauri) { + const { clipboard } = require("@tauri-apps/api"); + return await clipboard.writeText(text); + } else { + return await navigator.clipboard.writeText(text); + } }; /** @@ -19,11 +19,11 @@ const writeTextToClipboard = async (text: string): Promise => { * @returns {Promise} */ const readTextFromClipboard = async (): Promise => { - if (isTauri) { - const { clipboard } = require('@tauri-apps/api'); - return await clipboard.readText(); - } else { - return await navigator.clipboard.readText(); - } + if (isTauri) { + const { clipboard } = require("@tauri-apps/api"); + return await clipboard.readText(); + } else { + return await navigator.clipboard.readText(); + } }; export { writeTextToClipboard, readTextFromClipboard }; diff --git a/src/Service/directory.ts b/src/Service/directory.ts index e6f0beb9..639d11a7 100644 --- a/src/Service/directory.ts +++ b/src/Service/directory.ts @@ -1,181 +1,184 @@ -import joinPath from '../Components/Functions/path/joinPath'; -import normalizeSlash from '../Components/Functions/path/normalizeSlash'; -import type FileMetaData from '../Typings/fileMetaData'; -import type { UnlistenFn } from '@tauri-apps/api/event'; -import { LnkData } from '../Typings/fileMetaData'; -import isTauri from '../Util/is-tauri'; -import { CHECK_EXIST_ENDPOINT, CHECK_ISDIR_ENDPOINT, GET_DIR_SIZE_ENDPOINT, READ_DIR_ENDPOINT } from '../Util/constants'; +import type { UnlistenFn } from "@tauri-apps/api/event"; +import joinPath from "../Components/Functions/path/joinPath"; +import normalizeSlash from "../Components/Functions/path/normalizeSlash"; +import type FileMetaData from "../Typings/fileMetaData"; +import type { LnkData } from "../Typings/fileMetaData"; +import { CHECK_EXIST_ENDPOINT, CHECK_ISDIR_ENDPOINT, GET_DIR_SIZE_ENDPOINT, READ_DIR_ENDPOINT } from "../Util/constants"; +import isTauri from "../Util/is-tauri"; let listener: UnlistenFn; let searchListener: UnlistenFn; interface DirectoryData { - files: FileMetaData[]; - number_of_files: number; - skipped_files: string[]; - lnk_files: LnkData[]; + files: FileMetaData[]; + number_of_files: number; + skipped_files: string[]; + lnk_files: LnkData[]; } /** * Invoke Rust command to read information of a directory */ class DirectoryAPI { - readonly dirName: string; - readonly parentDir: string; - files: FileMetaData[]; - constructor(dirName: string, parentDir?: string) { - if (parentDir) { - this.parentDir = normalizeSlash(parentDir); - this.dirName = normalizeSlash(joinPath(parentDir, dirName)); - } else this.dirName = normalizeSlash(dirName); - } - /** - * Get files inside a directory - * @returns {Promise} - */ - getFiles(): Promise { - return new Promise((resolve, reject) => { - if (isTauri) { - const { invoke } = require('@tauri-apps/api'); - invoke('read_directory', { dir: this.dirName }) - .then((files: DirectoryData) => { - this.files = files.files; - resolve(files); - }) - .catch((err: string) => { - reject(err); - }); - } else { - fetch(READ_DIR_ENDPOINT + this.dirName, { method: 'GET' }).then((res) => { - res.json() - .then((files: DirectoryData) => { - this.files = files.files; - resolve(files); - }) - .catch((err) => { - console.error(err); - }); - }); - } - }); - } - /** - * Check if given path is directory - * @returns {Promise} - */ - async isDir(): Promise { - return new Promise((resolve) => { - if (isTauri) { - const { invoke } = require('@tauri-apps/api'); - invoke('is_dir', { path: this.dirName }).then((result: boolean) => resolve(result)); - } else { - fetch(CHECK_ISDIR_ENDPOINT + this.dirName, { method: 'GET' }) - .then((response) => response.json()) - .then((result: boolean) => resolve(result)); - } - }); - } - /** - * Return true if folder exist - * @returns {boolean} - */ - async exists(): Promise { - if (isTauri) { - const { invoke } = require('@tauri-apps/api'); - return await invoke('file_exist', { filePath: this.dirName }); - } else { - const exists = await (await fetch(CHECK_EXIST_ENDPOINT + this.dirName, { method: 'GET' })).json(); - return exists; - } - } - /** - * Create dir if not exists - * @returns {any} - */ - async mkdir(): Promise { - if (isTauri) { - const { invoke } = require('@tauri-apps/api'); - return await invoke('create_dir_recursive', { - dirPath: this.dirName, - }); - } - } + readonly dirName: string; + readonly parentDir: string; + files: FileMetaData[]; + constructor(dirName: string, parentDir?: string) { + if (parentDir) { + this.parentDir = normalizeSlash(parentDir); + this.dirName = normalizeSlash(joinPath(parentDir, dirName)); + } else this.dirName = normalizeSlash(dirName); + } + /** + * Get files inside a directory + * @returns {Promise} + */ + getFiles(): Promise { + return new Promise((resolve, reject) => { + if (isTauri) { + const { invoke } = require("@tauri-apps/api"); + invoke("read_directory", { dir: this.dirName }) + .then((files: DirectoryData) => { + this.files = files.files; + resolve(files); + }) + .catch((err: string) => { + reject(err); + }); + } else { + fetch(READ_DIR_ENDPOINT + this.dirName, { method: "GET" }).then((res) => { + res.json() + .then((files: DirectoryData) => { + this.files = files.files; + resolve(files); + }) + .catch((err) => { + console.error(err); + }); + }); + } + }); + } + /** + * Check if given path is directory + * @returns {Promise} + */ + async isDir(): Promise { + return new Promise((resolve) => { + if (isTauri) { + const { invoke } = require("@tauri-apps/api"); + invoke("is_dir", { path: this.dirName }).then((result: boolean) => resolve(result)); + } else { + fetch(CHECK_ISDIR_ENDPOINT + this.dirName, { method: "GET" }) + .then((response) => response.json()) + .then((result: boolean) => resolve(result)); + } + }); + } + /** + * Return true if folder exist + * @returns {boolean} + */ + async exists(): Promise { + if (isTauri) { + const { invoke } = require("@tauri-apps/api"); + return await invoke("file_exist", { filePath: this.dirName }); + } else { + const exists = await (await fetch(CHECK_EXIST_ENDPOINT + this.dirName, { method: "GET" })).json(); + return exists; + } + } + /** + * Create dir if not exists + * @returns {any} + */ + async mkdir(): Promise { + if (isTauri) { + const { invoke } = require("@tauri-apps/api"); + return await invoke("create_dir_recursive", { + dirPath: this.dirName, + }); + } + } - /** - * Listen to changes in a directory - * @param {() => void} cb - callback - * @returns {any} - */ - async listen(cb: () => void): Promise { - if (isTauri) { - const { invoke } = require('@tauri-apps/api'); - invoke('listen_dir', { dir: this.dirName }); - const { getCurrent } = require('@tauri-apps/api/window'); - // eslint-disable-next-line @typescript-eslint/no-explicit-any - listener = await getCurrent().listen('changes', (e: any) => { - console.log(e); - cb(); - }); - } - } - /** - * Unlisten to previous listener - * @returns {Promise} - */ - async unlisten(): Promise { - if (isTauri) { - const { getCurrent } = require('@tauri-apps/api/window'); - listener?.(); - return getCurrent().emit('unlisten_dir'); - } - } + /** + * Listen to changes in a directory + * @param {() => void} cb - callback + * @returns {any} + */ + async listen(cb: () => void): Promise { + if (isTauri) { + const { invoke } = require("@tauri-apps/api"); + invoke("listen_dir", { dir: this.dirName }); + const { getCurrent } = require("@tauri-apps/api/window"); + // eslint-disable-next-line @typescript-eslint/no-explicit-any + listener = await getCurrent().listen("changes", (e: any) => { + console.log(e); + cb(); + }); + } + } + /** + * Unlisten to previous listener + * @returns {Promise} + */ + async unlisten(): Promise { + if (isTauri) { + const { getCurrent } = require("@tauri-apps/api/window"); + listener?.(); + return getCurrent().emit("unlisten_dir"); + } + } - /** - * Get size of a directory - * @returns {Promise} - */ - async getSize(): Promise { - if (isTauri) { - const { invoke } = require('@tauri-apps/api'); - return await invoke('get_dir_size', { dir: this.dirName }); - } else { - const size = await (await fetch(GET_DIR_SIZE_ENDPOINT + this.dirName, { method: 'GET' })).json(); - return size; - } - } + /** + * Get size of a directory + * @returns {Promise} + */ + async getSize(): Promise { + if (isTauri) { + const { invoke } = require("@tauri-apps/api"); + return await invoke("get_dir_size", { dir: this.dirName }); + } else { + const size = await (await fetch(GET_DIR_SIZE_ENDPOINT + this.dirName, { method: "GET" })).json(); + return size; + } + } - /** - * Stop all searching progress - * @returns {Promise} - */ - async stopSearching(): Promise { - if (isTauri) { - const { getCurrent } = require('@tauri-apps/api/window'); + /** + * Stop all searching progress + * @returns {Promise} + */ + async stopSearching(): Promise { + if (isTauri) { + const { getCurrent } = require("@tauri-apps/api/window"); - const listenerExist = searchListener !== null && searchListener !== undefined; - searchListener?.(); - await getCurrent().emit('unsearch'); - return listenerExist; - } - } + const listenerExist = searchListener !== null && searchListener !== undefined; + searchListener?.(); + await getCurrent().emit("unsearch"); + return listenerExist; + } + } - /** - * Search for a file/folder in a directory - * @param {string} pattern - glob pattern - * @param {FileMetaData[] => void} callback - progress callback - * @returns {any} - */ - async search(pattern: string, callback: (partialFound: FileMetaData[]) => void): Promise { - if (isTauri) { - const { getCurrent } = require('@tauri-apps/api/window'); - // eslint-disable-next-line @typescript-eslint/no-explicit-any - searchListener = await getCurrent().listen('search_partial_result', (res: any) => { - if (searchListener !== null && searchListener !== undefined) callback(res.payload as FileMetaData[]); - }); - const { invoke } = require('@tauri-apps/api'); - const res = await invoke('search_in_dir', { dirPath: this.dirName, pattern }); - await this.stopSearching(); - searchListener = null; - return res as FileMetaData[]; - } - } + /** + * Search for a file/folder in a directory + * @param {string} pattern - glob pattern + * @param {FileMetaData[] => void} callback - progress callback + * @returns {any} + */ + async search(pattern: string, callback: (partialFound: FileMetaData[]) => void): Promise { + if (isTauri) { + const { getCurrent } = require("@tauri-apps/api/window"); + // eslint-disable-next-line @typescript-eslint/no-explicit-any + searchListener = await getCurrent().listen("search_partial_result", (res: any) => { + if (searchListener !== null && searchListener !== undefined) callback(res.payload as FileMetaData[]); + }); + const { invoke } = require("@tauri-apps/api"); + const res = await invoke("search_in_dir", { + dirPath: this.dirName, + pattern, + }); + await this.stopSearching(); + searchListener = null; + return res as FileMetaData[]; + } + } } export default DirectoryAPI; diff --git a/src/Service/drives.ts b/src/Service/drives.ts index d541f39f..943a2af9 100644 --- a/src/Service/drives.ts +++ b/src/Service/drives.ts @@ -1,98 +1,98 @@ -import { GET_DRIVES_ENDPOINT } from '../Util/constants'; -import isTauri from '../Util/is-tauri'; -import OS from './platform'; +import { GET_DRIVES_ENDPOINT } from "../Util/constants"; +import isTauri from "../Util/is-tauri"; +import OS from "./platform"; interface Drive { - name: string; - mount_point: string; - total_space: number; - available_space: number; - is_removable: boolean; - disk_type: 'HDD' | 'SSD' | 'Removable Disk'; - file_system: string; + name: string; + mount_point: string; + total_space: number; + available_space: number; + is_removable: boolean; + disk_type: "HDD" | "SSD" | "Removable Disk"; + file_system: string; } interface UniqueDrive { - mount_point: string; - name: string; + mount_point: string; + name: string; } let platform: string; (async () => { - if (!platform) { - platform = await OS(); - } + if (!platform) { + platform = await OS(); + } })(); /** * Invoke Rust command to list user's drive */ class DrivesAPI { - DRIVES: Drive[]; - /** - * List all user's drives - * @returns {Promise} - */ - get(): Promise { - return new Promise((resolve) => { - if (isTauri) { - const { invoke } = require('@tauri-apps/api'); + DRIVES: Drive[]; + /** + * List all user's drives + * @returns {Promise} + */ + get(): Promise { + return new Promise((resolve) => { + if (isTauri) { + const { invoke } = require("@tauri-apps/api"); - invoke('get_drives').then((drives: { array_of_drives: Drive[] }) => { - let filteredDrives = drives.array_of_drives.filter((drive) => drive.available_space > 0); - if (platform !== 'win32') { - filteredDrives = filteredDrives.filter((drive) => drive.is_removable); - } - resolve(filteredDrives); - }); - } else { - fetch(GET_DRIVES_ENDPOINT, { method: 'GET' }) - .then((res) => res.json()) - .then((res: { array_of_drives: Drive[] }) => { - let filteredDrives = res.array_of_drives.filter((drive) => drive.available_space > 0); - if (platform !== 'win32') { - filteredDrives = filteredDrives.filter((drive) => drive.is_removable); - } - resolve(filteredDrives); - }); - } - }); - } - async build(): Promise { - this.DRIVES = await this.get(); - } - /** - * Filter drives into unique drives regardless space - * @param {Array} drives - drives array - * @returns {UniqueDrive[]} unique drives array - */ - getUniqueDrives(drives: Array): Array { - const result: UniqueDrive[] = []; - drives.forEach((drive) => - result.push({ - mount_point: drive.mount_point, - name: drive.name && /[^?]/.test(drive.name) ? drive.name : drive.disk_type, - }) - ); - return result; - } - /** - * Listen to drives state changes - * @param {() => void} cb Callback function - * @returns {Promise} - */ - async detectChange(cb: () => void): Promise { - await this.build(); - let _drives = JSON.stringify(this.getUniqueDrives(this.DRIVES)); - setInterval(async () => { - await this.build(); - const _refreshedDrive = JSON.stringify(this.getUniqueDrives(this.DRIVES)); - if (_refreshedDrive !== _drives) { - cb(); - } - _drives = _refreshedDrive; - }, 500); - } + invoke("get_drives").then((drives: { array_of_drives: Drive[] }) => { + let filteredDrives = drives.array_of_drives.filter((drive) => drive.available_space > 0); + if (platform !== "win32") { + filteredDrives = filteredDrives.filter((drive) => drive.is_removable); + } + resolve(filteredDrives); + }); + } else { + fetch(GET_DRIVES_ENDPOINT, { method: "GET" }) + .then((res) => res.json()) + .then((res: { array_of_drives: Drive[] }) => { + let filteredDrives = res.array_of_drives.filter((drive) => drive.available_space > 0); + if (platform !== "win32") { + filteredDrives = filteredDrives.filter((drive) => drive.is_removable); + } + resolve(filteredDrives); + }); + } + }); + } + async build(): Promise { + this.DRIVES = await this.get(); + } + /** + * Filter drives into unique drives regardless space + * @param {Array} drives - drives array + * @returns {UniqueDrive[]} unique drives array + */ + getUniqueDrives(drives: Array): Array { + const result: UniqueDrive[] = []; + drives.forEach((drive) => + result.push({ + mount_point: drive.mount_point, + name: drive.name && /[^?]/.test(drive.name) ? drive.name : drive.disk_type, + }), + ); + return result; + } + /** + * Listen to drives state changes + * @param {() => void} cb Callback function + * @returns {Promise} + */ + async detectChange(cb: () => void): Promise { + await this.build(); + let _drives = JSON.stringify(this.getUniqueDrives(this.DRIVES)); + setInterval(async () => { + await this.build(); + const _refreshedDrive = JSON.stringify(this.getUniqueDrives(this.DRIVES)); + if (_refreshedDrive !== _drives) { + cb(); + } + _drives = _refreshedDrive; + }, 500); + } } export default DrivesAPI; -export { Drive }; +export type { Drive }; diff --git a/src/Service/favorites.ts b/src/Service/favorites.ts index 2f28ba5d..6e7fbcbe 100644 --- a/src/Service/favorites.ts +++ b/src/Service/favorites.ts @@ -1,41 +1,41 @@ -import isTauri from '../Util/is-tauri'; -import { GET_FAVORITES_PATH_ENDPOINT } from '../Util/constants'; +import { GET_FAVORITES_PATH_ENDPOINT } from "../Util/constants"; +import isTauri from "../Util/is-tauri"; class FavoritesAPI { - DOCUMENT_PATH: string; - DOWNLOAD_PATH: string; - DESKTOP_PATH: string; - PICTURE_PATH: string; - MUSIC_PATH: string; - VIDEO_PATH: string; - HOMEDIR_PATH: string; - async build(): Promise { - if (!isTauri) { - const res = await fetch(GET_FAVORITES_PATH_ENDPOINT); - const data = await res.json(); - this.DOCUMENT_PATH = data.document; - this.DOWNLOAD_PATH = data.download; - this.DESKTOP_PATH = data.desktop; - this.PICTURE_PATH = data.picture; - this.MUSIC_PATH = data.audio; - this.VIDEO_PATH = data.video; - this.HOMEDIR_PATH = data.home; - } else { - const { path } = require('@tauri-apps/api'); - try { - this.DOCUMENT_PATH = await path.documentDir(); - this.DOWNLOAD_PATH = await path.downloadDir(); - this.DESKTOP_PATH = await path.desktopDir(); - this.PICTURE_PATH = await path.pictureDir(); - this.MUSIC_PATH = await path.audioDir(); - this.VIDEO_PATH = await path.videoDir(); - // eslint-disable-next-line no-empty - } catch (_) {} - try { - this.HOMEDIR_PATH = await path.homeDir(); - // eslint-disable-next-line no-empty - } catch (_) {} - } - } + DOCUMENT_PATH: string; + DOWNLOAD_PATH: string; + DESKTOP_PATH: string; + PICTURE_PATH: string; + MUSIC_PATH: string; + VIDEO_PATH: string; + HOMEDIR_PATH: string; + async build(): Promise { + if (!isTauri) { + const res = await fetch(GET_FAVORITES_PATH_ENDPOINT); + const data = await res.json(); + this.DOCUMENT_PATH = data.document; + this.DOWNLOAD_PATH = data.download; + this.DESKTOP_PATH = data.desktop; + this.PICTURE_PATH = data.picture; + this.MUSIC_PATH = data.audio; + this.VIDEO_PATH = data.video; + this.HOMEDIR_PATH = data.home; + } else { + const { path } = require("@tauri-apps/api"); + try { + this.DOCUMENT_PATH = await path.documentDir(); + this.DOWNLOAD_PATH = await path.downloadDir(); + this.DESKTOP_PATH = await path.desktopDir(); + this.PICTURE_PATH = await path.pictureDir(); + this.MUSIC_PATH = await path.audioDir(); + this.VIDEO_PATH = await path.videoDir(); + // eslint-disable-next-line no-empty + } catch (_) {} + try { + this.HOMEDIR_PATH = await path.homeDir(); + // eslint-disable-next-line no-empty + } catch (_) {} + } + } } export default FavoritesAPI; diff --git a/src/Service/files.ts b/src/Service/files.ts index c4ea538a..0d742ced 100644 --- a/src/Service/files.ts +++ b/src/Service/files.ts @@ -1,197 +1,204 @@ -import joinPath from '../Components/Functions/path/joinPath'; -import dirname from '../Components/Functions/path/dirname'; -import FileMetaData from '../Typings/fileMetaData'; -import isTauri from '../Util/is-tauri'; -import { CALCULATE_DIRS_SIZE_ENDPOINT, CHECK_EXIST_ENDPOINT, CHECK_ISDIR_ENDPOINT, OPEN_FILE_ENDPOINT } from '../Util/constants'; +import dirname from "../Components/Functions/path/dirname"; +import joinPath from "../Components/Functions/path/joinPath"; +import type FileMetaData from "../Typings/fileMetaData"; +import { CALCULATE_DIRS_SIZE_ENDPOINT, CHECK_EXIST_ENDPOINT, CHECK_ISDIR_ENDPOINT, OPEN_FILE_ENDPOINT } from "../Util/constants"; +import isTauri from "../Util/is-tauri"; /** Invoke Rust command to handle files */ class FileAPI { - readonly fileName: string | string[]; - readonly parentDir: string; - /** - * Construct FileAPI Class - * @param {string} fileName - Your file path - * @param {string} parentDir - Parent directory of the file - */ - constructor(fileName: string | string[], parentDir?: string) { - if (parentDir && typeof fileName === 'string') { - this.parentDir = parentDir; - this.fileName = joinPath(parentDir, fileName); - } else this.fileName = fileName; - } - /** - * Read text file - * @returns {Promise} - */ - readFile(): Promise { - return new Promise((resolve, reject) => { - if (typeof this.fileName === 'string') { - if (isTauri) { - const { fs } = require('@tauri-apps/api'); - fs.readTextFile(this.fileName).then((fileContent: string) => resolve(fileContent)); - } else { - reject('Read file is currently not supported on web version'); - } - } else { - reject('File name is not a string'); - } - }); - } + readonly fileName: string | string[]; + readonly parentDir: string; + /** + * Construct FileAPI Class + * @param {string} fileName - Your file path + * @param {string} parentDir - Parent directory of the file + */ + constructor(fileName: string | string[], parentDir?: string) { + if (parentDir && typeof fileName === "string") { + this.parentDir = parentDir; + this.fileName = joinPath(parentDir, fileName); + } else this.fileName = fileName; + } + /** + * Read text file + * @returns {Promise} + */ + readFile(): Promise { + return new Promise((resolve, reject) => { + if (typeof this.fileName === "string") { + if (isTauri) { + const { fs } = require("@tauri-apps/api"); + fs.readTextFile(this.fileName).then((fileContent: string) => resolve(fileContent)); + } else { + reject("Read file is currently not supported on web version"); + } + } else { + reject("File name is not a string"); + } + }); + } - async readBuffer(): Promise { - const Buffer = require('buffer/').Buffer; - return new Promise((resolve, reject) => { - if (typeof this.fileName === 'string') { - if (isTauri) { - const { fs } = require('@tauri-apps/api'); - resolve(Buffer.from(fs.readBinaryFile(this.fileName).then((fileContent: string) => fileContent))); - } else { - reject('Read file is currently not supported on web version'); - } - } - }); - } - /** - * Open file on default app - * @returns {Promise} - */ - async openFile(): Promise { - if (isTauri) { - const { invoke } = require('@tauri-apps/api'); - return await invoke('open_file', { filePath: this.fileName }); - } else { - await fetch(OPEN_FILE_ENDPOINT + this.fileName, { method: 'GET' }); - return; - } - } - /** - * Get tauri url of local assets - * @returns {string} - */ - readAsset(): string { - if (isTauri) { - const { tauri } = require('@tauri-apps/api'); - return typeof this.fileName === 'string' ? tauri.convertFileSrc(this.fileName) : ''; - } - } - /** - * Read file and return as JSON - * @returns {Promise} - */ - async readJSONFile(): Promise { - const content = await this.readFile(); - return JSON.parse(content); - } + async readBuffer(): Promise { + const Buffer = require("buffer/").Buffer; + return new Promise((resolve, reject) => { + if (typeof this.fileName === "string") { + if (isTauri) { + const { fs } = require("@tauri-apps/api"); + resolve(Buffer.from(fs.readBinaryFile(this.fileName).then((fileContent: string) => fileContent))); + } else { + reject("Read file is currently not supported on web version"); + } + } + }); + } + /** + * Open file on default app + * @returns {Promise} + */ + async openFile(): Promise { + if (isTauri) { + const { invoke } = require("@tauri-apps/api"); + return await invoke("open_file", { filePath: this.fileName }); + } else { + await fetch(OPEN_FILE_ENDPOINT + this.fileName, { method: "GET" }); + return; + } + } + /** + * Get tauri url of local assets + * @returns {string} + */ + readAsset(): string { + if (isTauri) { + const { tauri } = require("@tauri-apps/api"); + return typeof this.fileName === "string" ? tauri.convertFileSrc(this.fileName) : ""; + } + } + /** + * Read file and return as JSON + * @returns {Promise} + */ + async readJSONFile(): Promise { + const content = await this.readFile(); + return JSON.parse(content); + } - /** - * Return true if file exist - * @returns {boolean} - */ - async exists(): Promise { - if (isTauri) { - const { invoke } = require('@tauri-apps/api'); - return await invoke('file_exist', { filePath: this.fileName }); - } else { - const exists = await (await fetch(CHECK_EXIST_ENDPOINT + this.fileName, { method: 'GET' })).json(); - return exists; - } - } - /** - * Create file if it doesn't exist - * @returns {Promise} - */ - async createFile(): Promise { - if (typeof this.fileName === 'string') { - if (isTauri) { - const { invoke } = require('@tauri-apps/api'); - await invoke('create_dir_recursive', { - dirPath: dirname(this.fileName), - }); - return await invoke('create_file', { filePath: this.fileName }); - } else { - return; - } - } - } - /** - * Read properties of a file - * @returns {Promise} - */ - async properties(): Promise { - if (isTauri) { - const { invoke } = require('@tauri-apps/api'); - return await invoke('get_file_properties', { filePath: this.fileName }); - } - } + /** + * Return true if file exist + * @returns {boolean} + */ + async exists(): Promise { + if (isTauri) { + const { invoke } = require("@tauri-apps/api"); + return await invoke("file_exist", { filePath: this.fileName }); + } else { + const exists = await (await fetch(CHECK_EXIST_ENDPOINT + this.fileName, { method: "GET" })).json(); + return exists; + } + } + /** + * Create file if it doesn't exist + * @returns {Promise} + */ + async createFile(): Promise { + if (typeof this.fileName === "string") { + if (isTauri) { + const { invoke } = require("@tauri-apps/api"); + await invoke("create_dir_recursive", { + dirPath: dirname(this.fileName), + }); + return await invoke("create_file", { filePath: this.fileName }); + } else { + return; + } + } + } + /** + * Read properties of a file + * @returns {Promise} + */ + async properties(): Promise { + if (isTauri) { + const { invoke } = require("@tauri-apps/api"); + return await invoke("get_file_properties", { filePath: this.fileName }); + } + } - /** - * Check if given path is directory - * @returns {Promise} - */ - async isDir(): Promise { - return new Promise((resolve) => { - if (isTauri) { - const { invoke } = require('@tauri-apps/api'); - invoke('is_dir', { path: this.fileName }).then((result: boolean) => resolve(result)); - } else { - fetch(CHECK_ISDIR_ENDPOINT + this.fileName, { method: 'GET' }) - .then((response) => response.json()) - .then((result: boolean) => resolve(result)); - } - }); - } + /** + * Check if given path is directory + * @returns {Promise} + */ + async isDir(): Promise { + return new Promise((resolve) => { + if (isTauri) { + const { invoke } = require("@tauri-apps/api"); + invoke("is_dir", { path: this.fileName }).then((result: boolean) => resolve(result)); + } else { + fetch(CHECK_ISDIR_ENDPOINT + this.fileName, { method: "GET" }) + .then((response) => response.json()) + .then((result: boolean) => resolve(result)); + } + }); + } - /** - * Extract icon of executable file - * @returns {Promise} - */ - async extractIcon(): Promise { - if (isTauri) { - const { invoke } = require('@tauri-apps/api'); - return await invoke('extract_icon', { filePath: this.fileName }); - } - } + /** + * Extract icon of executable file + * @returns {Promise} + */ + async extractIcon(): Promise { + if (isTauri) { + const { invoke } = require("@tauri-apps/api"); + return await invoke("extract_icon", { filePath: this.fileName }); + } + } - /** - * Calculate total size of given file paths - * @returns {number} - Size in bytes - */ - async calculateFilesSize(): Promise { - if (isTauri) { - const { invoke } = require('@tauri-apps/api'); - return await invoke('calculate_files_total_size', { files: this.fileName }); - } else { - const paths = Array.isArray(this.fileName) ? this.fileName.join('%2c-%2c') : this.fileName; - console.log(paths); - const size = await (await fetch(CALCULATE_DIRS_SIZE_ENDPOINT + paths, { method: 'GET' })).json(); - return size; - } - } + /** + * Calculate total size of given file paths + * @returns {number} - Size in bytes + */ + async calculateFilesSize(): Promise { + if (isTauri) { + const { invoke } = require("@tauri-apps/api"); + return await invoke("calculate_files_total_size", { + files: this.fileName, + }); + } else { + const paths = Array.isArray(this.fileName) ? this.fileName.join("%2c-%2c") : this.fileName; + console.log(paths); + const size = await (await fetch(CALCULATE_DIRS_SIZE_ENDPOINT + paths, { method: "GET" })).json(); + return size; + } + } - /** - * Compress file(s) to zip file - * @returns {Promise} - */ - async zip(): Promise { - if (isTauri) { - const { invoke } = require('@tauri-apps/api'); - return await invoke('compress_to_zip', { files: typeof this.fileName === 'string' ? [this.fileName] : this.fileName }); - } - return; - } + /** + * Compress file(s) to zip file + * @returns {Promise} + */ + async zip(): Promise { + if (isTauri) { + const { invoke } = require("@tauri-apps/api"); + return await invoke("compress_to_zip", { + files: typeof this.fileName === "string" ? [this.fileName] : this.fileName, + }); + } + return; + } - /** - * Extract zip file - * @param {string} target_dir - Target directory to extract files - * @returns {any} - */ - async unzip(target_dir: string): Promise { - if (isTauri) { - const { invoke } = require('@tauri-apps/api'); - return await invoke('decompress_from_zip', { zipPath: this.fileName, targetDir: target_dir }); - } - return; - } + /** + * Extract zip file + * @param {string} target_dir - Target directory to extract files + * @returns {any} + */ + async unzip(target_dir: string): Promise { + if (isTauri) { + const { invoke } = require("@tauri-apps/api"); + return await invoke("decompress_from_zip", { + zipPath: this.fileName, + targetDir: target_dir, + }); + } + return; + } } export default FileAPI; diff --git a/src/Service/locales.ts b/src/Service/locales.ts index f5b171dc..ad3208df 100644 --- a/src/Service/locales.ts +++ b/src/Service/locales.ts @@ -1,29 +1,27 @@ -import localesInformation from '../Locales/index.json'; +import localesInformation from "../Locales/index.json"; interface AvailableLocalesType { - [key: string]: string; + [key: string]: string; } interface Locales { - [key: string]: { - [key: string]: string; - }; + [key: string]: { + [key: string]: string; + }; } class LocalesAPI { - AVAILABLE_LOCALES: AvailableLocalesType; - LOCALES: Locales; - constructor() { - this.LOCALES = {}; - } - async build(): Promise { - this.AVAILABLE_LOCALES = localesInformation.availableLanguages; - for (const locale of Object.values(this.AVAILABLE_LOCALES)) { - const localeJSON = await import( - '../Locales/' + (locale === 'en-US' ? 'base' : locale) + '.json' - ); - this.LOCALES[locale] = localeJSON; - } - } + AVAILABLE_LOCALES: AvailableLocalesType; + LOCALES: Locales; + constructor() { + this.LOCALES = {}; + } + async build(): Promise { + this.AVAILABLE_LOCALES = localesInformation.availableLanguages; + for (const locale of Object.values(this.AVAILABLE_LOCALES)) { + const localeJSON = await import("../Locales/" + (locale === "en-US" ? "base" : locale) + ".json"); + this.LOCALES[locale] = localeJSON; + } + } } export default LocalesAPI; diff --git a/src/Service/operation.ts b/src/Service/operation.ts index d4be308d..d910c84d 100644 --- a/src/Service/operation.ts +++ b/src/Service/operation.ts @@ -1,62 +1,62 @@ -import isTauri from '../Util/is-tauri'; -import DirectoryAPI from './directory'; +import isTauri from "../Util/is-tauri"; +import DirectoryAPI from "./directory"; /** * Invoke Rust command to operate files/dirs */ class OperationAPI { - private src: string; - private dest: string; - constructor(src: string, dest?: string) { - this.src = src; - this.dest = dest; - } - /** - * Copy files/dirs - * @returns {Promise} - */ - async copyFile(): Promise { - if (isTauri) { - const { invoke } = require('@tauri-apps/api'); - return await invoke('copy', { src: this.src, dest: this.dest }); - } - } - /** - * Rename file/dir - * @returns {any} - */ - async rename(): Promise { - if (isTauri) { - const { invoke } = require('@tauri-apps/api'); + private src: string; + private dest: string; + constructor(src: string, dest?: string) { + this.src = src; + this.dest = dest; + } + /** + * Copy files/dirs + * @returns {Promise} + */ + async copyFile(): Promise { + if (isTauri) { + const { invoke } = require("@tauri-apps/api"); + return await invoke("copy", { src: this.src, dest: this.dest }); + } + } + /** + * Rename file/dir + * @returns {any} + */ + async rename(): Promise { + if (isTauri) { + const { invoke } = require("@tauri-apps/api"); - return await invoke('rename', { path: this.src, newPath: this.dest }); - } - } + return await invoke("rename", { path: this.src, newPath: this.dest }); + } + } - async cut(): Promise { - await this.copyFile(); - await this.unlink(); - return; - } + async cut(): Promise { + await this.copyFile(); + await this.unlink(); + return; + } - /** - * Unlink files/dirs - * @returns {Promise} - */ - async unlink(): Promise { - if (isTauri) { - const { invoke } = require('@tauri-apps/api'); - if (await new DirectoryAPI(this.src).isDir()) { - return await invoke('remove_dir', { path: this.src }); - } else { - return await invoke('remove_file', { path: this.src }); - } - } - } + /** + * Unlink files/dirs + * @returns {Promise} + */ + async unlink(): Promise { + if (isTauri) { + const { invoke } = require("@tauri-apps/api"); + if (await new DirectoryAPI(this.src).isDir()) { + return await invoke("remove_dir", { path: this.src }); + } else { + return await invoke("remove_file", { path: this.src }); + } + } + } - async duplicate(): Promise { - this.dest = - this.src.split('.').length > 1 ? this.src.split('.').slice(0, -1) + ' - COPY.' + this.src.split('.').slice(-1) : this.src + ' - COPY'; - return await this.copyFile(); - } + async duplicate(): Promise { + this.dest = + this.src.split(".").length > 1 ? this.src.split(".").slice(0, -1) + " - COPY." + this.src.split(".").slice(-1) : this.src + " - COPY"; + return await this.copyFile(); + } } export default OperationAPI; diff --git a/src/Service/platform.ts b/src/Service/platform.ts index ed361c4c..0642dcdd 100644 --- a/src/Service/platform.ts +++ b/src/Service/platform.ts @@ -1,25 +1,25 @@ -import { GET_PLATFORM_ENDPOINT } from '../Util/constants'; -import isTauri from '../Util/is-tauri'; +import { GET_PLATFORM_ENDPOINT } from "../Util/constants"; +import isTauri from "../Util/is-tauri"; const OS = async (): Promise => { - let platform: string; - if (isTauri) { - const { os } = require('@tauri-apps/api'); - platform = await os.platform(); - } else { - platform = await (await fetch(GET_PLATFORM_ENDPOINT, { method: 'GET' })).json(); - } - if (platform === 'windows') return 'win32'; - if (platform === 'macos') return 'darwin'; - return platform; + let platform: string; + if (isTauri) { + const { os } = require("@tauri-apps/api"); + platform = await os.platform(); + } else { + platform = await (await fetch(GET_PLATFORM_ENDPOINT, { method: "GET" })).json(); + } + if (platform === "windows") return "win32"; + if (platform === "macos") return "darwin"; + return platform; }; export default OS; export const isWin11 = async (): Promise => { - const ua = await (navigator as any).userAgentData.getHighEntropyValues(['platformVersion']); //eslint-disable-line - //eslint-disable-next-line - if ((navigator as any).userAgentData.platform !== 'Windows') { - return false; - } - return parseInt(ua.platformVersion.split('.')[0]) >= 13; + const ua = await (navigator as any).userAgentData.getHighEntropyValues(["platformVersion"]); //eslint-disable-line + //eslint-disable-next-line + if ((navigator as any).userAgentData.platform !== "Windows") { + return false; + } + return Number.parseInt(ua.platformVersion.split(".")[0]) >= 13; }; diff --git a/src/Service/reveal.ts b/src/Service/reveal.ts index c53be60d..98be9bae 100644 --- a/src/Service/reveal.ts +++ b/src/Service/reveal.ts @@ -1,15 +1,17 @@ -import { invoke } from '@tauri-apps/api'; -import NormalizeSlash from '../Components/Functions/path/normalizeSlash'; +import { invoke } from "@tauri-apps/api"; +import NormalizeSlash from "../Components/Functions/path/normalizeSlash"; /** * Open file/dir in a specified application * @returns {any} */ const reveal = async (path: string, app: string): Promise => { - switch (app) { - case 'vscode': - return await invoke('open_in_vscode', { path }); - case 'terminal': - return await invoke('open_in_terminal', { folderPath: NormalizeSlash(path) }); - } + switch (app) { + case "vscode": + return await invoke("open_in_vscode", { path }); + case "terminal": + return await invoke("open_in_terminal", { + folderPath: NormalizeSlash(path), + }); + } }; export default reveal; diff --git a/src/Service/storage.ts b/src/Service/storage.ts index b2eb7471..c536bac6 100644 --- a/src/Service/storage.ts +++ b/src/Service/storage.ts @@ -1,7 +1,7 @@ +import type IStorageData from "../Typings/storageData"; /* eslint-disable @typescript-eslint/explicit-module-boundary-types */ /* eslint-disable @typescript-eslint/no-explicit-any */ -import isTauri from '../Util/is-tauri'; -import IStorageData from '../Typings/storageData'; +import isTauri from "../Util/is-tauri"; // Store fetched data into variable const data: IStorageData = {}; @@ -12,14 +12,14 @@ const data: IStorageData = {}; * @returns {Promise} */ const set = async (key: string, value: any): Promise => { - if (isTauri) { - data[key] = value; - const { invoke } = require('@tauri-apps/api'); - return await invoke('write_data', { key, value }); - } else { - data[key] = value; - localStorage.setItem(key, JSON.stringify(value)); - } + if (isTauri) { + data[key] = value; + const { invoke } = require("@tauri-apps/api"); + return await invoke("write_data", { key, value }); + } else { + data[key] = value; + localStorage.setItem(key, JSON.stringify(value)); + } }; /** @@ -29,28 +29,28 @@ const set = async (key: string, value: any): Promise => { * @returns {Promise} - Your data */ const get = async (key: string, force?: boolean): Promise => { - interface returnedType { - status: boolean; - data: JSON; - } - if (Object.keys(data).includes(key) && !force) { - return data[key]; - } else { - if (isTauri) { - const { invoke } = require('@tauri-apps/api'); - const returnedData = (await invoke('read_data', { key })) as returnedType; - data[key] = returnedData.data; - return returnedData.status ? returnedData.data : {}; - } else { - const storedData = localStorage.getItem(key); - if (storedData) { - data[key] = JSON.parse(storedData); - return data[key]; - } else { - return {}; - } - } - } + interface returnedType { + status: boolean; + data: JSON; + } + if (Object.keys(data).includes(key) && !force) { + return data[key]; + } else { + if (isTauri) { + const { invoke } = require("@tauri-apps/api"); + const returnedData = (await invoke("read_data", { key })) as returnedType; + data[key] = returnedData.data; + return returnedData.status ? returnedData.data : {}; + } else { + const storedData = localStorage.getItem(key); + if (storedData) { + data[key] = JSON.parse(storedData); + return data[key]; + } else { + return {}; + } + } + } }; /** @@ -59,12 +59,12 @@ const get = async (key: string, force?: boolean): Promise => { * @returns {any} */ const remove = async (key: string): Promise => { - if (isTauri) { - const { invoke } = require('@tauri-apps/api'); - await invoke('delete_storage_data', { key }); - } else { - localStorage.removeItem(key); - } + if (isTauri) { + const { invoke } = require("@tauri-apps/api"); + await invoke("delete_storage_data", { key }); + } else { + localStorage.removeItem(key); + } }; export default { get, set, remove }; diff --git a/src/Service/trash.ts b/src/Service/trash.ts index d78e0c13..194cdb64 100644 --- a/src/Service/trash.ts +++ b/src/Service/trash.ts @@ -1,14 +1,14 @@ -import { invoke } from '@tauri-apps/api'; -import FileMetaData from '../Typings/fileMetaData'; +import { invoke } from "@tauri-apps/api"; +import type FileMetaData from "../Typings/fileMetaData"; interface TrashData { - files: FileMetaData[]; + files: FileMetaData[]; } interface ReturnInformation { - status: boolean; - message: string; - request_confirmation: boolean; + status: boolean; + message: string; + request_confirmation: boolean; } /** * Get list of files in trash @@ -16,9 +16,9 @@ interface ReturnInformation { * @returns {Promise} */ const getTrashedFiles = (): Promise => { - return new Promise((resolve) => { - invoke('get_trashed_items').then((result) => resolve(result as TrashData)); - }); + return new Promise((resolve) => { + invoke("get_trashed_items").then((result) => resolve(result as TrashData)); + }); }; /** @@ -27,9 +27,9 @@ const getTrashedFiles = (): Promise => { * @returns {Promise} */ const DeleteFiles = (paths: string[]): Promise => { - return new Promise((resolve) => { - invoke('delete_file', { paths }).then(() => resolve()); - }); + return new Promise((resolve) => { + invoke("delete_file", { paths }).then(() => resolve()); + }); }; /** @@ -39,9 +39,9 @@ const DeleteFiles = (paths: string[]): Promise => { * @returns {Promise} - Promise that resolves when files are restored */ const RestoreFiles = async (paths: string[], force = false): Promise => { - return new Promise((resolve) => { - invoke('restore_files', { paths, force }).then((result) => resolve(result as ReturnInformation)); - }); + return new Promise((resolve) => { + invoke("restore_files", { paths, force }).then((result) => resolve(result as ReturnInformation)); + }); }; /** @@ -50,9 +50,9 @@ const RestoreFiles = async (paths: string[], force = false): Promise} */ const PurgeFiles = (paths: string[]): Promise => { - return new Promise((resolve) => { - invoke('purge_trashes', { paths }).then(() => resolve()); - }); + return new Promise((resolve) => { + invoke("purge_trashes", { paths }).then(() => resolve()); + }); }; /** @@ -62,7 +62,10 @@ const PurgeFiles = (paths: string[]): Promise => { * @returns {Promise} */ const RestoreFile = async (original_parent: string, basename: string): Promise => { - return await invoke('restore_trash', { originalParent: original_parent, basename }); + return await invoke("restore_trash", { + originalParent: original_parent, + basename, + }); }; export { getTrashedFiles, DeleteFiles, RestoreFiles, PurgeFiles, RestoreFile }; diff --git a/src/Service/window.ts b/src/Service/window.ts index d0015b47..43dbceca 100644 --- a/src/Service/window.ts +++ b/src/Service/window.ts @@ -1,58 +1,58 @@ -import isTauri from '../Util/is-tauri'; +import isTauri from "../Util/is-tauri"; let windowName: string; if (isTauri) { - const window = require('@tauri-apps/api/window'); - windowName = window.getCurrent().label; + const window = require("@tauri-apps/api/window"); + windowName = window.getCurrent().label; } else windowName = location.pathname; const listenWindowClose = (): Promise => { - if (isTauri) { - const { event } = require('@tauri-apps/api'); - return new Promise((resolve) => { - event.listen('tauri://close-requested', () => { - const { appWindow } = require('@tauri-apps/api/window'); - resolve(); - appWindow.close(); - }); - }); - } else { - return new Promise((resolve) => { - window.addEventListener('beforeunload', () => { - resolve(); - }); - }); - } + if (isTauri) { + const { event } = require("@tauri-apps/api"); + return new Promise((resolve) => { + event.listen("tauri://close-requested", () => { + const { appWindow } = require("@tauri-apps/api/window"); + resolve(); + appWindow.close(); + }); + }); + } else { + return new Promise((resolve) => { + window.addEventListener("beforeunload", () => { + resolve(); + }); + }); + } }; const createNewWindow = (): void => { - if (isTauri) { - const { WebviewWindow } = require('@tauri-apps/api/window'); - new WebviewWindow(Math.random().toString(), { - decorations: false, - transparent: true, - title: 'Xplorer', - }); - } + if (isTauri) { + const { WebviewWindow } = require("@tauri-apps/api/window"); + new WebviewWindow(Math.random().toString(), { + decorations: false, + transparent: true, + title: "Xplorer", + }); + } }; const changeWindowTitle = (title: string): void => { - if (isTauri) { - const { window } = require('@tauri-apps/api'); - window.getCurrent().setTitle(`${title} - Xplorer`); - } else document.title = `${title} - Xplorer`; + if (isTauri) { + const { window } = require("@tauri-apps/api"); + window.getCurrent().setTitle(`${title} - Xplorer`); + } else document.title = `${title} - Xplorer`; }; const setDecorations = (decorations: boolean): void => { - if (isTauri) { - const { window } = require('@tauri-apps/api'); - window.getCurrent().setDecorations(decorations); - } + if (isTauri) { + const { window } = require("@tauri-apps/api"); + window.getCurrent().setDecorations(decorations); + } }; const listenUpdateTheme = (cb: () => void): void => { - if (isTauri) { - const { event } = require('@tauri-apps/api'); - event.listen('update_theme', () => cb()); - } + if (isTauri) { + const { event } = require("@tauri-apps/api"); + event.listen("update_theme", () => cb()); + } }; export default windowName; diff --git a/src/Services/AppService.ts b/src/Services/AppService.ts index 5e488104..6b3d666a 100644 --- a/src/Services/AppService.ts +++ b/src/Services/AppService.ts @@ -1,4 +1,4 @@ -import { invoke } from '@tauri-apps/api/core'; +import { invoke } from "@tauri-apps/api/core"; -export const fetchVSCodeInstalled = async (): Promise => invoke('check_vscode_installed'); -export const fetchAvailableFonts = async (): Promise => invoke('get_available_fonts'); +export const fetchVSCodeInstalled = async (): Promise => invoke("check_vscode_installed"); +export const fetchAvailableFonts = async (): Promise => invoke("get_available_fonts"); diff --git a/src/Services/CliService.ts b/src/Services/CliService.ts index dea34545..08b5252d 100644 --- a/src/Services/CliService.ts +++ b/src/Services/CliService.ts @@ -1,4 +1,4 @@ -import { invoke } from '@tauri-apps/api/core'; -import { ICliArguments } from '../Typings/Store/cli'; +import { invoke } from "@tauri-apps/api/core"; +import type { ICliArguments } from "../Typings/Store/cli"; -export const fetchCliInformation = async (): Promise => await invoke('get_cli_args'); \ No newline at end of file +export const fetchCliInformation = async (): Promise => await invoke("get_cli_args"); diff --git a/src/Services/ClipboardService.ts b/src/Services/ClipboardService.ts index 8ba917fd..cadd9565 100644 --- a/src/Services/ClipboardService.ts +++ b/src/Services/ClipboardService.ts @@ -1,4 +1,4 @@ -import { writeText, readText } from "@tauri-apps/plugin-clipboard-manager"; +import { readText, writeText } from "@tauri-apps/plugin-clipboard-manager"; /** * Write text into clipboard diff --git a/src/Services/DirectoryService.ts b/src/Services/DirectoryService.ts index 1a0ddf6d..da30ec0c 100644 --- a/src/Services/DirectoryService.ts +++ b/src/Services/DirectoryService.ts @@ -1,10 +1,10 @@ import { invoke } from "@tauri-apps/api/core"; -import { UnlistenFn } from "@tauri-apps/api/event"; +import type { UnlistenFn } from "@tauri-apps/api/event"; import { getCurrent } from "@tauri-apps/api/window"; -import FileMetaData from "../Typings/fileMetaData"; -import { IDirectoryMeta } from "../Typings/Store/directory"; import { fetchFilesRequest } from "../Store/ActionCreators/DirectoryActionCreators"; +import type { IDirectoryMeta } from "../Typings/Store/directory"; +import type FileMetaData from "../Typings/fileMetaData"; /** * Get files inside a directory diff --git a/src/Services/DrivesService.ts b/src/Services/DrivesService.ts index bef12a26..f831a0af 100644 --- a/src/Services/DrivesService.ts +++ b/src/Services/DrivesService.ts @@ -1,5 +1,5 @@ import { invoke } from "@tauri-apps/api/core"; -import { IDrive, IUniqueDrive } from "../Typings/Store/drive"; +import type { IDrive, IUniqueDrive } from "../Typings/Store/drive"; /** * List all user's drives diff --git a/src/Services/FavoritesService.ts b/src/Services/FavoritesService.ts index cb692c5d..c104dc0e 100644 --- a/src/Services/FavoritesService.ts +++ b/src/Services/FavoritesService.ts @@ -1,6 +1,6 @@ import { path } from "@tauri-apps/api"; -import { IFavorites } from "../Typings/Store/favorites"; +import type { IFavorites } from "../Typings/Store/favorites"; export const fetchFavorites = async (): Promise => ({ Documents: await path.documentDir(), diff --git a/src/Services/FilesService.ts b/src/Services/FilesService.ts index f30243af..c33c4154 100644 --- a/src/Services/FilesService.ts +++ b/src/Services/FilesService.ts @@ -1,10 +1,10 @@ +import { Buffer } from "buffer"; import { invoke } from "@tauri-apps/api/core"; -import { copyFile as copyFileNative, rename as renameFileNative, remove as removeNative, readTextFile } from "@tauri-apps/plugin-fs"; import { convertFileSrc } from "@tauri-apps/api/core"; -import { Buffer } from "buffer"; +import { copyFile as copyFileNative, readTextFile, remove as removeNative, rename as renameFileNative } from "@tauri-apps/plugin-fs"; -import FileMetaData from "../Typings/fileMetaData"; -import { TrashData, FileTrashMeta } from "../Typings/Store/files"; +import type { FileTrashMeta, TrashData } from "../Typings/Store/files"; +import type FileMetaData from "../Typings/fileMetaData"; /** * Read text file diff --git a/src/Services/LocaleService.ts b/src/Services/LocaleService.ts index b46c9b13..402a7de9 100644 --- a/src/Services/LocaleService.ts +++ b/src/Services/LocaleService.ts @@ -1,15 +1,18 @@ -import localesJSON from '../Locales/index.json'; +import localesJSON from "../Locales/index.json"; -import { ILocales, IAvailableLocales } from '../Typings/Store/locales'; +import type { IAvailableLocales, ILocales } from "../Typings/Store/locales"; -export const fetchLocales = async (): Promise<{ locales: ILocales, availableLocales: IAvailableLocales }> => { - const availableLocales: IAvailableLocales = localesJSON.availableLanguages; - const locales: ILocales = {}; +export const fetchLocales = async (): Promise<{ + locales: ILocales; + availableLocales: IAvailableLocales; +}> => { + const availableLocales: IAvailableLocales = localesJSON.availableLanguages; + const locales: ILocales = {}; - for (const localeName of Object.values(availableLocales)) { - const localeJSON = await import(`../Locales/${localeName === 'en-US' ? 'base' : localeName}.json`); - locales[localeName] = localeJSON; - } + for (const localeName of Object.values(availableLocales)) { + const localeJSON = await import(`../Locales/${localeName === "en-US" ? "base" : localeName}.json`); + locales[localeName] = localeJSON; + } - return ({ locales, availableLocales }); + return { locales, availableLocales }; }; diff --git a/src/Store/ActionCreators/AppActionCreators.ts b/src/Store/ActionCreators/AppActionCreators.ts index 346aec2d..522b2aca 100644 --- a/src/Store/ActionCreators/AppActionCreators.ts +++ b/src/Store/ActionCreators/AppActionCreators.ts @@ -1,39 +1,42 @@ -import { - FetchVSCodeInstalledRequest, FetchVSCodeInstalledSuccess, FetchVSCodeInstalledFailure, - FetchAvailableFontsRequest, FetchAvailableFontsSuccess, FetchAvailableFontsFailure +import type { + FetchAvailableFontsFailure, + FetchAvailableFontsRequest, + FetchAvailableFontsSuccess, + FetchVSCodeInstalledFailure, + FetchVSCodeInstalledRequest, + FetchVSCodeInstalledSuccess, } from "../../Typings/Store/app"; export const fetchVSCodeInstalledRequest = (): FetchVSCodeInstalledRequest => ({ - type: 'FETCH_VSCODE_INSTALLED', - status: 'REQUEST' + type: "FETCH_VSCODE_INSTALLED", + status: "REQUEST", }); export const fetchVSCodeInstalledSuccess = (vscodeInstalled: boolean): FetchVSCodeInstalledSuccess => ({ - type: 'FETCH_VSCODE_INSTALLED', - status: 'SUCCESS', - vscodeInstalled + type: "FETCH_VSCODE_INSTALLED", + status: "SUCCESS", + vscodeInstalled, }); export const fetchVSCodeInstalledFailure = (message: string): FetchVSCodeInstalledFailure => ({ - type: 'FETCH_VSCODE_INSTALLED', - status: 'FAILURE', - message + type: "FETCH_VSCODE_INSTALLED", + status: "FAILURE", + message, }); export const fetchAvailableFontsRequest = (): FetchAvailableFontsRequest => ({ - type: 'FETCH_AVAILABLE_FONTS', - status: 'REQUEST' + type: "FETCH_AVAILABLE_FONTS", + status: "REQUEST", }); export const fetchAvailableFontsSuccess = (fonts: string[]): FetchAvailableFontsSuccess => ({ - type: 'FETCH_AVAILABLE_FONTS', - status: 'SUCCESS', - fonts + type: "FETCH_AVAILABLE_FONTS", + status: "SUCCESS", + fonts, }); export const fetchAvailableFontsFailure = (message: string): FetchAvailableFontsFailure => ({ - type: 'FETCH_AVAILABLE_FONTS', - status: 'FAILURE', - message + type: "FETCH_AVAILABLE_FONTS", + status: "FAILURE", + message, }); - diff --git a/src/Store/ActionCreators/CliActionCreators.ts b/src/Store/ActionCreators/CliActionCreators.ts index bd8a2f03..410e134d 100644 --- a/src/Store/ActionCreators/CliActionCreators.ts +++ b/src/Store/ActionCreators/CliActionCreators.ts @@ -1,21 +1,18 @@ -import { - ICliArguments, - FetchCliInformationRequest, FetchCliInformationSuccess, FetchCliInformationFailure -} from "../../Typings/Store/cli"; +import type { FetchCliInformationFailure, FetchCliInformationRequest, FetchCliInformationSuccess, ICliArguments } from "../../Typings/Store/cli"; export const fetchCliInformationRequest = (): FetchCliInformationRequest => ({ - type: 'FETCH_CLI_INFORMATION', - status: 'REQUEST' + type: "FETCH_CLI_INFORMATION", + status: "REQUEST", }); export const fetchCliInformationSuccess = (cliArguments: ICliArguments): FetchCliInformationSuccess => ({ - type: 'FETCH_CLI_INFORMATION', - status: 'SUCCESS', - cliArguments + type: "FETCH_CLI_INFORMATION", + status: "SUCCESS", + cliArguments, }); export const fetchCliInformationFailure = (message: string): FetchCliInformationFailure => ({ - type: 'FETCH_CLI_INFORMATION', - status: 'FAILURE', - message + type: "FETCH_CLI_INFORMATION", + status: "FAILURE", + message, }); diff --git a/src/Store/ActionCreators/ClipboardActionCreators.ts b/src/Store/ActionCreators/ClipboardActionCreators.ts index d123f4a1..b0dc4817 100644 --- a/src/Store/ActionCreators/ClipboardActionCreators.ts +++ b/src/Store/ActionCreators/ClipboardActionCreators.ts @@ -1,39 +1,43 @@ -import { - ReadFromClipboardFailure, ReadFromClipboardRequest, ReadFromClipboardSuccess, - WriteToClipboardFailure, WriteToClipboardRequest, WriteToClipboardSuccess +import type { + ReadFromClipboardFailure, + ReadFromClipboardRequest, + ReadFromClipboardSuccess, + WriteToClipboardFailure, + WriteToClipboardRequest, + WriteToClipboardSuccess, } from "../../Typings/Store/clipboard"; export const writeToClipboardRequest = (text: string): WriteToClipboardRequest => ({ - type: 'WRITE_TO_CLIPBOARD', - status: 'REQUEST', - text + type: "WRITE_TO_CLIPBOARD", + status: "REQUEST", + text, }); export const writeToClipboardSuccess = (text: string): WriteToClipboardSuccess => ({ - type: 'WRITE_TO_CLIPBOARD', - status: 'SUCCESS', - text + type: "WRITE_TO_CLIPBOARD", + status: "SUCCESS", + text, }); export const writeToClipboardFailure = (message: string): WriteToClipboardFailure => ({ - type: 'WRITE_TO_CLIPBOARD', - status: 'FAILURE', - message + type: "WRITE_TO_CLIPBOARD", + status: "FAILURE", + message, }); export const readFromClipboardRequest = (): ReadFromClipboardRequest => ({ - type: 'READ_FROM_CLIPBOARD', - status: 'REQUEST' + type: "READ_FROM_CLIPBOARD", + status: "REQUEST", }); export const readFromClipboardSuccess = (text: string): ReadFromClipboardSuccess => ({ - type: 'READ_FROM_CLIPBOARD', - status: 'SUCCESS', - text + type: "READ_FROM_CLIPBOARD", + status: "SUCCESS", + text, }); export const readFromClipboardFailure = (message: string): ReadFromClipboardFailure => ({ - type: 'READ_FROM_CLIPBOARD', - status: 'FAILURE', - message + type: "READ_FROM_CLIPBOARD", + status: "FAILURE", + message, }); diff --git a/src/Store/ActionCreators/ConfigActionCreators.ts b/src/Store/ActionCreators/ConfigActionCreators.ts index 398545c7..1255aa19 100644 --- a/src/Store/ActionCreators/ConfigActionCreators.ts +++ b/src/Store/ActionCreators/ConfigActionCreators.ts @@ -1,7 +1,7 @@ -import { IConfigReducerState, UpdateConfigSuccess } from "../../Typings/Store/config"; +import type { IConfigReducerState, UpdateConfigSuccess } from "../../Typings/Store/config"; export const updateConfig = (updates: Partial): UpdateConfigSuccess => ({ - type: 'UPDATE_CONFIG', - status: 'SUCCESS', - updates + type: "UPDATE_CONFIG", + status: "SUCCESS", + updates, }); diff --git a/src/Store/ActionCreators/DirectoryActionCreators.ts b/src/Store/ActionCreators/DirectoryActionCreators.ts index d3594b78..1025556a 100644 --- a/src/Store/ActionCreators/DirectoryActionCreators.ts +++ b/src/Store/ActionCreators/DirectoryActionCreators.ts @@ -1,22 +1,24 @@ -import { UnlistenFn } from "@tauri-apps/api/event"; +import type { UnlistenFn } from "@tauri-apps/api/event"; -import { - IDirectoryMeta, +import type { CancelDirectorySearchFailure, CancelDirectorySearchRequest, CancelDirectorySearchSuccess, + DirectorySearchPartialResultFailure, + DirectorySearchPartialResultSuccess, FetchDirectorySizeFailure, FetchDirectorySizeRequest, FetchDirectorySizeSuccess, + FetchFileExistsFailure, + FetchFileExistsRequest, + FetchFileExistsSuccess, FetchFilesFailure, FetchFilesRequest, FetchFilesSuccess, FetchIsDirectoryFailure, FetchIsDirectoryRequest, FetchIsDirectorySuccess, - FetchFileExistsFailure, - FetchFileExistsRequest, - FetchFileExistsSuccess, + IDirectoryMeta, InitDirectorySearchFailure, InitDirectorySearchRequest, InitDirectorySearchSuccess, @@ -26,19 +28,17 @@ import { MakeDirectoryFailure, MakeDirectoryRequest, MakeDirectorySuccess, + PopHistorySuccess, + PushHistorySuccess, UnlistenDirectoryFailure, UnlistenDirectoryRequest, UnlistenDirectorySuccess, - DirectorySearchPartialResultSuccess, - DirectorySearchPartialResultFailure, - PushHistorySuccess, - PopHistorySuccess, - UpdateHistoryIdxSuccess, - UpdateHistoryIdxRequest, UpdateHistoryIdxFailure, + UpdateHistoryIdxRequest, + UpdateHistoryIdxSuccess, } from "../../Typings/Store/directory"; -import FileMetaData from "../../Typings/fileMetaData"; +import type FileMetaData from "../../Typings/fileMetaData"; export const fetchFilesRequest = (dirName: string, pushToHistory = true): FetchFilesRequest => ({ type: "FETCH_FILES", diff --git a/src/Store/ActionCreators/DriveActionCreators.ts b/src/Store/ActionCreators/DriveActionCreators.ts index ed4a07f0..5c52d1e8 100644 --- a/src/Store/ActionCreators/DriveActionCreators.ts +++ b/src/Store/ActionCreators/DriveActionCreators.ts @@ -1,21 +1,18 @@ -import { - IDrive, - FetchDrivesFailure, FetchDrivesRequest, FetchDrivesSuccess -} from "../../Typings/Store/drive"; +import type { FetchDrivesFailure, FetchDrivesRequest, FetchDrivesSuccess, IDrive } from "../../Typings/Store/drive"; export const fetchDrivesRequest = (): FetchDrivesRequest => ({ - type: 'FETCH_DRIVES', - status: 'REQUEST' + type: "FETCH_DRIVES", + status: "REQUEST", }); export const fetchDrivesSuccess = (drives: IDrive[]): FetchDrivesSuccess => ({ - type: 'FETCH_DRIVES', - status: 'SUCCESS', - drives + type: "FETCH_DRIVES", + status: "SUCCESS", + drives, }); export const fetchDrivesFailure = (message: string): FetchDrivesFailure => ({ - type: 'FETCH_DRIVES', - status: 'FAILURE', - message + type: "FETCH_DRIVES", + status: "FAILURE", + message, }); diff --git a/src/Store/ActionCreators/FavoritesActionCreators.ts b/src/Store/ActionCreators/FavoritesActionCreators.ts index 50b4ab1e..ef979330 100644 --- a/src/Store/ActionCreators/FavoritesActionCreators.ts +++ b/src/Store/ActionCreators/FavoritesActionCreators.ts @@ -1,21 +1,18 @@ -import { - IFavorites, - FetchFavoritesRequest, FetchFavoritesSuccess, FetchFavoritesFailure -} from "../../Typings/Store/favorites"; +import type { FetchFavoritesFailure, FetchFavoritesRequest, FetchFavoritesSuccess, IFavorites } from "../../Typings/Store/favorites"; export const fetchFavoritesRequest = (): FetchFavoritesRequest => ({ - type: 'FETCH_FAVORITES', - status: 'REQUEST' + type: "FETCH_FAVORITES", + status: "REQUEST", }); export const fetchFavoritesSuccess = (favorites: IFavorites): FetchFavoritesSuccess => ({ - type: 'FETCH_FAVORITES', - status: 'SUCCESS', - favorites + type: "FETCH_FAVORITES", + status: "SUCCESS", + favorites, }); export const fetchFavoritesFailure = (message: string): FetchFavoritesFailure => ({ - type: 'FETCH_FAVORITES', - status: 'FAILURE', - message + type: "FETCH_FAVORITES", + status: "FAILURE", + message, }); diff --git a/src/Store/ActionCreators/FilesActionCreators.ts b/src/Store/ActionCreators/FilesActionCreators.ts index 111a9197..bcfb4702 100644 --- a/src/Store/ActionCreators/FilesActionCreators.ts +++ b/src/Store/ActionCreators/FilesActionCreators.ts @@ -1,4 +1,4 @@ -import FileMetaData from "../../Typings/fileMetaData"; +import type FileMetaData from "../../Typings/fileMetaData"; import { FileTrashMeta, diff --git a/src/Store/ActionCreators/LocalesActionCreators.ts b/src/Store/ActionCreators/LocalesActionCreators.ts index 682b579e..b2624310 100644 --- a/src/Store/ActionCreators/LocalesActionCreators.ts +++ b/src/Store/ActionCreators/LocalesActionCreators.ts @@ -1,22 +1,19 @@ -import { - IAvailableLocales, ILocales, - FetchLocalesFailure, FetchLocalesRequest, FetchLocalesSuccess -} from "../../Typings/Store/locales"; +import type { FetchLocalesFailure, FetchLocalesRequest, FetchLocalesSuccess, IAvailableLocales, ILocales } from "../../Typings/Store/locales"; export const fetchLocalesRequest = (): FetchLocalesRequest => ({ - type: 'FETCH_LOCALES', - status: 'REQUEST' + type: "FETCH_LOCALES", + status: "REQUEST", }); export const fetchLocalesSuccess = (locales: ILocales, availableLocales: IAvailableLocales): FetchLocalesSuccess => ({ - type: 'FETCH_LOCALES', - status: 'SUCCESS', - locales, - availableLocales + type: "FETCH_LOCALES", + status: "SUCCESS", + locales, + availableLocales, }); export const fetchLocalesFailure = (message: string): FetchLocalesFailure => ({ - type: 'FETCH_LOCALES', - status: 'FAILURE', - message + type: "FETCH_LOCALES", + status: "FAILURE", + message, }); diff --git a/src/Store/ActionCreators/PlatformActionCreators.ts b/src/Store/ActionCreators/PlatformActionCreators.ts index a09ea714..8ca2d26d 100644 --- a/src/Store/ActionCreators/PlatformActionCreators.ts +++ b/src/Store/ActionCreators/PlatformActionCreators.ts @@ -1,20 +1,18 @@ -import { - GetOSFailure, GetOSRequest, GetOSSuccess -} from "../../Typings/Store/platform"; +import type { GetOSFailure, GetOSRequest, GetOSSuccess } from "../../Typings/Store/platform"; export const getOSRequest = (): GetOSRequest => ({ - type: 'GET_OS', - status: 'REQUEST' + type: "GET_OS", + status: "REQUEST", }); export const getOSSuccess = (os: string): GetOSSuccess => ({ - type: 'GET_OS', - status: 'SUCCESS', - os + type: "GET_OS", + status: "SUCCESS", + os, }); export const getOSFailure = (message: string): GetOSFailure => ({ - type: 'GET_OS', - status: 'FAILURE', - message + type: "GET_OS", + status: "FAILURE", + message, }); diff --git a/src/Store/ActionCreators/SelectionActionCreators.ts b/src/Store/ActionCreators/SelectionActionCreators.ts index 0b59ac1e..d4997874 100644 --- a/src/Store/ActionCreators/SelectionActionCreators.ts +++ b/src/Store/ActionCreators/SelectionActionCreators.ts @@ -1,4 +1,4 @@ -import { ISelectionReducerState, UpdateSelectionSuccess } from "../../Typings/Store/selection"; +import type { ISelectionReducerState, UpdateSelectionSuccess } from "../../Typings/Store/selection"; export const updateSelection = (updates: Partial): UpdateSelectionSuccess => ({ type: "UPDATE_SELECTION", diff --git a/src/Store/ActionCreators/StorageActionCreators.ts b/src/Store/ActionCreators/StorageActionCreators.ts index 27aee774..cba40a9d 100644 --- a/src/Store/ActionCreators/StorageActionCreators.ts +++ b/src/Store/ActionCreators/StorageActionCreators.ts @@ -1,62 +1,68 @@ -import { - ReadDataFailure, ReadDataRequest, ReadDataSuccess, - RemoveDataFailure, RemoveDataRequest, RemoveDataSuccess, - WriteDataFailure, WriteDataRequest, WriteDataSuccess +import type { + ReadDataFailure, + ReadDataRequest, + ReadDataSuccess, + RemoveDataFailure, + RemoveDataRequest, + RemoveDataSuccess, + WriteDataFailure, + WriteDataRequest, + WriteDataSuccess, } from "../../Typings/Store/storage"; // eslint-disable-next-line @typescript-eslint/no-explicit-any export const writeDataRequest = (key: string, data: any): WriteDataRequest => ({ - type: 'WRITE_DATA', - status: 'REQUEST', - key, - data + type: "WRITE_DATA", + status: "REQUEST", + key, + data, }); export const writeDataSuccess = (): WriteDataSuccess => ({ - type: 'WRITE_DATA', - status: 'SUCCESS' + type: "WRITE_DATA", + status: "SUCCESS", }); export const writeDataFailure = (message: string): WriteDataFailure => ({ - type: 'WRITE_DATA', - status: 'FAILURE', - message + type: "WRITE_DATA", + status: "FAILURE", + message, }); export const readDataRequest = (key: string): ReadDataRequest => ({ - type: 'READ_DATA', - status: 'REQUEST', - key + type: "READ_DATA", + status: "REQUEST", + key, }); // eslint-disable-next-line @typescript-eslint/no-explicit-any export const readDataSuccess = (key: string, data: any): ReadDataSuccess => ({ - type: 'READ_DATA', - status: 'SUCCESS', - key, - data + type: "READ_DATA", + status: "SUCCESS", + key, + data, }); export const readDataFailure = (message: string): ReadDataFailure => ({ - type: 'READ_DATA', - status: 'FAILURE', - message + type: "READ_DATA", + status: "FAILURE", + message, }); export const removeDataRequest = (key: string): RemoveDataRequest => ({ - type: 'REMOVE_DATA', - status: 'REQUEST', - key + type: "REMOVE_DATA", + status: "REQUEST", + key, }); export const removeDataSuccess = (key: string): RemoveDataSuccess => ({ - type: 'REMOVE_DATA', - status: 'SUCCESS', - key + type: "REMOVE_DATA", + status: "SUCCESS", + key, }); export const removeDataFailure = (message: string): RemoveDataFailure => ({ - type: 'REMOVE_DATA', - status: 'FAILURE', - message + type: "REMOVE_DATA", + status: "FAILURE", + message, }); diff --git a/src/Store/ActionCreators/TabActionCreators.ts b/src/Store/ActionCreators/TabActionCreators.ts index 91fd4812..351b7468 100644 --- a/src/Store/ActionCreators/TabActionCreators.ts +++ b/src/Store/ActionCreators/TabActionCreators.ts @@ -1,4 +1,4 @@ -import { ITab, CreateTabSuccess, UpdateTabSuccess, DeleteTabSuccess, SetActiveTabSuccess } from "../../Typings/Store/tab"; +import type { CreateTabSuccess, DeleteTabSuccess, ITab, SetActiveTabSuccess, UpdateTabSuccess } from "../../Typings/Store/tab"; export const createTab = (tab: ITab): CreateTabSuccess => ({ type: "CREATE_TAB", diff --git a/src/Store/ActionCreators/WindowActionCreators.ts b/src/Store/ActionCreators/WindowActionCreators.ts index a183e124..398b2bd5 100644 --- a/src/Store/ActionCreators/WindowActionCreators.ts +++ b/src/Store/ActionCreators/WindowActionCreators.ts @@ -1,26 +1,26 @@ -import { WebviewWindow } from "@tauri-apps/api/webviewWindow"; -import { +import type { WebviewWindow } from "@tauri-apps/api/webviewWindow"; +import type { ChangeWindowTitleFailure, ChangeWindowTitleRequest, ChangeWindowTitleSuccess, + CloseWindowFailure, + CloseWindowRequest, + CloseWindowSuccess, CreateNewWindowFailure, CreateNewWindowRequest, CreateNewWindowSuccess, ListenWindowCloseFailure, ListenWindowCloseRequest, ListenWindowCloseSuccess, - SetDecorationsFailure, - SetDecorationsRequest, - SetDecorationsSuccess, + MaximizeWindowFailure, MaximizeWindowRequest, MaximizeWindowSuccess, - MaximizeWindowFailure, + MinimizeWindowFailure, MinimizeWindowRequest, MinimizeWindowSuccess, - MinimizeWindowFailure, - CloseWindowRequest, - CloseWindowSuccess, - CloseWindowFailure, + SetDecorationsFailure, + SetDecorationsRequest, + SetDecorationsSuccess, } from "../../Typings/Store/window"; export const listenWindowCloseRequest = (): ListenWindowCloseRequest => ({ diff --git a/src/Store/Reducers/AppReducer.ts b/src/Store/Reducers/AppReducer.ts index 2479514c..57ed336c 100644 --- a/src/Store/Reducers/AppReducer.ts +++ b/src/Store/Reducers/AppReducer.ts @@ -1,29 +1,28 @@ -import { IAppReducerState } from "../../Typings/Store/app"; -import { Actions } from "../../Typings/Store/store"; +import type { IAppReducerState } from "../../Typings/Store/app"; +import type { Actions } from "../../Typings/Store/store"; const initialState: IAppReducerState = { - vscodeIntstalled: false, - availableFonts: [] + vscodeIntstalled: false, + availableFonts: [], }; - const reducer = (state = initialState, action: Actions): IAppReducerState => { - if (action.status !== 'SUCCESS') return state; + if (action.status !== "SUCCESS") return state; - switch (action.type) { - case 'FETCH_VSCODE_INSTALLED': - return { - ...state, - vscodeIntstalled: action.vscodeInstalled - }; - case 'FETCH_AVAILABLE_FONTS': - return { - ...state, - availableFonts: action.fonts - }; - default: - return state; - } + switch (action.type) { + case "FETCH_VSCODE_INSTALLED": + return { + ...state, + vscodeIntstalled: action.vscodeInstalled, + }; + case "FETCH_AVAILABLE_FONTS": + return { + ...state, + availableFonts: action.fonts, + }; + default: + return state; + } }; export default reducer; diff --git a/src/Store/Reducers/CliReducer.ts b/src/Store/Reducers/CliReducer.ts index 710a5e9f..f7d33608 100644 --- a/src/Store/Reducers/CliReducer.ts +++ b/src/Store/Reducers/CliReducer.ts @@ -1,25 +1,24 @@ -import { ICliReducerState } from "../../Typings/Store/cli"; -import { Actions } from "../../Typings/Store/store"; +import type { ICliReducerState } from "../../Typings/Store/cli"; +import type { Actions } from "../../Typings/Store/store"; const initialState: ICliReducerState = { - args: [], - flags: [] + args: [], + flags: [], }; const reducer = (state = initialState, action: Actions): ICliReducerState => { - if (action.status !== 'SUCCESS') return state; + if (action.status !== "SUCCESS") return state; - switch (action.type) { - case 'FETCH_CLI_INFORMATION': - return { - ...state, - args: action.cliArguments.args, - flags: action.cliArguments.flags - }; - default: - return state; - } + switch (action.type) { + case "FETCH_CLI_INFORMATION": + return { + ...state, + args: action.cliArguments.args, + flags: action.cliArguments.flags, + }; + default: + return state; + } }; export default reducer; - diff --git a/src/Store/Reducers/ClipboardReducer.ts b/src/Store/Reducers/ClipboardReducer.ts index 64ccbdc2..77f79d48 100644 --- a/src/Store/Reducers/ClipboardReducer.ts +++ b/src/Store/Reducers/ClipboardReducer.ts @@ -1,23 +1,23 @@ -import { IClipboardReducerState } from "../../Typings/Store/clipboard"; -import { Actions } from "../../Typings/Store/store"; +import type { IClipboardReducerState } from "../../Typings/Store/clipboard"; +import type { Actions } from "../../Typings/Store/store"; const initialState: IClipboardReducerState = { - text: '' + text: "", }; const reducer = (state = initialState, action: Actions): IClipboardReducerState => { - if (action.status !== 'SUCCESS') return state; + if (action.status !== "SUCCESS") return state; - switch (action.type) { - case 'WRITE_TO_CLIPBOARD': - case 'READ_FROM_CLIPBOARD': - return { - ...state, - text: action.text - }; - default: - return state; - } + switch (action.type) { + case "WRITE_TO_CLIPBOARD": + case "READ_FROM_CLIPBOARD": + return { + ...state, + text: action.text, + }; + default: + return state; + } }; export default reducer; diff --git a/src/Store/Reducers/ConfigReducer.ts b/src/Store/Reducers/ConfigReducer.ts index 49303e20..4e8199a9 100644 --- a/src/Store/Reducers/ConfigReducer.ts +++ b/src/Store/Reducers/ConfigReducer.ts @@ -1,5 +1,5 @@ -import { Actions } from "../../Typings/Store/store"; -import { IConfigReducerState } from "../../Typings/Store/config"; +import type { IConfigReducerState } from "../../Typings/Store/config"; +import type { Actions } from "../../Typings/Store/store"; const initialState: IConfigReducerState = { opacity: 0.5, diff --git a/src/Store/Reducers/DirectoryReducer.ts b/src/Store/Reducers/DirectoryReducer.ts index d1db444b..e8931d25 100644 --- a/src/Store/Reducers/DirectoryReducer.ts +++ b/src/Store/Reducers/DirectoryReducer.ts @@ -1,8 +1,8 @@ -import omit from "lodash.omit"; import dropWhile from "lodash.dropwhile"; +import omit from "lodash.omit"; -import { IDirectoryReducerState } from "../../Typings/Store/directory"; -import { Actions } from "../../Typings/Store/store"; +import type { IDirectoryReducerState } from "../../Typings/Store/directory"; +import type { Actions } from "../../Typings/Store/store"; const MAX_HISTORY_SIZE = 5; diff --git a/src/Store/Reducers/DriveReducer.ts b/src/Store/Reducers/DriveReducer.ts index 0ee2d6b5..2cf43438 100644 --- a/src/Store/Reducers/DriveReducer.ts +++ b/src/Store/Reducers/DriveReducer.ts @@ -1,5 +1,5 @@ -import { IDriveReducerState } from "../../Typings/Store/drive"; -import { Actions } from "../../Typings/Store/store"; +import type { IDriveReducerState } from "../../Typings/Store/drive"; +import type { Actions } from "../../Typings/Store/store"; const initialState: IDriveReducerState = { drives: [], diff --git a/src/Store/Reducers/FavoritesReducer.ts b/src/Store/Reducers/FavoritesReducer.ts index 25bd2dda..604eb313 100644 --- a/src/Store/Reducers/FavoritesReducer.ts +++ b/src/Store/Reducers/FavoritesReducer.ts @@ -1,5 +1,5 @@ -import { IFavoritesReducerState } from "../../Typings/Store/favorites"; -import { Actions } from "../../Typings/Store/store"; +import type { IFavoritesReducerState } from "../../Typings/Store/favorites"; +import type { Actions } from "../../Typings/Store/store"; const initialState: IFavoritesReducerState = { Documents: null, @@ -11,10 +11,7 @@ const initialState: IFavoritesReducerState = { Home: null, }; -const reducer = ( - state = initialState, - action: Actions -): IFavoritesReducerState => { +const reducer = (state = initialState, action: Actions): IFavoritesReducerState => { if (action.status !== "SUCCESS") return state; switch (action.type) { diff --git a/src/Store/Reducers/FilesReducer.ts b/src/Store/Reducers/FilesReducer.ts index c236c4be..b3a51d7c 100644 --- a/src/Store/Reducers/FilesReducer.ts +++ b/src/Store/Reducers/FilesReducer.ts @@ -1,8 +1,8 @@ import omit from "lodash.omit"; import omitBy from "lodash.omitby"; -import { IFilesReducerState } from "../../Typings/Store/files"; -import { Actions } from "../../Typings/Store/store"; +import type { IFilesReducerState } from "../../Typings/Store/files"; +import type { Actions } from "../../Typings/Store/store"; const initialState: IFilesReducerState = { buffers: {}, diff --git a/src/Store/Reducers/LocalesReducer.ts b/src/Store/Reducers/LocalesReducer.ts index 9e8c179d..513f162c 100644 --- a/src/Store/Reducers/LocalesReducer.ts +++ b/src/Store/Reducers/LocalesReducer.ts @@ -1,24 +1,24 @@ -import { ILocalesReducerState } from "../../Typings/Store/locales"; -import { Actions } from "../../Typings/Store/store"; +import type { ILocalesReducerState } from "../../Typings/Store/locales"; +import type { Actions } from "../../Typings/Store/store"; const initialState: ILocalesReducerState = { - locales: {}, - availableLocales: {} + locales: {}, + availableLocales: {}, }; const reducer = (state = initialState, action: Actions): ILocalesReducerState => { - if (action.status !== 'SUCCESS') return state; + if (action.status !== "SUCCESS") return state; - switch (action.type) { - case 'FETCH_LOCALES': - return { - ...state, - locales: action.locales, - availableLocales: action.availableLocales - }; - default: - return state; - } + switch (action.type) { + case "FETCH_LOCALES": + return { + ...state, + locales: action.locales, + availableLocales: action.availableLocales, + }; + default: + return state; + } }; export default reducer; diff --git a/src/Store/Reducers/PlatformReducer.ts b/src/Store/Reducers/PlatformReducer.ts index 37640134..a2622464 100644 --- a/src/Store/Reducers/PlatformReducer.ts +++ b/src/Store/Reducers/PlatformReducer.ts @@ -1,22 +1,22 @@ -import { IPlatformReducerState } from "../../Typings/Store/platform"; -import { Actions } from "../../Typings/Store/store"; +import type { IPlatformReducerState } from "../../Typings/Store/platform"; +import type { Actions } from "../../Typings/Store/store"; const initialState: IPlatformReducerState = { - os: null + os: null, }; const reducer = (state = initialState, action: Actions): IPlatformReducerState => { - if (action.status !== 'SUCCESS') return state; + if (action.status !== "SUCCESS") return state; - switch (action.type) { - case 'GET_OS': - return { - ...state, - os: action.os - }; - default: - return state; - } + switch (action.type) { + case "GET_OS": + return { + ...state, + os: action.os, + }; + default: + return state; + } }; export default reducer; diff --git a/src/Store/Reducers/RequestReducer.ts b/src/Store/Reducers/RequestReducer.ts index 4fdb75cc..2808d0e5 100644 --- a/src/Store/Reducers/RequestReducer.ts +++ b/src/Store/Reducers/RequestReducer.ts @@ -1,5 +1,5 @@ -import { IRequestReducerState } from "../../Typings/Store/request"; -import { Actions } from "../../Typings/Store/store"; +import type { IRequestReducerState } from "../../Typings/Store/request"; +import type { Actions } from "../../Typings/Store/store"; const initialState: IRequestReducerState = {}; diff --git a/src/Store/Reducers/SelectionReducer.ts b/src/Store/Reducers/SelectionReducer.ts index 40791be4..46a4477f 100644 --- a/src/Store/Reducers/SelectionReducer.ts +++ b/src/Store/Reducers/SelectionReducer.ts @@ -1,5 +1,5 @@ -import { Actions } from "../../Typings/Store/store"; -import { ISelectionReducerState } from "../../Typings/Store/selection"; +import type { ISelectionReducerState } from "../../Typings/Store/selection"; +import type { Actions } from "../../Typings/Store/store"; const initialState: ISelectionReducerState = { selected: [], diff --git a/src/Store/Reducers/StorageReducer.ts b/src/Store/Reducers/StorageReducer.ts index 6f7d1228..9cc285a6 100644 --- a/src/Store/Reducers/StorageReducer.ts +++ b/src/Store/Reducers/StorageReducer.ts @@ -1,37 +1,37 @@ -import omit from 'lodash.omit'; +import omit from "lodash.omit"; -import { IStorageReducerState } from "../../Typings/Store/storage"; -import { Actions } from "../../Typings/Store/store"; +import type { IStorageReducerState } from "../../Typings/Store/storage"; +import type { Actions } from "../../Typings/Store/store"; const initialState: IStorageReducerState = { - store: {} + store: {}, }; const reducer = (state = initialState, action: Actions): IStorageReducerState => { - if (action.status !== 'SUCCESS') return state; + if (action.status !== "SUCCESS") return state; - switch (action.type) { - // * Don't need to handle - // case 'WRITE_DATA': - // return { - // ...state - // }; - case 'READ_DATA': - return { - ...state, - store: { - ...state.store, - [action.key]: action.data - } - }; - case 'REMOVE_DATA': - return { - ...state, - store: omit(state.store, action.key) - }; - default: - return state; - } + switch (action.type) { + // * Don't need to handle + // case 'WRITE_DATA': + // return { + // ...state + // }; + case "READ_DATA": + return { + ...state, + store: { + ...state.store, + [action.key]: action.data, + }, + }; + case "REMOVE_DATA": + return { + ...state, + store: omit(state.store, action.key), + }; + default: + return state; + } }; export default reducer; diff --git a/src/Store/Reducers/TabReducer.ts b/src/Store/Reducers/TabReducer.ts index d2dfb9a1..49e79b2d 100644 --- a/src/Store/Reducers/TabReducer.ts +++ b/src/Store/Reducers/TabReducer.ts @@ -1,7 +1,7 @@ import omit from "lodash.omit"; -import { ITab, ITabReducerState } from "../../Typings/Store/tab"; -import { Actions } from "../../Typings/Store/store"; +import type { Actions } from "../../Typings/Store/store"; +import type { ITab, ITabReducerState } from "../../Typings/Store/tab"; const defaultTab: ITab = { name: "Default Tab", diff --git a/src/Store/Reducers/WindowReducer.ts b/src/Store/Reducers/WindowReducer.ts index bd188b2a..b147d551 100644 --- a/src/Store/Reducers/WindowReducer.ts +++ b/src/Store/Reducers/WindowReducer.ts @@ -1,45 +1,45 @@ -import omit from 'lodash.omit'; +import omit from "lodash.omit"; -import { Actions } from "../../Typings/Store/store"; -import { IWindowReducerState } from "../../Typings/Store/window"; +import type { Actions } from "../../Typings/Store/store"; +import type { IWindowReducerState } from "../../Typings/Store/window"; const initialState: IWindowReducerState = { - windows: {} + windows: {}, }; const reducer = (state = initialState, action: Actions): IWindowReducerState => { - if (action.status !== 'SUCCESS') return state; + if (action.status !== "SUCCESS") return state; - switch (action.type) { - // * Don't need to handle - // case 'LISTEN_WINDOW_CLOSE': - // return { - // ...state - // }; - case 'CREATE_WINDOW': - return { - ...state, - windows: { - ...state.windows, - [action.title]: action.window - } - }; - case 'CHANGE_WINDOW_TITLE': - return { - ...state, - windows: { - ...omit(state.windows, action.title), - [action.dest]: state.windows?.[action.title] || null - } - }; - // * Don't need to handle - // case 'SET_DECORATIONS': - // return { - // ...state - // }; - default: - return state; - } + switch (action.type) { + // * Don't need to handle + // case 'LISTEN_WINDOW_CLOSE': + // return { + // ...state + // }; + case "CREATE_WINDOW": + return { + ...state, + windows: { + ...state.windows, + [action.title]: action.window, + }, + }; + case "CHANGE_WINDOW_TITLE": + return { + ...state, + windows: { + ...omit(state.windows, action.title), + [action.dest]: state.windows?.[action.title] || null, + }, + }; + // * Don't need to handle + // case 'SET_DECORATIONS': + // return { + // ...state + // }; + default: + return state; + } }; export default reducer; diff --git a/src/Store/Reducers/index.ts b/src/Store/Reducers/index.ts index e2688673..f8c3a1c5 100644 --- a/src/Store/Reducers/index.ts +++ b/src/Store/Reducers/index.ts @@ -1,25 +1,25 @@ import { combineReducers } from "redux"; import { Actions } from "../../Typings/Store/store"; -import { IAppReducerState } from "../../Typings/Store/app"; -import { IClipboardReducerState } from "../../Typings/Store/clipboard"; -import { ICliReducerState } from "../../Typings/Store/cli"; -import { IConfigReducerState } from "../../Typings/Store/config"; -import { IDirectoryReducerState } from "../../Typings/Store/directory"; -import { IDriveReducerState } from "../../Typings/Store/drive"; -import { IFavoritesReducerState } from "../../Typings/Store/favorites"; -import { IFilesReducerState } from "../../Typings/Store/files"; -import { ILocalesReducerState } from "../../Typings/Store/locales"; -import { IPlatformReducerState } from "../../Typings/Store/platform"; -import { IRequestReducerState } from "../../Typings/Store/request"; -import { IStorageReducerState } from "../../Typings/Store/storage"; -import { ITabReducerState } from "../../Typings/Store/tab"; -import { IWindowReducerState } from "../../Typings/Store/window"; -import { ISelectionReducerState } from "../../Typings/Store/selection"; +import type { IAppReducerState } from "../../Typings/Store/app"; +import type { ICliReducerState } from "../../Typings/Store/cli"; +import type { IClipboardReducerState } from "../../Typings/Store/clipboard"; +import type { IConfigReducerState } from "../../Typings/Store/config"; +import type { IDirectoryReducerState } from "../../Typings/Store/directory"; +import type { IDriveReducerState } from "../../Typings/Store/drive"; +import type { IFavoritesReducerState } from "../../Typings/Store/favorites"; +import type { IFilesReducerState } from "../../Typings/Store/files"; +import type { ILocalesReducerState } from "../../Typings/Store/locales"; +import type { IPlatformReducerState } from "../../Typings/Store/platform"; +import type { IRequestReducerState } from "../../Typings/Store/request"; +import type { ISelectionReducerState } from "../../Typings/Store/selection"; +import type { IStorageReducerState } from "../../Typings/Store/storage"; +import type { ITabReducerState } from "../../Typings/Store/tab"; +import type { IWindowReducerState } from "../../Typings/Store/window"; import AppReducer from "./AppReducer"; -import ClipboardReducer from "./ClipboardReducer"; import CliReducer from "./CliReducer"; +import ClipboardReducer from "./ClipboardReducer"; import ConfigReducer from "./ConfigReducer"; import DirectoryReducer from "./DirectoryReducer"; import DriveReducer from "./DriveReducer"; @@ -28,10 +28,10 @@ import FilesReducer from "./FilesReducer"; import LocalesReducer from "./LocalesReducer"; import PlatformReducer from "./PlatformReducer"; import RequestReducer from "./RequestReducer"; +import SelectionReducer from "./SelectionReducer"; import StorageReducer from "./StorageReducer"; import TabReducer from "./TabReducer"; import WindowReducer from "./WindowReducer"; -import SelectionReducer from "./SelectionReducer"; export interface IAppState { app: IAppReducerState; diff --git a/src/Store/Sagas/AppSaga.ts b/src/Store/Sagas/AppSaga.ts index 0691fe81..06984c9b 100644 --- a/src/Store/Sagas/AppSaga.ts +++ b/src/Store/Sagas/AppSaga.ts @@ -1,36 +1,38 @@ import { all, call, takeLatest } from "redux-saga/effects"; import { - fetchAvailableFontsFailure, fetchAvailableFontsSuccess, - fetchVSCodeInstalledFailure, fetchVSCodeInstalledSuccess -} from '../ActionCreators/AppActionCreators'; + fetchAvailableFontsFailure, + fetchAvailableFontsSuccess, + fetchVSCodeInstalledFailure, + fetchVSCodeInstalledSuccess, +} from "../ActionCreators/AppActionCreators"; -import { selectStatus, typedPut as put } from './helpers'; -import * as AppService from '../../Services/AppService'; +import * as AppService from "../../Services/AppService"; +import { typedPut as put, selectStatus } from "./helpers"; function* fetchVSCodeInstalledWorker() { - try { - const isVSCodeInstalled: boolean = yield call(AppService.fetchVSCodeInstalled); - yield put(fetchVSCodeInstalledSuccess(isVSCodeInstalled)); - } catch (error) { - yield put(fetchVSCodeInstalledFailure(error.message)); - } + try { + const isVSCodeInstalled: boolean = yield call(AppService.fetchVSCodeInstalled); + yield put(fetchVSCodeInstalledSuccess(isVSCodeInstalled)); + } catch (error) { + yield put(fetchVSCodeInstalledFailure(error.message)); + } } function* fetchAvailableFontsWorker() { - try { - const availableFonts: string[] = yield call(AppService.fetchAvailableFonts); - yield put(fetchAvailableFontsSuccess(availableFonts)); - } catch (error) { - yield put(fetchAvailableFontsFailure(error.message)) - } + try { + const availableFonts: string[] = yield call(AppService.fetchAvailableFonts); + yield put(fetchAvailableFontsSuccess(availableFonts)); + } catch (error) { + yield put(fetchAvailableFontsFailure(error.message)); + } } function* appSaga() { - yield all([ - takeLatest(selectStatus('FETCH_VSCODE_INSTALLED'), fetchVSCodeInstalledWorker), - takeLatest(selectStatus('FETCH_AVAILABLE_FONTS'), fetchAvailableFontsWorker) - ]); + yield all([ + takeLatest(selectStatus("FETCH_VSCODE_INSTALLED"), fetchVSCodeInstalledWorker), + takeLatest(selectStatus("FETCH_AVAILABLE_FONTS"), fetchAvailableFontsWorker), + ]); } export default appSaga; diff --git a/src/Store/Sagas/CliSaga.ts b/src/Store/Sagas/CliSaga.ts index a5550884..b8301b6b 100644 --- a/src/Store/Sagas/CliSaga.ts +++ b/src/Store/Sagas/CliSaga.ts @@ -2,23 +2,21 @@ import { all, call, takeLatest } from "redux-saga/effects"; import { fetchCliInformationFailure, fetchCliInformationSuccess } from "../ActionCreators/CliActionCreators"; -import { selectStatus, typedPut as put } from "./helpers"; import * as CliService from "../../Services/CliService"; -import { ICliArguments } from "../../Typings/Store/cli"; +import type { ICliArguments } from "../../Typings/Store/cli"; +import { typedPut as put, selectStatus } from "./helpers"; function* fetchCliInformationWorker() { - try { - const cliInformation: ICliArguments = yield call(CliService.fetchCliInformation); - yield put(fetchCliInformationSuccess(cliInformation)); - } catch (error) { - yield put(fetchCliInformationFailure(error.message)); - } + try { + const cliInformation: ICliArguments = yield call(CliService.fetchCliInformation); + yield put(fetchCliInformationSuccess(cliInformation)); + } catch (error) { + yield put(fetchCliInformationFailure(error.message)); + } } function* cliSaga() { - yield all([ - takeLatest(selectStatus('FETCH_CLI_INFORMATION'), fetchCliInformationWorker) - ]); + yield all([takeLatest(selectStatus("FETCH_CLI_INFORMATION"), fetchCliInformationWorker)]); } export default cliSaga; diff --git a/src/Store/Sagas/ClipboardSaga.ts b/src/Store/Sagas/ClipboardSaga.ts index bb706227..f1470349 100644 --- a/src/Store/Sagas/ClipboardSaga.ts +++ b/src/Store/Sagas/ClipboardSaga.ts @@ -1,39 +1,41 @@ import { all, call, takeLatest } from "redux-saga/effects"; import { - readFromClipboardFailure, readFromClipboardSuccess, - writeToClipboardFailure, writeToClipboardSuccess -} from '../ActionCreators/ClipboardActionCreators'; + readFromClipboardFailure, + readFromClipboardSuccess, + writeToClipboardFailure, + writeToClipboardSuccess, +} from "../ActionCreators/ClipboardActionCreators"; -import { WriteToClipboardRequest } from "../../Typings/Store/clipboard"; +import type { WriteToClipboardRequest } from "../../Typings/Store/clipboard"; -import { selectStatus, typedPut as put } from './helpers'; -import * as ClipboardService from '../../Services/ClipboardService'; +import * as ClipboardService from "../../Services/ClipboardService"; +import { typedPut as put, selectStatus } from "./helpers"; function* writeToClipboardWorker(action: WriteToClipboardRequest) { - try { - const { text } = action; - yield call(ClipboardService.writeTextToClipboard, text); - yield put(writeToClipboardSuccess(text)); - } catch (error) { - yield put(writeToClipboardFailure(error.message)); - } + try { + const { text } = action; + yield call(ClipboardService.writeTextToClipboard, text); + yield put(writeToClipboardSuccess(text)); + } catch (error) { + yield put(writeToClipboardFailure(error.message)); + } } function* readFromClipboardWorker(/* action: ReadFromClipboardRequest */) { - try { - const text: string = yield call(ClipboardService.readTextFromClipboard); - yield put(readFromClipboardSuccess(text)); - } catch (error) { - yield put(readFromClipboardFailure(error.message)); - } + try { + const text: string = yield call(ClipboardService.readTextFromClipboard); + yield put(readFromClipboardSuccess(text)); + } catch (error) { + yield put(readFromClipboardFailure(error.message)); + } } function* clipboardSaga() { - yield all([ - takeLatest(selectStatus('WRITE_TO_CLIPBOARD'), writeToClipboardWorker), - takeLatest(selectStatus('READ_FROM_CLIPBOARD'), readFromClipboardWorker) - ]); + yield all([ + takeLatest(selectStatus("WRITE_TO_CLIPBOARD"), writeToClipboardWorker), + takeLatest(selectStatus("READ_FROM_CLIPBOARD"), readFromClipboardWorker), + ]); } export default clipboardSaga; diff --git a/src/Store/Sagas/DirectorySaga.ts b/src/Store/Sagas/DirectorySaga.ts index e01761b3..3d67ef95 100644 --- a/src/Store/Sagas/DirectorySaga.ts +++ b/src/Store/Sagas/DirectorySaga.ts @@ -1,4 +1,4 @@ -import { UnlistenFn } from "@tauri-apps/api/event"; +import type { UnlistenFn } from "@tauri-apps/api/event"; import { getCurrent } from "@tauri-apps/api/window"; import { all, call, takeLatest } from "redux-saga/effects"; @@ -6,8 +6,10 @@ import { cancelDirectorySearchFailure, cancelDirectorySearchRequest, cancelDirectorySearchSuccess, + directorySearchFailure, directorySearchPartialResultFailure, directorySearchPartialResultSuccess, + directorySearchSuccess, fetchDirectorySizeFailure, fetchDirectorySizeSuccess, fetchFileExistsFailure, @@ -16,26 +18,24 @@ import { fetchFilesSuccess, fetchIsDirectoryFailure, fetchIsDirectorySuccess, - directorySearchFailure, - directorySearchSuccess, listenDirectoryFailure, listenDirectorySuccess, makeDirectoryFailure, makeDirectorySuccess, + pushHistory, unlistenDirectoryFailure, unlistenDirectorySuccess, - pushHistory, updateHistoryIdxFailure, updateHistoryIdxSuccess, } from "../ActionCreators/DirectoryActionCreators"; -import { - IDirectoryMeta, +import type { CancelDirectorySearchRequest, FetchDirectorySizeRequest, FetchFileExistsRequest, FetchFilesRequest, FetchIsDirectoryRequest, + IDirectoryMeta, InitDirectorySearchRequest, ListenDirectoryRequest, MakeDirectoryRequest, @@ -43,11 +43,11 @@ import { UpdateHistoryIdxRequest, } from "../../Typings/Store/directory"; -import { selectStatus, typedPut as put, typedSelect as select } from "./helpers"; -import { setActiveTab } from "../ActionCreators/TabActionCreators"; import * as DirectoryService from "../../Services/DirectoryService"; -import FileMetaData from "../../Typings/fileMetaData"; -import { ITab } from "../../Typings/Store/tab"; +import type { ITab } from "../../Typings/Store/tab"; +import type FileMetaData from "../../Typings/fileMetaData"; +import { setActiveTab } from "../ActionCreators/TabActionCreators"; +import { typedPut as put, typedSelect as select, selectStatus } from "./helpers"; function* fetchFilesWorker(action: FetchFilesRequest) { try { diff --git a/src/Store/Sagas/DrivesSaga.ts b/src/Store/Sagas/DrivesSaga.ts index aa3a337c..88eb4dbb 100644 --- a/src/Store/Sagas/DrivesSaga.ts +++ b/src/Store/Sagas/DrivesSaga.ts @@ -3,9 +3,9 @@ import { all, call, takeLatest } from "redux-saga/effects"; import { fetchDrivesFailure, fetchDrivesSuccess } from "../ActionCreators/DriveActionCreators"; import { getOSRequest } from "../ActionCreators/PlatformActionCreators"; -import { selectStatus, typedPut as put, typedSelect as select } from "./helpers"; import * as DrivesService from "../../Services/DrivesService"; -import { IDrive } from "../../Typings/Store/drive"; +import type { IDrive } from "../../Typings/Store/drive"; +import { typedPut as put, typedSelect as select, selectStatus } from "./helpers"; function* fetchDrivesWorker(/* action: FetchDrivesRequest */) { try { diff --git a/src/Store/Sagas/FavoritesSaga.ts b/src/Store/Sagas/FavoritesSaga.ts index 81a4c601..631625e1 100644 --- a/src/Store/Sagas/FavoritesSaga.ts +++ b/src/Store/Sagas/FavoritesSaga.ts @@ -2,23 +2,21 @@ import { all, call, takeLatest } from "redux-saga/effects"; import { fetchFavoritesFailure, fetchFavoritesSuccess } from "../ActionCreators/FavoritesActionCreators"; -import { selectStatus, typedPut as put } from "./helpers"; import * as FavoritesService from "../../Services/FavoritesService"; -import { IFavorites } from "../../Typings/Store/favorites"; +import type { IFavorites } from "../../Typings/Store/favorites"; +import { typedPut as put, selectStatus } from "./helpers"; function* fetchFavoritesWorker() { - try { - const favorites: IFavorites = yield call(FavoritesService.fetchFavorites); - yield put(fetchFavoritesSuccess(favorites)); - } catch (error) { - yield put(fetchFavoritesFailure(error.message)); - } + try { + const favorites: IFavorites = yield call(FavoritesService.fetchFavorites); + yield put(fetchFavoritesSuccess(favorites)); + } catch (error) { + yield put(fetchFavoritesFailure(error.message)); + } } function* favoritesSaga() { - yield all([ - takeLatest(selectStatus('FETCH_FAVORITES'), fetchFavoritesWorker) - ]); + yield all([takeLatest(selectStatus("FETCH_FAVORITES"), fetchFavoritesWorker)]); } export default favoritesSaga; diff --git a/src/Store/Sagas/FilesSaga.ts b/src/Store/Sagas/FilesSaga.ts index 9788527c..9f4262de 100644 --- a/src/Store/Sagas/FilesSaga.ts +++ b/src/Store/Sagas/FilesSaga.ts @@ -9,6 +9,8 @@ import { createFileSuccess, cutFileFailure, cutFileSuccess, + deleteFilesFailure, + deleteFilesSuccess, extractIconFailure, extractIconSuccess, fetchFilePropertiesFailure, @@ -19,6 +21,8 @@ import { isDirectorySuccess, openFileFailure, openFileSuccess, + purgeFilesFailure, + purgeFilesSuccess, readAssetFailure, readAssetSuccess, readFileFailure, @@ -29,44 +33,40 @@ import { removeFileSuccess, renameFileFailure, renameFileSuccess, - revealFileFailure, - revealFileSuccess, - deleteFilesFailure, - deleteFilesSuccess, restoreFileFailure, restoreFileSuccess, restoreFilesFailure, restoreFilesSuccess, - purgeFilesFailure, - purgeFilesSuccess, + revealFileFailure, + revealFileSuccess, } from "../ActionCreators/FilesActionCreators"; -import { - TrashData, - FileTrashMeta, +import type { CalculateFileSizeRequest, CopyFileRequest, CreateFileRequest, CutFileRequest, + DeleteFilesRequest, ExtractIconRequest, FetchFilePropertiesRequest, + FileTrashMeta, IsDirectoryRequest, OpenFileRequest, + PurgeFilesRequest, ReadAssetRequest, ReadFileRequest, ReadJsonFileRequest, RemoveFileRequest, RenameFileRequest, - RevealFileRequest, - DeleteFilesRequest, RestoreFileRequest, RestoreFilesRequest, - PurgeFilesRequest, + RevealFileRequest, + TrashData, } from "../../Typings/Store/files"; -import { selectStatus, typedPut as put } from "./helpers"; import * as FilesService from "../../Services/FilesService"; -import FileMetaData from "../../Typings/fileMetaData"; +import type FileMetaData from "../../Typings/fileMetaData"; +import { typedPut as put, selectStatus } from "./helpers"; function* readFileWorker(action: ReadFileRequest) { try { diff --git a/src/Store/Sagas/LocaleSaga.ts b/src/Store/Sagas/LocaleSaga.ts index e9441a64..541aa7a8 100644 --- a/src/Store/Sagas/LocaleSaga.ts +++ b/src/Store/Sagas/LocaleSaga.ts @@ -2,23 +2,21 @@ import { all, call, takeLatest } from "redux-saga/effects"; import { fetchLocalesFailure, fetchLocalesSuccess } from "../ActionCreators/LocalesActionCreators"; -import { selectStatus, typedPut as put } from "./helpers"; import * as LocalesService from "../../Services/LocaleService"; -import { IAvailableLocales, ILocales } from "../../Typings/Store/locales"; +import type { IAvailableLocales, ILocales } from "../../Typings/Store/locales"; +import { typedPut as put, selectStatus } from "./helpers"; function* fetchLocalesWorker(/* action: FetchLocalesRequest */) { - try { - const { locales, availableLocales }: { locales: ILocales, availableLocales: IAvailableLocales } = yield call(LocalesService.fetchLocales); - yield put(fetchLocalesSuccess(locales, availableLocales)); - } catch (error) { - yield put(fetchLocalesFailure(error.message)); - } + try { + const { locales, availableLocales }: { locales: ILocales; availableLocales: IAvailableLocales } = yield call(LocalesService.fetchLocales); + yield put(fetchLocalesSuccess(locales, availableLocales)); + } catch (error) { + yield put(fetchLocalesFailure(error.message)); + } } function* localeSaga() { - yield all([ - takeLatest(selectStatus('FETCH_LOCALES'), fetchLocalesWorker) - ]); + yield all([takeLatest(selectStatus("FETCH_LOCALES"), fetchLocalesWorker)]); } export default localeSaga; diff --git a/src/Store/Sagas/PlatformSaga.ts b/src/Store/Sagas/PlatformSaga.ts index e90af093..571e18db 100644 --- a/src/Store/Sagas/PlatformSaga.ts +++ b/src/Store/Sagas/PlatformSaga.ts @@ -1,10 +1,10 @@ import { all, call, takeLatest } from "redux-saga/effects"; -import { getOSFailure, getOSSuccess } from "../ActionCreators/PlatformActionCreators"; import {} from "../../Typings/Store/platform"; +import { getOSFailure, getOSSuccess } from "../ActionCreators/PlatformActionCreators"; -import { selectStatus, typedPut as put } from "./helpers"; import * as PlatformService from "../../Services/PlatformService"; +import { typedPut as put, selectStatus } from "./helpers"; function* getOSWorker() { try { diff --git a/src/Store/Sagas/StorageSaga.ts b/src/Store/Sagas/StorageSaga.ts index e302d6b8..c1287467 100644 --- a/src/Store/Sagas/StorageSaga.ts +++ b/src/Store/Sagas/StorageSaga.ts @@ -1,63 +1,62 @@ import { all, call, takeLatest } from "redux-saga/effects"; import { - readDataFailure, readDataSuccess, - removeDataFailure, removeDataSuccess, - writeDataFailure, writeDataSuccess + readDataFailure, + readDataSuccess, + removeDataFailure, + removeDataSuccess, + writeDataFailure, + writeDataSuccess, } from "../ActionCreators/StorageActionCreators"; -import { - ReadDataRequest, - RemoveDataRequest, - WriteDataRequest -} from "../../Typings/Store/storage"; +import type { ReadDataRequest, RemoveDataRequest, WriteDataRequest } from "../../Typings/Store/storage"; -import { selectStatus, typedPut as put } from "./helpers"; import * as StorageService from "../../Services/StorageService"; +import { typedPut as put, selectStatus } from "./helpers"; function* writeDataWorker(action: WriteDataRequest) { - try { - const { key, data } = action; - yield call(StorageService.writeData, key, data); - yield put(writeDataSuccess()); - } catch (error) { - yield put(writeDataFailure(error.message)); - } + try { + const { key, data } = action; + yield call(StorageService.writeData, key, data); + yield put(writeDataSuccess()); + } catch (error) { + yield put(writeDataFailure(error.message)); + } } function* readDataWorker(action: ReadDataRequest) { - try { - const { key } = action; - - /* eslint-disable @typescript-eslint/no-explicit-any */ - /* eslint-disable @typescript-eslint/ban-ts-comment */ - // @ts-ignore - const data: any = yield call(StorageService.readData, key); - /* eslint-enable @typescript-eslint/no-explicit-any */ - /* eslint-enable @typescript-eslint/ban-ts-comment */ - - yield put(readDataSuccess(key, data)); - } catch (error) { - yield put(readDataFailure(error.message)); - } + try { + const { key } = action; + + /* eslint-disable @typescript-eslint/no-explicit-any */ + /* eslint-disable @typescript-eslint/ban-ts-comment */ + // @ts-ignore + const data: any = yield call(StorageService.readData, key); + /* eslint-enable @typescript-eslint/no-explicit-any */ + /* eslint-enable @typescript-eslint/ban-ts-comment */ + + yield put(readDataSuccess(key, data)); + } catch (error) { + yield put(readDataFailure(error.message)); + } } function* removeDataWorker(action: RemoveDataRequest) { - try { - const { key } = action; - yield call(StorageService.removeData, key); - yield put(removeDataSuccess(key)); - } catch (error) { - yield put(removeDataFailure(error.message)); - } + try { + const { key } = action; + yield call(StorageService.removeData, key); + yield put(removeDataSuccess(key)); + } catch (error) { + yield put(removeDataFailure(error.message)); + } } function* storageSaga() { - yield all([ - takeLatest(selectStatus('WRITE_DATA'), writeDataWorker), - takeLatest(selectStatus('READ_DATA'), readDataWorker), - takeLatest(selectStatus('REMOVE_DATA'), removeDataWorker) - ]); + yield all([ + takeLatest(selectStatus("WRITE_DATA"), writeDataWorker), + takeLatest(selectStatus("READ_DATA"), readDataWorker), + takeLatest(selectStatus("REMOVE_DATA"), removeDataWorker), + ]); } export default storageSaga; diff --git a/src/Store/Sagas/TabSaga.ts b/src/Store/Sagas/TabSaga.ts index e9283e94..096acf59 100644 --- a/src/Store/Sagas/TabSaga.ts +++ b/src/Store/Sagas/TabSaga.ts @@ -1,19 +1,17 @@ import { all, takeLatest } from "redux-saga/effects"; -import { SetActiveTabSuccess } from "../../Typings/Store/tab"; +import type { SetActiveTabSuccess } from "../../Typings/Store/tab"; -import { selectStatus, typedPut as put } from "./helpers"; import { fetchFilesRequest } from "../ActionCreators/DirectoryActionCreators"; +import { typedPut as put, selectStatus } from "./helpers"; // Requests files when a new active tab is set successfully function* refetchFilesWorker(action: SetActiveTabSuccess) { - yield put(fetchFilesRequest(action.tab.path, !!action.pushToHistory)); + yield put(fetchFilesRequest(action.tab.path, !!action.pushToHistory)); } function* tabSaga() { - yield all([ - takeLatest(selectStatus('SET_ACTIVE_TAB', 'SUCCESS'), refetchFilesWorker) - ]); + yield all([takeLatest(selectStatus("SET_ACTIVE_TAB", "SUCCESS"), refetchFilesWorker)]); } export default tabSaga; diff --git a/src/Store/Sagas/WindowSaga.ts b/src/Store/Sagas/WindowSaga.ts index 55098458..2a889b4a 100644 --- a/src/Store/Sagas/WindowSaga.ts +++ b/src/Store/Sagas/WindowSaga.ts @@ -1,27 +1,27 @@ +import type { WebviewWindow } from "@tauri-apps/api/webviewWindow"; import { all, call, takeLatest } from "redux-saga/effects"; -import { WebviewWindow } from "@tauri-apps/api/webviewWindow"; import { changeWindowTitleFailure, changeWindowTitleSuccess, + closeWindowFailure, + closeWindowSuccess, createNewWindowFailure, createNewWindowSuccess, listenWindowCloseFailure, listenWindowCloseSuccess, - setDecorationsFailure, - setDecorationsSuccess, - maximizeWindowSuccess, maximizeWindowFailure, - minimizeWindowSuccess, + maximizeWindowSuccess, minimizeWindowFailure, - closeWindowSuccess, - closeWindowFailure, + minimizeWindowSuccess, + setDecorationsFailure, + setDecorationsSuccess, } from "../ActionCreators/WindowActionCreators"; -import { ChangeWindowTitleRequest, CreateNewWindowRequest, SetDecorationsRequest } from "../../Typings/Store/window"; +import type { ChangeWindowTitleRequest, CreateNewWindowRequest, SetDecorationsRequest } from "../../Typings/Store/window"; -import { selectStatus, typedPut as put } from "./helpers"; import * as WindowService from "../../Services/WindowService"; +import { typedPut as put, selectStatus } from "./helpers"; function* listenWindowCloseWorker(/* action: ListenWindowCloseRequest */) { try { diff --git a/src/Store/Sagas/helpers.ts b/src/Store/Sagas/helpers.ts index 27bbde5d..9c8eb18a 100644 --- a/src/Store/Sagas/helpers.ts +++ b/src/Store/Sagas/helpers.ts @@ -1,10 +1,12 @@ import { put, select } from "@redux-saga/core/effects"; -import { ActionStatus } from "../../Typings/Store/actions"; -import { Actions, ActionTypes } from "../../Typings/Store/store"; -import { IAppState } from "../Reducers"; +import type { ActionStatus } from "../../Typings/Store/actions"; +import type { ActionTypes, Actions } from "../../Typings/Store/store"; +import type { IAppState } from "../Reducers"; -export const selectStatus = (type: ActionTypes, status: ActionStatus = 'REQUEST') => - (action: Actions) => (action.type === type && action.status === status); +export const selectStatus = + (type: ActionTypes, status: ActionStatus = "REQUEST") => + (action: Actions) => + action.type === type && action.status === status; export const typedPut = (action: Actions) => put(action); // eslint-disable-next-line @typescript-eslint/no-explicit-any diff --git a/src/Store/index.ts b/src/Store/index.ts index b7c507dc..580457e5 100644 --- a/src/Store/index.ts +++ b/src/Store/index.ts @@ -1,9 +1,9 @@ import { configureStore } from "@reduxjs/toolkit"; -import createSagaMiddleware from "redux-saga"; import { createLogger } from "redux-logger"; +import createSagaMiddleware from "redux-saga"; -import rootSaga from "./Sagas"; import rootReducer, { IAppState } from "./Reducers"; +import rootSaga from "./Sagas"; const sagaMiddleware = createSagaMiddleware(); const loggerMiddleware = createLogger(); diff --git a/src/Typings/Store/actions.ts b/src/Typings/Store/actions.ts index 004eeb18..231e0875 100644 --- a/src/Typings/Store/actions.ts +++ b/src/Typings/Store/actions.ts @@ -1,4 +1,4 @@ -import { Action } from 'redux'; +import type { Action } from "redux"; -export type ActionStatus = 'REQUEST' | 'SUCCESS' | 'FAILURE'; -export type AppActionBase = Action & { status: S }; \ No newline at end of file +export type ActionStatus = "REQUEST" | "SUCCESS" | "FAILURE"; +export type AppActionBase = Action & { status: S }; diff --git a/src/Typings/Store/app.ts b/src/Typings/Store/app.ts index fd607b1a..ef177002 100644 --- a/src/Typings/Store/app.ts +++ b/src/Typings/Store/app.ts @@ -1,22 +1,27 @@ -import { AppActionBase } from "./actions"; +import type { AppActionBase } from "./actions"; export interface IAppReducerState { - vscodeIntstalled: boolean, - availableFonts: string[] + vscodeIntstalled: boolean; + availableFonts: string[]; } -export const FETCH_VSCODE_INSTALLED = 'FETCH_VSCODE_INSTALLED'; -export const FETCH_AVAILABLE_FONTS = 'FETCH_AVAILABLE_FONTS'; +export const FETCH_VSCODE_INSTALLED = "FETCH_VSCODE_INSTALLED"; +export const FETCH_AVAILABLE_FONTS = "FETCH_AVAILABLE_FONTS"; -export type FetchVSCodeInstalledRequest = AppActionBase & {}; -export type FetchVSCodeInstalledSuccess = AppActionBase & { vscodeInstalled: boolean }; -export type FetchVSCodeInstalledFailure = AppActionBase & { message: string }; +export type FetchVSCodeInstalledRequest = AppActionBase & {}; +export type FetchVSCodeInstalledSuccess = AppActionBase & { vscodeInstalled: boolean }; +export type FetchVSCodeInstalledFailure = AppActionBase & { message: string }; -export type FetchAvailableFontsRequest = AppActionBase & {}; -export type FetchAvailableFontsSuccess = AppActionBase & { fonts: string[] }; -export type FetchAvailableFontsFailure = AppActionBase & { message: string }; +export type FetchAvailableFontsRequest = AppActionBase & {}; +export type FetchAvailableFontsSuccess = AppActionBase & { fonts: string[] }; +export type FetchAvailableFontsFailure = AppActionBase & { message: string }; -export type AppActions = FetchVSCodeInstalledRequest | FetchVSCodeInstalledSuccess | FetchVSCodeInstalledFailure - | FetchAvailableFontsRequest | FetchAvailableFontsSuccess | FetchAvailableFontsFailure; +export type AppActions = + | FetchVSCodeInstalledRequest + | FetchVSCodeInstalledSuccess + | FetchVSCodeInstalledFailure + | FetchAvailableFontsRequest + | FetchAvailableFontsSuccess + | FetchAvailableFontsFailure; export type AppActionTypes = typeof FETCH_VSCODE_INSTALLED | typeof FETCH_AVAILABLE_FONTS; diff --git a/src/Typings/Store/cli.ts b/src/Typings/Store/cli.ts index 3e86136a..ef0d28ec 100644 --- a/src/Typings/Store/cli.ts +++ b/src/Typings/Store/cli.ts @@ -1,19 +1,17 @@ -import { AppActionBase } from "./actions"; +import type { AppActionBase } from "./actions"; export interface ICliArguments { - args: string[]; - flags: string[]; + args: string[]; + flags: string[]; } -export interface ICliReducerState extends ICliArguments { +export interface ICliReducerState extends ICliArguments {} -} - -export const FETCH_CLI_INFORMATION = 'FETCH_CLI_INFORMATION'; +export const FETCH_CLI_INFORMATION = "FETCH_CLI_INFORMATION"; -export type FetchCliInformationRequest = AppActionBase & {}; -export type FetchCliInformationSuccess = AppActionBase & { cliArguments: ICliArguments }; -export type FetchCliInformationFailure = AppActionBase & { message: string }; +export type FetchCliInformationRequest = AppActionBase & {}; +export type FetchCliInformationSuccess = AppActionBase & { cliArguments: ICliArguments }; +export type FetchCliInformationFailure = AppActionBase & { message: string }; export type CliActions = FetchCliInformationRequest | FetchCliInformationSuccess | FetchCliInformationFailure; diff --git a/src/Typings/Store/clipboard.ts b/src/Typings/Store/clipboard.ts index ceefa432..97dc64db 100644 --- a/src/Typings/Store/clipboard.ts +++ b/src/Typings/Store/clipboard.ts @@ -1,21 +1,26 @@ -import { AppActionBase } from "./actions"; +import type { AppActionBase } from "./actions"; export interface IClipboardReducerState { - text: string + text: string; } -export const WRITE_TO_CLIPBOARD = 'WRITE_TO_CLIPBOARD'; -export const READ_FROM_CLIPBOARD = 'READ_FROM_CLIPBOARD'; +export const WRITE_TO_CLIPBOARD = "WRITE_TO_CLIPBOARD"; +export const READ_FROM_CLIPBOARD = "READ_FROM_CLIPBOARD"; -export type WriteToClipboardRequest = AppActionBase & { text: string }; -export type WriteToClipboardSuccess = AppActionBase & { text: string }; -export type WriteToClipboardFailure = AppActionBase & { message: string }; +export type WriteToClipboardRequest = AppActionBase & { text: string }; +export type WriteToClipboardSuccess = AppActionBase & { text: string }; +export type WriteToClipboardFailure = AppActionBase & { message: string }; -export type ReadFromClipboardRequest = AppActionBase & {}; -export type ReadFromClipboardSuccess = AppActionBase & { text: string }; -export type ReadFromClipboardFailure = AppActionBase & { message: string }; +export type ReadFromClipboardRequest = AppActionBase & {}; +export type ReadFromClipboardSuccess = AppActionBase & { text: string }; +export type ReadFromClipboardFailure = AppActionBase & { message: string }; -export type ClipboardActions = WriteToClipboardRequest | WriteToClipboardSuccess | WriteToClipboardFailure - | ReadFromClipboardRequest | ReadFromClipboardSuccess | ReadFromClipboardFailure; +export type ClipboardActions = + | WriteToClipboardRequest + | WriteToClipboardSuccess + | WriteToClipboardFailure + | ReadFromClipboardRequest + | ReadFromClipboardSuccess + | ReadFromClipboardFailure; export type ClipboardActionTypes = typeof WRITE_TO_CLIPBOARD | typeof READ_FROM_CLIPBOARD; diff --git a/src/Typings/Store/config.ts b/src/Typings/Store/config.ts index dd6eba41..0252fefc 100644 --- a/src/Typings/Store/config.ts +++ b/src/Typings/Store/config.ts @@ -1,4 +1,4 @@ -import { AppActionBase } from "./actions"; +import type { AppActionBase } from "./actions"; export type AppTheme = "Light" | "Dark"; diff --git a/src/Typings/Store/directory.ts b/src/Typings/Store/directory.ts index a8a236a8..498dce58 100644 --- a/src/Typings/Store/directory.ts +++ b/src/Typings/Store/directory.ts @@ -1,6 +1,6 @@ -import { UnlistenFn } from "@tauri-apps/api/event"; -import FileMetaData from "../fileMetaData"; -import { AppActionBase } from "./actions"; +import type { UnlistenFn } from "@tauri-apps/api/event"; +import type FileMetaData from "../fileMetaData"; +import type { AppActionBase } from "./actions"; export interface IDirectoryMeta { files: FileMetaData[]; @@ -39,9 +39,17 @@ export const PUSH_HISTORY = "PUSH_HISTORY"; // * Internal export const POP_HISTORY = "POP_HISTORY"; // * Internal export const UPDATE_HISTORY_IDX = "UPDATE_HISTORY_IDX"; -export type FetchFilesRequest = AppActionBase & { dirName: string; pushToHistory?: boolean }; -export type FetchFilesSuccess = AppActionBase & { dirName: string; meta: IDirectoryMeta }; -export type FetchFilesFailure = AppActionBase & { message: string }; +export type FetchFilesRequest = AppActionBase & { + dirName: string; + pushToHistory?: boolean; +}; +export type FetchFilesSuccess = AppActionBase & { + dirName: string; + meta: IDirectoryMeta; +}; +export type FetchFilesFailure = AppActionBase & { + message: string; +}; export type FetchIsDirectoryRequest = AppActionBase & { path: string }; export type FetchIsDirectorySuccess = AppActionBase & { isDir: boolean }; @@ -83,7 +91,9 @@ export type CancelDirectorySearchSuccess = AppActionBase & { message: string }; export type PushHistorySuccess = AppActionBase & { path: string }; -export type PopHistorySuccess = AppActionBase & { number: number }; +export type PopHistorySuccess = AppActionBase & { + number: number; +}; export type UpdateHistoryIdxRequest = AppActionBase & { idx: number }; export type UpdateHistoryIdxSuccess = AppActionBase & { idx: number }; diff --git a/src/Typings/Store/drive.ts b/src/Typings/Store/drive.ts index c9a47501..4bf68ab4 100644 --- a/src/Typings/Store/drive.ts +++ b/src/Typings/Store/drive.ts @@ -1,4 +1,4 @@ -import { AppActionBase } from "./actions"; +import type { AppActionBase } from "./actions"; export interface IDrive { name: string; diff --git a/src/Typings/Store/favorites.ts b/src/Typings/Store/favorites.ts index 7e8bc5ad..da7df454 100644 --- a/src/Typings/Store/favorites.ts +++ b/src/Typings/Store/favorites.ts @@ -1,4 +1,4 @@ -import { AppActionBase } from "./actions"; +import type { AppActionBase } from "./actions"; // * Allows for iteration over objects of type IFavorites, IFavoritesReducerState interface IFavoritesBase { diff --git a/src/Typings/Store/files.ts b/src/Typings/Store/files.ts index 6a8530b3..70cb9b5e 100644 --- a/src/Typings/Store/files.ts +++ b/src/Typings/Store/files.ts @@ -1,5 +1,5 @@ -import { AppActionBase } from "./actions"; -import FileMetaData from "../fileMetaData"; +import type FileMetaData from "../fileMetaData"; +import type { AppActionBase } from "./actions"; export interface TrashData { files: FileMetaData[]; diff --git a/src/Typings/Store/locales.ts b/src/Typings/Store/locales.ts index 41a524ff..1e41b6b4 100644 --- a/src/Typings/Store/locales.ts +++ b/src/Typings/Store/locales.ts @@ -1,25 +1,25 @@ -import { AppActionBase } from "./actions"; +import type { AppActionBase } from "./actions"; export interface IAvailableLocales { - [key: string]: string + [key: string]: string; } export interface ILocales { - [key: string]: { - [key: string]: string - } + [key: string]: { + [key: string]: string; + }; } export interface ILocalesReducerState { - locales: ILocales, - availableLocales: IAvailableLocales + locales: ILocales; + availableLocales: IAvailableLocales; } -export const FETCH_LOCALES = 'FETCH_LOCALES'; +export const FETCH_LOCALES = "FETCH_LOCALES"; -export type FetchLocalesRequest = AppActionBase & {}; -export type FetchLocalesSuccess = AppActionBase & { locales: ILocales, availableLocales: IAvailableLocales }; -export type FetchLocalesFailure = AppActionBase & { message: string }; +export type FetchLocalesRequest = AppActionBase & {}; +export type FetchLocalesSuccess = AppActionBase & { locales: ILocales; availableLocales: IAvailableLocales }; +export type FetchLocalesFailure = AppActionBase & { message: string }; export type LocalesActions = FetchLocalesRequest | FetchLocalesSuccess | FetchLocalesFailure; diff --git a/src/Typings/Store/platform.ts b/src/Typings/Store/platform.ts index 437930fd..e25c8f5f 100644 --- a/src/Typings/Store/platform.ts +++ b/src/Typings/Store/platform.ts @@ -1,4 +1,4 @@ -import { AppActionBase } from "./actions"; +import type { AppActionBase } from "./actions"; export interface IPlatformReducerState { os: string; @@ -7,8 +7,12 @@ export interface IPlatformReducerState { export const GET_OS = "GET_OS"; export type GetOSRequest = AppActionBase & {}; -export type GetOSSuccess = AppActionBase & { os: string }; -export type GetOSFailure = AppActionBase & { message: string }; +export type GetOSSuccess = AppActionBase & { + os: string; +}; +export type GetOSFailure = AppActionBase & { + message: string; +}; export type PlatformActions = GetOSRequest | GetOSSuccess | GetOSFailure; diff --git a/src/Typings/Store/request.ts b/src/Typings/Store/request.ts index 26e838f0..b87858e5 100644 --- a/src/Typings/Store/request.ts +++ b/src/Typings/Store/request.ts @@ -1,9 +1,9 @@ -import { ActionStatus } from "./actions"; +import type { ActionStatus } from "./actions"; export interface IRequest { status: ActionStatus; - requestTime: String; - completedTime: String; + requestTime: string; + completedTime: string; // attempts: number // Currently unimplemented, for future use } diff --git a/src/Typings/Store/selection.ts b/src/Typings/Store/selection.ts index 7d544266..179e0428 100644 --- a/src/Typings/Store/selection.ts +++ b/src/Typings/Store/selection.ts @@ -1,4 +1,4 @@ -import { AppActionBase } from "./actions"; +import type { AppActionBase } from "./actions"; export interface ISelectionReducerState { selected: string[]; diff --git a/src/Typings/Store/storage.ts b/src/Typings/Store/storage.ts index 90809425..fc921986 100644 --- a/src/Typings/Store/storage.ts +++ b/src/Typings/Store/storage.ts @@ -1,27 +1,52 @@ -import { AppActionBase } from "./actions"; +import type { AppActionBase } from "./actions"; export interface IStorageReducerState { - store: Record + store: Record; } -export const WRITE_DATA = 'WRITE_DATA'; -export const READ_DATA = 'READ_DATA'; -export const REMOVE_DATA = 'REMOVE_DATA'; +export const WRITE_DATA = "WRITE_DATA"; +export const READ_DATA = "READ_DATA"; +export const REMOVE_DATA = "REMOVE_DATA"; -export type WriteDataRequest = AppActionBase & { key: string, data: any }; -export type WriteDataSuccess = AppActionBase & {}; -export type WriteDataFailure = AppActionBase & { message: string }; +export type WriteDataRequest = AppActionBase & { + key: string; + data: any; +}; +export type WriteDataSuccess = AppActionBase & {}; +export type WriteDataFailure = AppActionBase & { + message: string; +}; -export type ReadDataRequest = AppActionBase & { key: string }; -export type ReadDataSuccess = AppActionBase & { key: string, data: any }; -export type ReadDataFailure = AppActionBase & { message: string }; +export type ReadDataRequest = AppActionBase & { + key: string; +}; +export type ReadDataSuccess = AppActionBase & { + key: string; + data: any; +}; +export type ReadDataFailure = AppActionBase & { + message: string; +}; -export type RemoveDataRequest = AppActionBase & { key: string }; -export type RemoveDataSuccess = AppActionBase & { key: string }; -export type RemoveDataFailure = AppActionBase & { message: string }; +export type RemoveDataRequest = AppActionBase & { + key: string; +}; +export type RemoveDataSuccess = AppActionBase & { + key: string; +}; +export type RemoveDataFailure = AppActionBase & { + message: string; +}; -export type StorageActions = WriteDataRequest | WriteDataSuccess | WriteDataFailure - | ReadDataRequest | ReadDataSuccess | ReadDataFailure - | RemoveDataRequest | RemoveDataSuccess | RemoveDataFailure; +export type StorageActions = + | WriteDataRequest + | WriteDataSuccess + | WriteDataFailure + | ReadDataRequest + | ReadDataSuccess + | ReadDataFailure + | RemoveDataRequest + | RemoveDataSuccess + | RemoveDataFailure; export type StorageActionTypes = typeof WRITE_DATA | typeof READ_DATA | typeof REMOVE_DATA; diff --git a/src/Typings/Store/store.ts b/src/Typings/Store/store.ts index 396b288a..6d92f5ac 100644 --- a/src/Typings/Store/store.ts +++ b/src/Typings/Store/store.ts @@ -1,17 +1,17 @@ -import { AppActions, AppActionTypes } from "./app"; -import { CliActions, CliActionTypes } from "./cli"; -import { ClipboardActions, ClipboardActionTypes } from "./clipboard"; -import { ConfigActions, ConfigActionTypes } from "./config"; -import { DirectoryActions, DirectoryActionTypes } from "./directory"; -import { DriveActions, DriveActionTypes } from "./drive"; -import { FavoritesActions, FavoritesActionTypes } from "./favorites"; -import { FileActions, FileActionTypes } from "./files"; -import { LocalesActions, LocalesActionTypes } from "./locales"; -import { PlatformActions, PlatformActionTypes } from "./platform"; -import { StorageActions, StorageActionTypes } from "./storage"; -import { TabActions, TabActionTypes } from "./tab"; -import { WindowActions, WindowActionTypes } from "./window"; -import { SelectionActions, SelectionActionTypes } from "./selection"; +import type { AppActionTypes, AppActions } from "./app"; +import type { CliActionTypes, CliActions } from "./cli"; +import type { ClipboardActionTypes, ClipboardActions } from "./clipboard"; +import type { ConfigActionTypes, ConfigActions } from "./config"; +import type { DirectoryActionTypes, DirectoryActions } from "./directory"; +import type { DriveActionTypes, DriveActions } from "./drive"; +import type { FavoritesActionTypes, FavoritesActions } from "./favorites"; +import type { FileActionTypes, FileActions } from "./files"; +import type { LocalesActionTypes, LocalesActions } from "./locales"; +import type { PlatformActionTypes, PlatformActions } from "./platform"; +import type { SelectionActionTypes, SelectionActions } from "./selection"; +import type { StorageActionTypes, StorageActions } from "./storage"; +import type { TabActionTypes, TabActions } from "./tab"; +import type { WindowActionTypes, WindowActions } from "./window"; export type Actions = | AppActions diff --git a/src/Typings/Store/tab.ts b/src/Typings/Store/tab.ts index d5883bbf..a1069054 100644 --- a/src/Typings/Store/tab.ts +++ b/src/Typings/Store/tab.ts @@ -1,4 +1,4 @@ -import { AppActionBase } from "./actions"; +import type { AppActionBase } from "./actions"; export interface ITab { name: string; @@ -16,9 +16,16 @@ export const UPDATE_TAB = "UPDATE_TAB"; // * Internal export const DELETE_TAB = "DELETE_TAB"; // * Internal export const SET_ACTIVE_TAB = "SET_ACTIVE_TAB"; // * Internal -export type CreateTabSuccess = AppActionBase & { tab: ITab }; -export type UpdateTabSuccess = AppActionBase & { name: string; tab: Partial }; -export type DeleteTabSuccess = AppActionBase & { id: number }; +export type CreateTabSuccess = AppActionBase & { + tab: ITab; +}; +export type UpdateTabSuccess = AppActionBase & { + name: string; + tab: Partial; +}; +export type DeleteTabSuccess = AppActionBase & { + id: number; +}; export type SetActiveTabSuccess = AppActionBase & { tab: ITab; pushToHistory?: boolean }; export type TabActions = CreateTabSuccess | UpdateTabSuccess | DeleteTabSuccess | SetActiveTabSuccess; diff --git a/src/Typings/Store/window.ts b/src/Typings/Store/window.ts index a1112674..d02b0f69 100644 --- a/src/Typings/Store/window.ts +++ b/src/Typings/Store/window.ts @@ -1,6 +1,6 @@ -import { WebviewWindow } from "@tauri-apps/api/webviewWindow"; +import type { WebviewWindow } from "@tauri-apps/api/webviewWindow"; -import { AppActionBase } from "./actions"; +import type { AppActionBase } from "./actions"; export interface IWindowReducerState { windows: Record; // title -> window diff --git a/src/Typings/contextMenuItem.d.ts b/src/Typings/contextMenuItem.d.ts index 38797942..3e06b080 100644 --- a/src/Typings/contextMenuItem.d.ts +++ b/src/Typings/contextMenuItem.d.ts @@ -1,13 +1,13 @@ export default interface MenuItem { - menu: string; - role?: () => void; - visible?: boolean; - icon?: string; - shortcut?: string; - submenu?: { - shortcut?: string; - name?: string; - role?: () => void; - icon?: string; - }[]; + menu: string; + role?: () => void; + visible?: boolean; + icon?: string; + shortcut?: string; + submenu?: { + shortcut?: string; + name?: string; + role?: () => void; + icon?: string; + }[]; } diff --git a/src/Typings/fileData.d.ts b/src/Typings/fileData.d.ts index 9897b676..83c43720 100644 --- a/src/Typings/fileData.d.ts +++ b/src/Typings/fileData.d.ts @@ -1,16 +1,16 @@ export default interface fileData { - name: string; - isDir: boolean; - isHidden: boolean; - createdAt?: string | Date; - modifiedAt?: string | Date; - accessedAt?: string | Date; - size?: number; - isSystemFile?: boolean; - isTrash?: boolean; - type?: string; - path?: string; - realPath?: string; - trashDeletionDate?: string | Date; - displayName?: string; + name: string; + isDir: boolean; + isHidden: boolean; + createdAt?: string | Date; + modifiedAt?: string | Date; + accessedAt?: string | Date; + size?: number; + isSystemFile?: boolean; + isTrash?: boolean; + type?: string; + path?: string; + realPath?: string; + trashDeletionDate?: string | Date; + displayName?: string; } diff --git a/src/Typings/fileMetaData.d.ts b/src/Typings/fileMetaData.d.ts index 5bf96457..8f9c954d 100644 --- a/src/Typings/fileMetaData.d.ts +++ b/src/Typings/fileMetaData.d.ts @@ -1,28 +1,28 @@ interface SystemTime { - nanos_since_epoch: number; - secs_since_epoch: number; + nanos_since_epoch: number; + secs_since_epoch: number; } interface FileMetaData { - file_path: string; - basename: string; - file_type: string; - original_parent?: string; - time_deleted?: number; - is_trash: boolean; - is_dir?: boolean; - is_hidden?: boolean; - is_file?: boolean; - is_system?: boolean; - size?: number; - readonly?: boolean; - last_modified?: SystemTime; - last_accessed?: SystemTime; - created?: SystemTime; + file_path: string; + basename: string; + file_type: string; + original_parent?: string; + time_deleted?: number; + is_trash: boolean; + is_dir?: boolean; + is_hidden?: boolean; + is_file?: boolean; + is_system?: boolean; + size?: number; + readonly?: boolean; + last_modified?: SystemTime; + last_accessed?: SystemTime; + created?: SystemTime; } export interface LnkData { - file_path: string; - icon: string; + file_path: string; + icon: string; } export default FileMetaData; diff --git a/src/Typings/mammoth.d.ts b/src/Typings/mammoth.d.ts index 25ef9e53..8312b373 100644 --- a/src/Typings/mammoth.d.ts +++ b/src/Typings/mammoth.d.ts @@ -1,77 +1,72 @@ /** A module for converting Microsoft Word .docx files to HTML or text. */ -declare module 'mammoth' { - type Input = { - /** The path to the .docx file. */ - path?: string; +declare module "mammoth" { + type Input = { + /** The path to the .docx file. */ + path?: string; - /** The buffer containing the .docx file, if path is not specified. */ - buffer?: Buffer; - }; + /** The buffer containing the .docx file, if path is not specified. */ + buffer?: Buffer; + }; - /** Conversion options. */ - type Options = { - /** - * Overrides for the default style map. - * Examples: - * "b => em" - * "i => strong" - */ - styleMap?: string[]; + /** Conversion options. */ + type Options = { + /** + * Overrides for the default style map. + * Examples: + * "b => em" + * "i => strong" + */ + styleMap?: string[]; - /** To stop using the default style map. */ - includeDefaultStyleMap?: boolean; + /** To stop using the default style map. */ + includeDefaultStyleMap?: boolean; - convertImage?: unknown; - }; + convertImage?: unknown; + }; - /** The error or warning message returned from the processing operation. */ - type Message = { - /** a string representing the type of the message, such as "warning" or "error" */ - type: 'warning' | 'error'; + /** The error or warning message returned from the processing operation. */ + type Message = { + /** a string representing the type of the message, such as "warning" or "error" */ + type: "warning" | "error"; - /** a string containing the actual message */ - message: string; + /** a string containing the actual message */ + message: string; - /** the thrown exception that caused this message, if any */ - error?: Error; - }; + /** the thrown exception that caused this message, if any */ + error?: Error; + }; - /** The result from the processing operation. */ - type Result = { - /** The HTML result. */ - value: string; + /** The result from the processing operation. */ + type Result = { + /** The HTML result. */ + value: string; - /** Error and warning messages if any. */ - messages: Message[]; - }; + /** Error and warning messages if any. */ + messages: Message[]; + }; - namespace images { - type Image = { - read(type: string): Promise; - contentType: string; - }; + namespace images { + type Image = { + read(type: string): Promise; + contentType: string; + }; - type Source = { - src: string; - }; + type Source = { + src: string; + }; - export function imgElement( - callback: (image: Image) => Source | Promise - ): void; - } + export function imgElement(callback: (image: Image) => Source | Promise): void; + } - /** - * Converts an existing .docx file to HTML. - * @param input An object containing the path or buffer. - */ - export function convertToHtml( - input: Input, - options?: Options - ): Promise; + /** + * Converts an existing .docx file to HTML. + * @param input An object containing the path or buffer. + */ + export function convertToHtml(input: Input, options?: Options): Promise; - /** - * Converts an existing .docx file to plain texts. - * @param input An object containing the path or buffer. - */ - export function extractRawText(input: Input): Promise; + /** + * Converts an existing .docx file to plain texts. + * @param input An object containing the path or buffer. + */ + export function extractRawText(input: Input): Promise; } diff --git a/src/Typings/select.d.ts b/src/Typings/select.d.ts index 5699bc88..add1c9c5 100644 --- a/src/Typings/select.d.ts +++ b/src/Typings/select.d.ts @@ -1,6 +1,6 @@ type direction = { x: -1 | 0 | 1; y: -1 | 0 | 1; -} +}; -export { direction } \ No newline at end of file +export type { direction }; diff --git a/src/Typings/storageData.d.ts b/src/Typings/storageData.d.ts index 681d7681..98855f82 100644 --- a/src/Typings/storageData.d.ts +++ b/src/Typings/storageData.d.ts @@ -1,3 +1,3 @@ export default interface IStorageData { - [key: string]: any; + [key: string]: any; } diff --git a/src/Typings/svg.d.ts b/src/Typings/svg.d.ts index 976923f6..156473a5 100644 --- a/src/Typings/svg.d.ts +++ b/src/Typings/svg.d.ts @@ -1,4 +1,4 @@ -declare module '*.svg' { - const content: any; - export default content; +declare module "*.svg" { + const content: any; + export default content; } diff --git a/src/Typings/theme.d.ts b/src/Typings/theme.d.ts index bdb8bf41..94907be0 100644 --- a/src/Typings/theme.d.ts +++ b/src/Typings/theme.d.ts @@ -1,15 +1,15 @@ export interface Theme { - [key: string]: string; + [key: string]: string; } export interface CustomTheme { - author: string; - name: string; - description: string; - version: string; - identifier: string; - homepage: string; - license: string; - repository: string; - theme: Theme; + author: string; + name: string; + description: string; + version: string; + identifier: string; + homepage: string; + license: string; + repository: string; + theme: Theme; } diff --git a/src/Util/constants.ts b/src/Util/constants.ts index 10b3483d..0aba6214 100644 --- a/src/Util/constants.ts +++ b/src/Util/constants.ts @@ -1,16 +1,16 @@ -export const SERVICE_ENDPOINT = 'http://localhost:3030/'; -export const READ_DIR_ENDPOINT = SERVICE_ENDPOINT + 'read_dir?path='; -export const GET_FAVORITES_PATH_ENDPOINT = SERVICE_ENDPOINT + 'dir/favorites'; -export const CHECK_EXIST_ENDPOINT = SERVICE_ENDPOINT + 'check_exist?path='; -export const CHECK_ISDIR_ENDPOINT = SERVICE_ENDPOINT + 'check_isdir?path='; -export const OPEN_FILE_ENDPOINT = SERVICE_ENDPOINT + 'open_file?path='; -export const GET_AVAILABLE_FONTS_ENDPOINT = SERVICE_ENDPOINT + 'get_available_fonts'; -export const GET_DIR_SIZE_ENDPOINT = SERVICE_ENDPOINT + 'get_dir_size?path='; -export const GET_DRIVES_ENDPOINT = SERVICE_ENDPOINT + 'drives'; -export const GET_PLATFORM_ENDPOINT = SERVICE_ENDPOINT + 'platform'; -export const CALCULATE_DIRS_SIZE_ENDPOINT = SERVICE_ENDPOINT + 'calculate_dirs_size?paths='; +export const SERVICE_ENDPOINT = "http://localhost:3030/"; +export const READ_DIR_ENDPOINT = SERVICE_ENDPOINT + "read_dir?path="; +export const GET_FAVORITES_PATH_ENDPOINT = SERVICE_ENDPOINT + "dir/favorites"; +export const CHECK_EXIST_ENDPOINT = SERVICE_ENDPOINT + "check_exist?path="; +export const CHECK_ISDIR_ENDPOINT = SERVICE_ENDPOINT + "check_isdir?path="; +export const OPEN_FILE_ENDPOINT = SERVICE_ENDPOINT + "open_file?path="; +export const GET_AVAILABLE_FONTS_ENDPOINT = SERVICE_ENDPOINT + "get_available_fonts"; +export const GET_DIR_SIZE_ENDPOINT = SERVICE_ENDPOINT + "get_dir_size?path="; +export const GET_DRIVES_ENDPOINT = SERVICE_ENDPOINT + "drives"; +export const GET_PLATFORM_ENDPOINT = SERVICE_ENDPOINT + "platform"; +export const CALCULATE_DIRS_SIZE_ENDPOINT = SERVICE_ENDPOINT + "calculate_dirs_size?paths="; -export const MAIN_BOX_ELEMENT = () => document.querySelector('.main-box'); +export const MAIN_BOX_ELEMENT = () => document.querySelector(".main-box"); export const GET_WORKSPACE_ELEMENT = (id: number) => document.getElementById(`workspace-${id}`); -export const GET_TAB_ELEMENT = () => document.querySelector('.workspace-tab-active'); +export const GET_TAB_ELEMENT = () => document.querySelector(".workspace-tab-active"); diff --git a/src/Util/is-tauri.ts b/src/Util/is-tauri.ts index d1589069..c6366470 100644 --- a/src/Util/is-tauri.ts +++ b/src/Util/is-tauri.ts @@ -3,6 +3,6 @@ * Check if it's running on Tauri */ const isTauri = Boolean( - typeof window !== 'undefined' && window != undefined && (window as any).__TAURI__ !== undefined && (window as any).promisified !== null + typeof window !== "undefined" && window != undefined && (window as any).__TAURI__ !== undefined && (window as any).promisified !== null, ); export default isTauri; diff --git a/src/components/Infobar/index.tsx b/src/components/Infobar/index.tsx index 1708565d..b862ae3d 100644 --- a/src/components/Infobar/index.tsx +++ b/src/components/Infobar/index.tsx @@ -1,5 +1,4 @@ import React, { useEffect } from "react"; -import { ThemedDiv, ThemedSpan } from "../Theme"; import { useSelector } from "react-redux"; import { IAppState } from "../../Store/Reducers"; import formatBytes from "../Functions/filesize"; diff --git a/src/components/Theme/_theme.ts b/src/components/Theme/_theme.ts index cffc2043..ad8ee67b 100644 --- a/src/components/Theme/_theme.ts +++ b/src/components/Theme/_theme.ts @@ -1,36 +1,36 @@ -import isTauri from '../../Util/is-tauri'; -import { listenStylesheetChange } from '../../Service/app'; -import Storage from '../../Service/storage'; -import { CustomTheme, Theme } from '../../Typings/theme'; +import { listenStylesheetChange } from "../../Service/app"; +import Storage from "../../Service/storage"; +import type { CustomTheme, Theme } from "../../Typings/theme"; +import isTauri from "../../Util/is-tauri"; -type Category = '*' | 'root' | 'tabbing' | 'favorites' | 'grid'; -type ElementType = 'sidebar' | 'tab' | 'card' | 'grid'; +type Category = "*" | "root" | "tabbing" | "favorites" | "grid"; +type ElementType = "sidebar" | "tab" | "card" | "grid"; -import IsValid from '../Functions/validChecker'; +import IsValid from "../Functions/validChecker"; /** * Detect system theme * @returns {string} System color scheme preference */ const detectDefaultTheme = (): string => { - if (matchMedia('(prefers-color-scheme: dark)').matches) return 'dark'; - return 'light'; + if (matchMedia("(prefers-color-scheme: dark)").matches) return "dark"; + return "light"; }; let defaultTheme = detectDefaultTheme(); const updateNativeTheme = (): void => { - defaultTheme = detectDefaultTheme(); - updateTheme('*'); + defaultTheme = detectDefaultTheme(); + updateTheme("*"); }; -matchMedia('(prefers-color-scheme: dark)').addEventListener('change', (e) => { - defaultTheme = e.matches ? 'dark' : 'light'; - updateTheme('*'); +matchMedia("(prefers-color-scheme: dark)").addEventListener("change", (e) => { + defaultTheme = e.matches ? "dark" : "light"; + updateTheme("*"); }); let themeJSON: Theme; // user preference theme json -import * as defaultThemeData from './theme.json'; +import * as defaultThemeData from "./theme.json"; interface DefaultTheme { - [key: string]: Theme; + [key: string]: Theme; } const defaultThemeJSON: DefaultTheme = defaultThemeData; @@ -43,7 +43,7 @@ let currentTheme: string; * @returns {string|null} Style of the [variable] of the element */ const getElementStyle = (variable: string, theme?: string): string | null => { - return themeJSON?.[variable] || defaultThemeJSON[theme ?? currentTheme]?.[variable]; + return themeJSON?.[variable] || defaultThemeJSON[theme ?? currentTheme]?.[variable]; }; /** @@ -55,7 +55,7 @@ const getElementStyle = (variable: string, theme?: string): string | null => { * @returns {void} */ const changeElementTheme = (element: HTMLElement, variable: string, key: string, theme: string) => { - if (element) (element.style)[key] = themeJSON?.[variable] || defaultThemeJSON?.[theme]?.[variable]; //eslint-disable-line + if (element) (element.style)[key] = themeJSON?.[variable] || defaultThemeJSON?.[theme]?.[variable]; //eslint-disable-line }; /** @@ -66,48 +66,37 @@ const changeElementTheme = (element: HTMLElement, variable: string, key: string, * @returns {void} */ const hoverHandler = (obj: HTMLElement, theme: string, type: ElementType) => { - changeElementTheme(obj, type + 'Background', 'background', theme); - if (obj.getAttribute('being-listened') === 'true') return; - obj.setAttribute('being-listened', 'true'); - obj.addEventListener('mousemove', (e) => { - const rect = (e.currentTarget as HTMLElement).getBoundingClientRect(); - const x = e.clientX - rect.left; - const y = e.clientY - rect.top; - if (obj.classList.contains('active')) return (obj.onmouseleave = null); - const color = getElementStyle('animation.' + type, currentTheme); - obj.style.background = `radial-gradient(circle at ${x}px ${y}px, ${color})`; - obj.onmouseleave = () => (obj.style.background = obj.style.borderImage = null); - }); + changeElementTheme(obj, type + "Background", "background", theme); + if (obj.getAttribute("being-listened") === "true") return; + obj.setAttribute("being-listened", "true"); + obj.addEventListener("mousemove", (e) => { + const rect = (e.currentTarget as HTMLElement).getBoundingClientRect(); + const x = e.clientX - rect.left; + const y = e.clientY - rect.top; + if (obj.classList.contains("active")) return (obj.onmouseleave = null); + const color = getElementStyle("animation." + type, currentTheme); + obj.style.background = `radial-gradient(circle at ${x}px ${y}px, ${color})`; + obj.onmouseleave = () => (obj.style.background = obj.style.borderImage = null); + }); }; const ALLOWED_STYLES = [ - 'background', - 'color', - 'font', - 'border', - 'text', - 'cursor', - 'outline', - 'box-shadow', - '--scrollbar', - '--tabs-scrollbar', - '--preview-object', - '--selected-grid', + "background", + "color", + "font", + "border", + "text", + "cursor", + "outline", + "box-shadow", + "--scrollbar", + "--tabs-scrollbar", + "--preview-object", + "--selected-grid", ]; // prettier-ignore -const CATEGORIES = [ - 'root', - 'windowmanager', - 'tabs', - 'settings', - 'favorites', - 'grid', - 'contextmenu', - 'prompt', - 'preview', - 'properties', -]; +const CATEGORIES = ["root", "windowmanager", "tabs", "settings", "favorites", "grid", "contextmenu", "prompt", "preview", "properties"]; /** * Change page theme @@ -115,70 +104,70 @@ const CATEGORIES = [ * @returns {Promise} */ const changeTheme = async (theme?: string, category?: Category): Promise => { - if (!category) category = '*'; - const appearance = (await Storage.get('appearance')) || {}; - if (category === '*' || category === 'root') { - const root = document.documentElement; - const opacity = appearance.windowTransparency || '0.8'; - root.style.fontSize = appearance.fontSize || '16px'; - root.style.fontFamily = appearance.fontFamily || 'system-ui'; - root.style.setProperty('--edge-radius', appearance.frameStyle === 'os' || !isTauri ? '0px' : '10px'); - root.style.setProperty('--sidebar-transparency', isTauri && (appearance.transparentSidebar ?? true) ? opacity : 1); - root.style.setProperty('--workspace-transparency', isTauri && appearance.transparentWorkspace ? opacity : 1); - root.style.setProperty('--topbar-transparency', isTauri && appearance.transparentTopbar ? opacity : 1); - - const sidebarItems = document.querySelectorAll('.sidebar-hover-effect'); - sidebarItems.forEach((obj) => hoverHandler(obj, theme, 'sidebar')); - - const style = document.querySelector('style#root') ?? document.createElement('style'); - style.id = 'root'; - let content = ''; - // Generate CSS styles from user theme - for (const key of Object.keys(IsValid(themeJSON) ? themeJSON : defaultThemeJSON[theme])) { - const value = IsValid(themeJSON) ? themeJSON[key] : defaultThemeJSON[theme]?.[key]; - const formalKey = key.replace(/[A-Z]/g, (m) => '-' + m.toLowerCase()); - const splittedKey = formalKey.split('.'); - const styleKey = splittedKey[splittedKey.length - 1]; - if (key.startsWith('hljs')) { - const className = formalKey.split('.').slice(0, -1).join('.').replace('hljs.', 'hljs-'); - content += `.${className} { ${styleKey}: ${value} }\n`; - } else { - for (const _category of CATEGORIES) { - if (!key.startsWith(_category)) continue; - const usingClassName = formalKey[_category.length] === '.'; - const className = formalKey.split('.').slice(1, -1).join('.'); - const idName = formalKey.split('#').slice(1).join('#').split('.')[0]; - for (const allowedStyle of ALLOWED_STYLES) { - if (!styleKey.startsWith(allowedStyle)) continue; - if (styleKey.startsWith('--')) { - content += `:root { ${styleKey}: ${value}; }\n`; - break; - } - if (!usingClassName) content += '#' + idName; - else if (className !== '') content += '.' + className; - else if (_category !== 'root') content += '.' + _category; - else content += ':root'; - content += `{ ${styleKey}: ${value} }\n`; - break; - } - } - } - } - style.textContent = content; - !document.head.contains(style) && document.head.appendChild(style); - } - if (category === '*' || category === 'tabbing') { - const tabItems = document.querySelectorAll('.tab-hover-effect'); - tabItems.forEach((obj) => hoverHandler(obj, theme, 'tab')); - } - if (category === '*' || category === 'favorites') { - const cardItems = document.querySelectorAll('.card-hover-effect'); - cardItems.forEach((obj) => hoverHandler(obj, theme, 'card')); - } - if (category === '*' || category === 'grid') { - const gridItems = document.querySelectorAll('.grid-hover-effect'); - gridItems.forEach((obj) => hoverHandler(obj, theme, 'grid')); - } + if (!category) category = "*"; + const appearance = (await Storage.get("appearance")) || {}; + if (category === "*" || category === "root") { + const root = document.documentElement; + const opacity = appearance.windowTransparency || "0.8"; + root.style.fontSize = appearance.fontSize || "16px"; + root.style.fontFamily = appearance.fontFamily || "system-ui"; + root.style.setProperty("--edge-radius", appearance.frameStyle === "os" || !isTauri ? "0px" : "10px"); + root.style.setProperty("--sidebar-transparency", isTauri && (appearance.transparentSidebar ?? true) ? opacity : 1); + root.style.setProperty("--workspace-transparency", isTauri && appearance.transparentWorkspace ? opacity : 1); + root.style.setProperty("--topbar-transparency", isTauri && appearance.transparentTopbar ? opacity : 1); + + const sidebarItems = document.querySelectorAll(".sidebar-hover-effect"); + sidebarItems.forEach((obj) => hoverHandler(obj, theme, "sidebar")); + + const style = document.querySelector("style#root") ?? document.createElement("style"); + style.id = "root"; + let content = ""; + // Generate CSS styles from user theme + for (const key of Object.keys(IsValid(themeJSON) ? themeJSON : defaultThemeJSON[theme])) { + const value = IsValid(themeJSON) ? themeJSON[key] : defaultThemeJSON[theme]?.[key]; + const formalKey = key.replace(/[A-Z]/g, (m) => "-" + m.toLowerCase()); + const splittedKey = formalKey.split("."); + const styleKey = splittedKey[splittedKey.length - 1]; + if (key.startsWith("hljs")) { + const className = formalKey.split(".").slice(0, -1).join(".").replace("hljs.", "hljs-"); + content += `.${className} { ${styleKey}: ${value} }\n`; + } else { + for (const _category of CATEGORIES) { + if (!key.startsWith(_category)) continue; + const usingClassName = formalKey[_category.length] === "."; + const className = formalKey.split(".").slice(1, -1).join("."); + const idName = formalKey.split("#").slice(1).join("#").split(".")[0]; + for (const allowedStyle of ALLOWED_STYLES) { + if (!styleKey.startsWith(allowedStyle)) continue; + if (styleKey.startsWith("--")) { + content += `:root { ${styleKey}: ${value}; }\n`; + break; + } + if (!usingClassName) content += "#" + idName; + else if (className !== "") content += "." + className; + else if (_category !== "root") content += "." + _category; + else content += ":root"; + content += `{ ${styleKey}: ${value} }\n`; + break; + } + } + } + } + style.textContent = content; + !document.head.contains(style) && document.head.appendChild(style); + } + if (category === "*" || category === "tabbing") { + const tabItems = document.querySelectorAll(".tab-hover-effect"); + tabItems.forEach((obj) => hoverHandler(obj, theme, "tab")); + } + if (category === "*" || category === "favorites") { + const cardItems = document.querySelectorAll(".card-hover-effect"); + cardItems.forEach((obj) => hoverHandler(obj, theme, "card")); + } + if (category === "*" || category === "grid") { + const gridItems = document.querySelectorAll(".grid-hover-effect"); + gridItems.forEach((obj) => hoverHandler(obj, theme, "grid")); + } }; /** @@ -186,56 +175,56 @@ const changeTheme = async (theme?: string, category?: Category): Promise = * @returns {Promise} */ const getInstalledThemes = async (): Promise => { - const extensions = await Storage.get('extensions'); - const themes: CustomTheme[] = []; - if (!extensions?.themes) return themes; - for (const extension of extensions.themes) { - const { identifier, author, version, description, homepage, repository, license } = extension; - for (const { name, value } of extension.themes) { - themes.push({ - name, - identifier: identifier + '@' + identifier, - author, - version, - description, - homepage, - repository, - license, - theme: value, - }); - } - } - return themes; + const extensions = await Storage.get("extensions"); + const themes: CustomTheme[] = []; + if (!extensions?.themes) return themes; + for (const extension of extensions.themes) { + const { identifier, author, version, description, homepage, repository, license } = extension; + for (const { name, value } of extension.themes) { + themes.push({ + name, + identifier: identifier + "@" + identifier, + author, + version, + description, + homepage, + repository, + license, + theme: value, + }); + } + } + return themes; }; /** * Update the entire page theme * @returns {Promise} */ const updateTheme = async (category?: Category, customStyleSheet?: JSON): Promise => { - const data = await Storage.get('theme'); - if (IsValid(customStyleSheet)) { - console.log(customStyleSheet); - themeJSON = customStyleSheet as unknown as Theme; - document.body.dataset.usingCustomTheme = 'true'; - listenStylesheetChange((styles) => { - themeJSON = styles as unknown as Theme; - changeTheme(data.theme, '*'); - }); - } - // If user has no preference theme - if (!data || !Object.keys(data).length || data.theme === 'System Default') { - return await changeTheme((currentTheme = defaultTheme), category); - } - // If user preference is default color theme... - if (Object.keys(defaultThemeJSON).indexOf(data.theme) !== -1) { - if (document.body.dataset.usingCustomTheme !== 'true') themeJSON = null; - return await changeTheme((currentTheme = data.theme), category); - } - for (const theme of await getInstalledThemes()) { - if (theme.identifier !== data.theme) continue; - if (document.body.dataset.usingCustomTheme !== 'true') themeJSON = theme.theme; - return await changeTheme(theme.name, category); - } + const data = await Storage.get("theme"); + if (IsValid(customStyleSheet)) { + console.log(customStyleSheet); + themeJSON = customStyleSheet as unknown as Theme; + document.body.dataset.usingCustomTheme = "true"; + listenStylesheetChange((styles) => { + themeJSON = styles as unknown as Theme; + changeTheme(data.theme, "*"); + }); + } + // If user has no preference theme + if (!data || !Object.keys(data).length || data.theme === "System Default") { + return await changeTheme((currentTheme = defaultTheme), category); + } + // If user preference is default color theme... + if (Object.keys(defaultThemeJSON).indexOf(data.theme) !== -1) { + if (document.body.dataset.usingCustomTheme !== "true") themeJSON = null; + return await changeTheme((currentTheme = data.theme), category); + } + for (const theme of await getInstalledThemes()) { + if (theme.identifier !== data.theme) continue; + if (document.body.dataset.usingCustomTheme !== "true") themeJSON = theme.theme; + return await changeTheme(theme.name, category); + } }; export { changeTheme, updateTheme, detectDefaultTheme, updateNativeTheme, getElementStyle, getInstalledThemes }; diff --git a/src/components/Theme/index.tsx b/src/components/Theme/index.tsx index e8ca21ae..929cb941 100644 --- a/src/components/Theme/index.tsx +++ b/src/components/Theme/index.tsx @@ -1,4 +1,4 @@ -import React, { useContext, PropsWithChildren, HTMLAttributes } from "react"; +import React, { useContext, type PropsWithChildren, type HTMLAttributes } from "react"; import * as themeJson from "./theme.json"; export const ThemeContext = React.createContext({ theme: "light" }); diff --git a/src/index.tsx b/src/index.tsx index a32e68d2..92c8b771 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -21,12 +21,12 @@ import { Provider } from "react-redux"; import App from "./App"; import store from "./Store"; -import { fetchFavoritesRequest } from "./Store/ActionCreators/FavoritesActionCreators"; +import { ThemeContext } from "./Components/Theme"; +import { fetchFilesRequest, listenDirectoryRequest } from "./Store/ActionCreators/DirectoryActionCreators"; import { fetchDrivesRequest } from "./Store/ActionCreators/DriveActionCreators"; +import { fetchFavoritesRequest } from "./Store/ActionCreators/FavoritesActionCreators"; import { getOSRequest } from "./Store/ActionCreators/PlatformActionCreators"; -import { fetchFilesRequest, listenDirectoryRequest } from "./Store/ActionCreators/DirectoryActionCreators"; import { readDataRequest } from "./Store/ActionCreators/StorageActionCreators"; -import { ThemeContext } from "./Components/Theme"; // Wait DOM Loaded to be loaded document.addEventListener("DOMContentLoaded", async () => { store.dispatch(getOSRequest()); diff --git a/yarn.lock b/yarn.lock index fdeabd0f..4d81f3e2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -310,6 +310,60 @@ resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw== +"@biomejs/biome@1.6.4": + version "1.6.4" + resolved "https://registry.yarnpkg.com/@biomejs/biome/-/biome-1.6.4.tgz#d09ab44c1df2a0cbbbb15901779a164beacd356d" + integrity sha512-3groVd2oWsLC0ZU+XXgHSNbq31lUcOCBkCcA7sAQGBopHcmL+jmmdoWlY3S61zIh+f2mqQTQte1g6PZKb3JJjA== + optionalDependencies: + "@biomejs/cli-darwin-arm64" "1.6.4" + "@biomejs/cli-darwin-x64" "1.6.4" + "@biomejs/cli-linux-arm64" "1.6.4" + "@biomejs/cli-linux-arm64-musl" "1.6.4" + "@biomejs/cli-linux-x64" "1.6.4" + "@biomejs/cli-linux-x64-musl" "1.6.4" + "@biomejs/cli-win32-arm64" "1.6.4" + "@biomejs/cli-win32-x64" "1.6.4" + +"@biomejs/cli-darwin-arm64@1.6.4": + version "1.6.4" + resolved "https://registry.yarnpkg.com/@biomejs/cli-darwin-arm64/-/cli-darwin-arm64-1.6.4.tgz#a2b07cacb0d2769ae5545b6a3cf40907fbfd4ab0" + integrity sha512-2WZef8byI9NRzGajGj5RTrroW9BxtfbP9etigW1QGAtwu/6+cLkdPOWRAs7uFtaxBNiKFYA8j/BxV5zeAo5QOQ== + +"@biomejs/cli-darwin-x64@1.6.4": + version "1.6.4" + resolved "https://registry.yarnpkg.com/@biomejs/cli-darwin-x64/-/cli-darwin-x64-1.6.4.tgz#476720d731864508312b12fbef62a35609ef5f96" + integrity sha512-uo1zgM7jvzcoDpF6dbGizejDLCqNpUIRkCj/oEK0PB0NUw8re/cn1EnxuOLZqDpn+8G75COLQTOx8UQIBBN/Kg== + +"@biomejs/cli-linux-arm64-musl@1.6.4": + version "1.6.4" + resolved "https://registry.yarnpkg.com/@biomejs/cli-linux-arm64-musl/-/cli-linux-arm64-musl-1.6.4.tgz#403f5889a4ec290e35a0b910c1c26723373cf5fc" + integrity sha512-Hp8Jwt6rjj0wCcYAEN6/cfwrrPLLlGOXZ56Lei4Pt4jy39+UuPeAVFPeclrrCfxyL1wQ2xPrhd/saTHSL6DoJg== + +"@biomejs/cli-linux-arm64@1.6.4": + version "1.6.4" + resolved "https://registry.yarnpkg.com/@biomejs/cli-linux-arm64/-/cli-linux-arm64-1.6.4.tgz#7eff2af0fc5d9af9affc963bb594ec2ebf89668f" + integrity sha512-wAOieaMNIpLrxGc2/xNvM//CIZg7ueWy3V5A4T7gDZ3OL/Go27EKE59a+vMKsBCYmTt7jFl4yHz0TUkUbodA/w== + +"@biomejs/cli-linux-x64-musl@1.6.4": + version "1.6.4" + resolved "https://registry.yarnpkg.com/@biomejs/cli-linux-x64-musl/-/cli-linux-x64-musl-1.6.4.tgz#aeca8dd886b19b7779dfb43898ec896c71da279f" + integrity sha512-wqi0hr8KAx5kBO0B+m5u8QqiYFFBJOSJVSuRqTeGWW+GYLVUtXNidykNqf1JsW6jJDpbkSp2xHKE/bTlVaG2Kg== + +"@biomejs/cli-linux-x64@1.6.4": + version "1.6.4" + resolved "https://registry.yarnpkg.com/@biomejs/cli-linux-x64/-/cli-linux-x64-1.6.4.tgz#545b205dea20195b1fa64f5a0e60331a70133518" + integrity sha512-qTWhuIw+/ePvOkjE9Zxf5OqSCYxtAvcTJtVmZT8YQnmY2I62JKNV2m7tf6O5ViKZUOP0mOQ6NgqHKcHH1eT8jw== + +"@biomejs/cli-win32-arm64@1.6.4": + version "1.6.4" + resolved "https://registry.yarnpkg.com/@biomejs/cli-win32-arm64/-/cli-win32-arm64-1.6.4.tgz#2c377c0965749d01280baac6cb273bcbe11cd652" + integrity sha512-Wp3FiEeF6v6C5qMfLkHwf4YsoNHr/n0efvoC8jCKO/kX05OXaVExj+1uVQ1eGT7Pvx0XVm/TLprRO0vq/V6UzA== + +"@biomejs/cli-win32-x64@1.6.4": + version "1.6.4" + resolved "https://registry.yarnpkg.com/@biomejs/cli-win32-x64/-/cli-win32-x64-1.6.4.tgz#317fed21b863d43778665d42a41cbd0f94351051" + integrity sha512-mz183Di5hTSGP7KjNWEhivcP1wnHLGmOxEROvoFsIxMYtDhzJDad4k5gI/1JbmA0xe4n52vsgqo09tBhrMT/Zg== + "@crowdin/cli@^3.6.5": version "3.19.2" resolved "https://registry.yarnpkg.com/@crowdin/cli/-/cli-3.19.2.tgz#d81d85c78d7235c6c273bae72c93631dc0aedab6" @@ -7804,11 +7858,6 @@ prelude-ls@^1.2.1: resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== -prettier@3.2.5: - version "3.2.5" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-3.2.5.tgz#e52bc3090586e824964a8813b09aba6233b28368" - integrity sha512-3/GWa9aOC0YeD7LUfvOG2NiDyhOWRvt1k+rcKhOuYnMY24iiCphgneUfJDyFXd6rZCAnuLBv6UeAULtrhT/F4A== - pretty-bytes@^5.3.0: version "5.6.0" resolved "https://registry.yarnpkg.com/pretty-bytes/-/pretty-bytes-5.6.0.tgz#356256f643804773c82f64723fe78c92c62beaeb" From 5a7283682da9fc5c9f83426e443a1f7b600554ab Mon Sep 17 00:00:00 2001 From: curtisy Date: Sun, 14 Apr 2024 13:59:35 +0200 Subject: [PATCH 02/21] chore: add biome to recommended extensions and settings --- .vscode/extensions.json | 4 ++-- .vscode/settings.json | 19 ++++++++++--------- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/.vscode/extensions.json b/.vscode/extensions.json index d17b7472..0ad22a49 100644 --- a/.vscode/extensions.json +++ b/.vscode/extensions.json @@ -1,7 +1,7 @@ { "recommendations": [ "kimlimjustin.jsdoc-generator", - "esbenp.prettier-vscode", - "orta.vscode-jest" + "orta.vscode-jest", + "biomejs.biome" ] } diff --git a/.vscode/settings.json b/.vscode/settings.json index a795ea8d..2b478d5f 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,11 +1,12 @@ { - "eslint.format.enable": true, - "editor.codeActionsOnSave": { - "source.fixAll.eslint": "explicit" - }, - "editor.defaultFormatter": "esbenp.prettier-vscode", - "editor.formatOnSave": true, - "[rust]": { - "editor.defaultFormatter": "rust-lang.rust" - } + "eslint.format.enable": true, + "editor.codeActionsOnSave": { + "source.fixAll.eslint": "explicit", + "source.organizeImports.biome": "explicit" + }, + "editor.defaultFormatter": "biomejs.biome", + "editor.formatOnSave": true, + "[rust]": { + "editor.defaultFormatter": "rust-lang.rust" + } } From 1c1d913f607abcbe1e6c2225dc0a62ef7b71340e Mon Sep 17 00:00:00 2001 From: curtisy Date: Sun, 14 Apr 2024 17:19:57 +0200 Subject: [PATCH 03/21] style: apply biome style/noUselessElse rule --- src/Components/Files/File Operation/paste.ts | 3 +-- src/Components/Files/File Operation/redo.ts | 3 +-- src/Components/Files/File Operation/search.ts | 2 +- src/Components/Files/File Operation/undo.ts | 3 +-- src/Components/Functions/changePosition.ts | 2 +- src/Components/Functions/extractExeIcon.ts | 3 +-- src/Components/Functions/validChecker.ts | 10 +++++----- src/Components/Preview/index.tsx | 17 ++++++++--------- src/Components/Thumbnail/thumbnail.ts | 10 ++++------ src/Service/app.ts | 3 +-- src/Service/clipboard.ts | 6 ++---- src/Service/directory.ts | 6 ++---- src/Service/files.ts | 12 ++++-------- src/Service/operation.ts | 3 +-- src/Service/storage.ts | 12 ++++-------- src/Service/window.ts | 3 +-- src/Services/FilesService.ts | 2 +- 17 files changed, 39 insertions(+), 61 deletions(-) diff --git a/src/Components/Files/File Operation/paste.ts b/src/Components/Files/File Operation/paste.ts index a85db289..5357da6d 100644 --- a/src/Components/Files/File Operation/paste.ts +++ b/src/Components/Files/File Operation/paste.ts @@ -61,9 +61,8 @@ const Paste = async (target: string): Promise => { )) ) return; - else { + await new OperationAPI(dest).unlink(); - } } await new OperationAPI(file, dest).cut(); break; diff --git a/src/Components/Files/File Operation/redo.ts b/src/Components/Files/File Operation/redo.ts index f7792a12..62eb728c 100644 --- a/src/Components/Files/File Operation/redo.ts +++ b/src/Components/Files/File Operation/redo.ts @@ -38,9 +38,8 @@ const Redo = async (): Promise => { )) ) return; - else { + await new OperationAPI(dest).unlink(); - } } await new OperationAPI(source, dest).rename(); } diff --git a/src/Components/Files/File Operation/search.ts b/src/Components/Files/File Operation/search.ts index 137679f8..e4fa3e2b 100644 --- a/src/Components/Files/File Operation/search.ts +++ b/src/Components/Files/File Operation/search.ts @@ -91,7 +91,7 @@ const Search = async (): Promise => { clearTimeout(listener); if (e.ctrlKey && e.key === "f") { return; - } else if (e.key === "Enter") { + }if (e.key === "Enter") { const value = (e.target as HTMLInputElement).value; if (value !== being_watch) { processSearch(value, await getFocusingPath()); diff --git a/src/Components/Files/File Operation/undo.ts b/src/Components/Files/File Operation/undo.ts index e396df28..2f8b898e 100644 --- a/src/Components/Files/File Operation/undo.ts +++ b/src/Components/Files/File Operation/undo.ts @@ -40,9 +40,8 @@ const Undo = async (): Promise => { )) ) return; - else { + await new OperationAPI(source).unlink(); - } } await new OperationAPI(dest, source).rename(); break; diff --git a/src/Components/Functions/changePosition.ts b/src/Components/Functions/changePosition.ts index 8c5801a1..a9adfe26 100644 --- a/src/Components/Functions/changePosition.ts +++ b/src/Components/Functions/changePosition.ts @@ -23,7 +23,7 @@ const changePosition = async (newPath: string, forceChange = false, writeHistory if (newPath === _focusingTab.history[_focusingTab.currentIndex] && !forceChange) { return; - } else if (newPath === _focusingTab.history[_focusingTab.currentIndex + 1]) { + }if (newPath === _focusingTab.history[_focusingTab.currentIndex + 1]) { _focusingTab.currentIndex += 1; } else if (newPath === _focusingTab.history[_focusingTab.currentIndex - 1]) { _focusingTab.currentIndex -= 1; diff --git a/src/Components/Functions/extractExeIcon.ts b/src/Components/Functions/extractExeIcon.ts index 7478b296..cb066e17 100644 --- a/src/Components/Functions/extractExeIcon.ts +++ b/src/Components/Functions/extractExeIcon.ts @@ -19,10 +19,9 @@ const extractExeIcon = (filePath: string): string => { // Cache the icon parsed from the exe if (fs.existsSync(ICON_FILE_NAME)) { return ICON_FILE_NAME; - } else { + } const buffer = extractIcon(filePath, "large"); fs.writeFileSync(ICON_FILE_NAME, buffer); return ICON_FILE_NAME; - } }; export default extractExeIcon; diff --git a/src/Components/Functions/validChecker.ts b/src/Components/Functions/validChecker.ts index 56d0dc71..617c98c9 100644 --- a/src/Components/Functions/validChecker.ts +++ b/src/Components/Functions/validChecker.ts @@ -7,13 +7,13 @@ */ const IsValid = (obj: any): boolean => { if (obj === null || obj === undefined) return false; - else if (Array.isArray(obj)) { + if (Array.isArray(obj)) { if (obj.length === 0) return false; - else return true; - } else if (typeof obj === "object") { + return true; + }if (typeof obj === "object") { if (Object.keys(obj).length === 0) return false; - else return true; - } else if (obj) return true; + return true; + }if (obj) return true; return false; }; export default IsValid; diff --git a/src/Components/Preview/index.tsx b/src/Components/Preview/index.tsx index 78d10e40..361117a7 100644 --- a/src/Components/Preview/index.tsx +++ b/src/Components/Preview/index.tsx @@ -45,23 +45,22 @@ const Preview = ({ filePath }: IPreviewProps): JSX.Element => { if (extensionMatches(PDF_TYPES, extension)) { return ; - } else if (extensionMatches(HTML_TYPES, extension)) { + }if (extensionMatches(HTML_TYPES, extension)) { return ; - } else if (extensionMatches(DOCX_TYPES, extension)) { + }if (extensionMatches(DOCX_TYPES, extension)) { return ; - } else if (extensionMatches(XLSX_TYPES, extension)) { + }if (extensionMatches(XLSX_TYPES, extension)) { return ; - } else if (extensionMatches(IMAGE_TYPES, extension)) { + }if (extensionMatches(IMAGE_TYPES, extension)) { return ; - } else if (extensionMatches(VIDEO_TYPES, extension)) { + }if (extensionMatches(VIDEO_TYPES, extension)) { return ; - } else if (extensionMatches(PLAINTEXT_TYPES, extension)) { + }if (extensionMatches(PLAINTEXT_TYPES, extension)) { return ; - } else if (extensionMatches(MARKDOWN_TYPES, extension)) { + }if (extensionMatches(MARKDOWN_TYPES, extension)) { return ; - } else { - return
{JSON.stringify(file)}
; } + return
{JSON.stringify(file)}
; }; export default Preview; diff --git a/src/Components/Thumbnail/thumbnail.ts b/src/Components/Thumbnail/thumbnail.ts index e503b0fc..4a8d37a4 100644 --- a/src/Components/Thumbnail/thumbnail.ts +++ b/src/Components/Thumbnail/thumbnail.ts @@ -81,13 +81,12 @@ const fileThumbnail = async (filePath: string, category = "folder", HTMLFormat = if (IMAGE_TYPES.indexOf(ext) !== -1) { if (imageAsThumbnail) { return imageThumbnail(filePath, HTMLFormat, true); - } else { - return imageThumbnail(DEFAULT_IMAGE_THUMBNAIL, HTMLFormat); } - } else if (VIDEO_TYPES.indexOf(ext) !== -1) { + return imageThumbnail(DEFAULT_IMAGE_THUMBNAIL, HTMLFormat); + }if (VIDEO_TYPES.indexOf(ext) !== -1) { const assetSrc = new FileAPI(filePath).readAsset(); return HTMLFormat ? await videoPreview(assetSrc) : assetSrc; - } else if ((appearance?.extractExeIcon ?? false) && (ext === "exe" || ext === "msi")) { + }if ((appearance?.extractExeIcon ?? false) && (ext === "exe" || ext === "msi")) { return imageThumbnail(await new FileAPI(filePath).extractIcon(), HTMLFormat, true); } } @@ -102,7 +101,7 @@ const fileThumbnail = async (filePath: string, category = "folder", HTMLFormat = filenameThumbnailTrie.search(basename) ?? extensionThumbnailTrie.search(ext) ?? defaultThumbnail.DEFAULT_FILE_THUMBNAIL, HTMLFormat, ); - } else { + } if (category !== "folder") { const _key = `${category}-${filename}`; if (Object.keys(customThumbnail).indexOf(_key) !== -1) { @@ -110,7 +109,6 @@ const fileThumbnail = async (filePath: string, category = "folder", HTMLFormat = } } return imageThumbnail(folderThumbnailTrie.search(basename) ?? defaultThumbnail.DEFAULT_FOLDER_THUMBNAIL, HTMLFormat); - } }; export default fileThumbnail; diff --git a/src/Service/app.ts b/src/Service/app.ts index a1085db5..3e3f0354 100644 --- a/src/Service/app.ts +++ b/src/Service/app.ts @@ -20,10 +20,9 @@ const getAvailableFonts = async (): Promise => { if (isTauri) { const { invoke } = require("@tauri-apps/api"); return await invoke("get_available_fonts"); - } else { + } const fonts = await (await fetch(GET_AVAILABLE_FONTS_ENDPOINT, { method: "GET" })).json(); return fonts; - } }; let listened = false; const listenStylesheetChange = async (cb: (stylesheet: JSON) => void): Promise => { diff --git a/src/Service/clipboard.ts b/src/Service/clipboard.ts index 205f28ab..d6ada8b9 100644 --- a/src/Service/clipboard.ts +++ b/src/Service/clipboard.ts @@ -9,9 +9,8 @@ const writeTextToClipboard = async (text: string): Promise => { if (isTauri) { const { clipboard } = require("@tauri-apps/api"); return await clipboard.writeText(text); - } else { - return await navigator.clipboard.writeText(text); } + return await navigator.clipboard.writeText(text); }; /** @@ -22,8 +21,7 @@ const readTextFromClipboard = async (): Promise => { if (isTauri) { const { clipboard } = require("@tauri-apps/api"); return await clipboard.readText(); - } else { - return await navigator.clipboard.readText(); } + return await navigator.clipboard.readText(); }; export { writeTextToClipboard, readTextFromClipboard }; diff --git a/src/Service/directory.ts b/src/Service/directory.ts index 639d11a7..3b433aa4 100644 --- a/src/Service/directory.ts +++ b/src/Service/directory.ts @@ -80,10 +80,9 @@ class DirectoryAPI { if (isTauri) { const { invoke } = require("@tauri-apps/api"); return await invoke("file_exist", { filePath: this.dirName }); - } else { + } const exists = await (await fetch(CHECK_EXIST_ENDPOINT + this.dirName, { method: "GET" })).json(); return exists; - } } /** * Create dir if not exists @@ -135,10 +134,9 @@ class DirectoryAPI { if (isTauri) { const { invoke } = require("@tauri-apps/api"); return await invoke("get_dir_size", { dir: this.dirName }); - } else { + } const size = await (await fetch(GET_DIR_SIZE_ENDPOINT + this.dirName, { method: "GET" })).json(); return size; - } } /** diff --git a/src/Service/files.ts b/src/Service/files.ts index 0d742ced..570c4f73 100644 --- a/src/Service/files.ts +++ b/src/Service/files.ts @@ -59,10 +59,9 @@ class FileAPI { if (isTauri) { const { invoke } = require("@tauri-apps/api"); return await invoke("open_file", { filePath: this.fileName }); - } else { + } await fetch(OPEN_FILE_ENDPOINT + this.fileName, { method: "GET" }); return; - } } /** * Get tauri url of local assets @@ -91,10 +90,9 @@ class FileAPI { if (isTauri) { const { invoke } = require("@tauri-apps/api"); return await invoke("file_exist", { filePath: this.fileName }); - } else { + } const exists = await (await fetch(CHECK_EXIST_ENDPOINT + this.fileName, { method: "GET" })).json(); return exists; - } } /** * Create file if it doesn't exist @@ -108,9 +106,8 @@ class FileAPI { dirPath: dirname(this.fileName), }); return await invoke("create_file", { filePath: this.fileName }); - } else { - return; } + return; } } /** @@ -162,12 +159,11 @@ class FileAPI { return await invoke("calculate_files_total_size", { files: this.fileName, }); - } else { + } const paths = Array.isArray(this.fileName) ? this.fileName.join("%2c-%2c") : this.fileName; console.log(paths); const size = await (await fetch(CALCULATE_DIRS_SIZE_ENDPOINT + paths, { method: "GET" })).json(); return size; - } } /** diff --git a/src/Service/operation.ts b/src/Service/operation.ts index d910c84d..1a0f5c7d 100644 --- a/src/Service/operation.ts +++ b/src/Service/operation.ts @@ -47,9 +47,8 @@ class OperationAPI { const { invoke } = require("@tauri-apps/api"); if (await new DirectoryAPI(this.src).isDir()) { return await invoke("remove_dir", { path: this.src }); - } else { - return await invoke("remove_file", { path: this.src }); } + return await invoke("remove_file", { path: this.src }); } } diff --git a/src/Service/storage.ts b/src/Service/storage.ts index c536bac6..653cd306 100644 --- a/src/Service/storage.ts +++ b/src/Service/storage.ts @@ -16,10 +16,9 @@ const set = async (key: string, value: any): Promise => { data[key] = value; const { invoke } = require("@tauri-apps/api"); return await invoke("write_data", { key, value }); - } else { + } data[key] = value; localStorage.setItem(key, JSON.stringify(value)); - } }; /** @@ -35,22 +34,19 @@ const get = async (key: string, force?: boolean): Promise => { } if (Object.keys(data).includes(key) && !force) { return data[key]; - } else { + } if (isTauri) { const { invoke } = require("@tauri-apps/api"); const returnedData = (await invoke("read_data", { key })) as returnedType; data[key] = returnedData.data; return returnedData.status ? returnedData.data : {}; - } else { + } const storedData = localStorage.getItem(key); if (storedData) { data[key] = JSON.parse(storedData); return data[key]; - } else { - return {}; } - } - } + return {}; }; /** diff --git a/src/Service/window.ts b/src/Service/window.ts index 43dbceca..5e23c51e 100644 --- a/src/Service/window.ts +++ b/src/Service/window.ts @@ -15,13 +15,12 @@ const listenWindowClose = (): Promise => { appWindow.close(); }); }); - } else { + } return new Promise((resolve) => { window.addEventListener("beforeunload", () => { resolve(); }); }); - } }; const createNewWindow = (): void => { diff --git a/src/Services/FilesService.ts b/src/Services/FilesService.ts index c33c4154..1c17bf27 100644 --- a/src/Services/FilesService.ts +++ b/src/Services/FilesService.ts @@ -100,7 +100,7 @@ export const cutFile = async (fileName: string, dest: string): Promise => */ export const removeFile = async (fileName: string): Promise => { if (isDirectory(fileName)) return removeNative(fileName, { recursive: true }); - else return removeNative(fileName); + return removeNative(fileName); }; /** From eff04c4c428d5114854d06f31926e727d8970e98 Mon Sep 17 00:00:00 2001 From: curtisy Date: Sun, 14 Apr 2024 17:21:09 +0200 Subject: [PATCH 04/21] style: apply biome style/useSelfClosingElements rule --- src/Components/ContextMenu/index.tsx | 4 ++-- src/Components/Header/index.tsx | 6 +++--- src/Components/LoadingBar/index.tsx | 2 +- src/Components/Properties/index.tsx | 2 +- src/Components/SettingsView/index.tsx | 4 ++-- src/Components/Sidebar/index.tsx | 4 ++-- src/components/Infobar/index.tsx | 2 +- 7 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/Components/ContextMenu/index.tsx b/src/Components/ContextMenu/index.tsx index ed6a014e..c315015a 100644 --- a/src/Components/ContextMenu/index.tsx +++ b/src/Components/ContextMenu/index.tsx @@ -2,8 +2,8 @@ import React from "react"; const ContextMenu = () => ( <> -
-
+
+
); diff --git a/src/Components/Header/index.tsx b/src/Components/Header/index.tsx index 064c235f..3ba0423c 100644 --- a/src/Components/Header/index.tsx +++ b/src/Components/Header/index.tsx @@ -72,19 +72,19 @@ const Header = () => { id="minimize" title="Minimize" onClick={() => dispatch(minimizeWindowRequest())} - > + /> dispatch(maximizeWindowRequest())} - > + /> dispatch(closeWindowRequest())} - > + /> diff --git a/src/Components/LoadingBar/index.tsx b/src/Components/LoadingBar/index.tsx index cb24124a..0c8950d6 100644 --- a/src/Components/LoadingBar/index.tsx +++ b/src/Components/LoadingBar/index.tsx @@ -6,7 +6,7 @@ export interface ILoadingBarProps { const LoadingBar = ({ isLoading }: ILoadingBarProps) => (
- +
); diff --git a/src/Components/Properties/index.tsx b/src/Components/Properties/index.tsx index 3b50e36f..2f689de4 100644 --- a/src/Components/Properties/index.tsx +++ b/src/Components/Properties/index.tsx @@ -6,7 +6,7 @@ const Properties = () => ( Properties ×
-
+
); diff --git a/src/Components/SettingsView/index.tsx b/src/Components/SettingsView/index.tsx index e44b49d0..82e7cefd 100644 --- a/src/Components/SettingsView/index.tsx +++ b/src/Components/SettingsView/index.tsx @@ -7,9 +7,9 @@ const SettingsView = () => ( Settings
-
+
-
+
); diff --git a/src/Components/Sidebar/index.tsx b/src/Components/Sidebar/index.tsx index 676e0ac3..6cf6a6c5 100644 --- a/src/Components/Sidebar/index.tsx +++ b/src/Components/Sidebar/index.tsx @@ -48,7 +48,7 @@ const Sidebar = () => { onClick={() => navigateToPath(path)} key={path + name} > -
+
{name} @@ -70,7 +70,7 @@ const Sidebar = () => { onClick={() => navigateToPath(mount_point.replace(/\\/g, "/"))} key={mount_point + name} > -
+
{name} diff --git a/src/components/Infobar/index.tsx b/src/components/Infobar/index.tsx index b862ae3d..dd4b2d7e 100644 --- a/src/components/Infobar/index.tsx +++ b/src/components/Infobar/index.tsx @@ -28,7 +28,7 @@ const Infobar = () => { ) : null} - + ); From cc4853891ed5aa253b181fd3edd196ddcddb41d9 Mon Sep 17 00:00:00 2001 From: curtisy Date: Sun, 14 Apr 2024 17:22:13 +0200 Subject: [PATCH 05/21] style: apply biome style/noUnusedTemplateLiteral rule --- src/Components/ContextMenu/contextMenu.ts | 2 +- src/Components/Drives/drives.ts | 4 ++-- src/Components/Files/File Operation/trash.ts | 2 +- src/Components/Layout/sidebar.ts | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Components/ContextMenu/contextMenu.ts b/src/Components/ContextMenu/contextMenu.ts index 82b0ca37..755fe5b9 100644 --- a/src/Components/ContextMenu/contextMenu.ts +++ b/src/Components/ContextMenu/contextMenu.ts @@ -95,7 +95,7 @@ const MenuToElements = async (menu: contextMenuItem[][]): Promise => { } } } - if (index !== menu.length - 1 && section.filter((menu) => menu.visible !== false).length > 0) contextMenu.innerHTML += `
`; + if (index !== menu.length - 1 && section.filter((menu) => menu.visible !== false).length > 0) contextMenu.innerHTML += "
"; } return; }; diff --git a/src/Components/Drives/drives.ts b/src/Components/Drives/drives.ts index 8c41df49..3f105c8d 100644 --- a/src/Components/Drives/drives.ts +++ b/src/Components/Drives/drives.ts @@ -91,9 +91,9 @@ const writeSidebarDriveItems = async (): Promise => { `\n` + ` \n` + + "
\n" + ` ${driveName}\n` + - ``; + ""; } const sidebar = await Storage.get("sidebar"); const driveList = driveElement.querySelector(".sidebar-nav-list"); diff --git a/src/Components/Files/File Operation/trash.ts b/src/Components/Files/File Operation/trash.ts index a1739f4b..17eadf45 100644 --- a/src/Components/Files/File Operation/trash.ts +++ b/src/Components/Files/File Operation/trash.ts @@ -48,7 +48,7 @@ const Trash = async (filePaths: string[]): Promise => { try { DeleteFiles(filePaths); } catch (err) { - PromptError("Failed to delete files/dirs", `Failed to move ` + filePaths.join(", ") + ` to trash. [${err}]`); + PromptError("Failed to delete files/dirs", "Failed to move " + filePaths.join(", ") + ` to trash. [${err}]`); } if (platform !== "darwin") { OperationLog("delete", filePaths); diff --git a/src/Components/Layout/sidebar.ts b/src/Components/Layout/sidebar.ts index 9229ec9c..81dc1986 100644 --- a/src/Components/Layout/sidebar.ts +++ b/src/Components/Layout/sidebar.ts @@ -46,9 +46,9 @@ const writeFavoriteItems = async (favorites: Favorites[]): Promise => { `\n` + ` \n` + + "
\n" + ` ${await Translate(favorite.name)}\n` + - `\n`; + "\n"; } const favoriteElement = document.querySelector("#sidebar-favorites"); const favoriteBtnText = favoriteElement.querySelector(".sidebar-text"); From 31c35ef8eb12e4be5c1f0946fb1d584bdd6f1744 Mon Sep 17 00:00:00 2001 From: curtisy Date: Sun, 14 Apr 2024 17:29:48 +0200 Subject: [PATCH 06/21] style: apply biome style/useConst rule --- src/Components/Files/File Operation/cut.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Components/Files/File Operation/cut.ts b/src/Components/Files/File Operation/cut.ts index 1cd5fedb..816dd245 100644 --- a/src/Components/Files/File Operation/cut.ts +++ b/src/Components/Files/File Operation/cut.ts @@ -12,6 +12,7 @@ const Cut = (files: Array): void => { } (async function detectClipboardChange() { + // biome-ignore lint/style/useConst: Recursively assigned let n: NodeJS.Timeout; //eslint-disable-line if ((await Storage.get("clipboard")).files !== files) { global.clearTimeout(n); From ac6b605244a4b8df4158a0f207655b38815d26bc Mon Sep 17 00:00:00 2001 From: curtisy Date: Sun, 14 Apr 2024 17:30:50 +0200 Subject: [PATCH 07/21] style: apply biome style/useTemplate rule --- src/Components/ContextMenu/contextMenu.ts | 8 ++++---- src/Components/Drives/drives.ts | 11 +++------- src/Components/Files/File Operation/select.ts | 6 +++--- src/Components/Files/File Operation/trash.ts | 2 +- src/Components/Functions/dragElement.ts | 4 ++-- src/Components/Functions/extractExeIcon.ts | 2 +- src/Components/Functions/filesize.ts | 2 +- src/Components/Functions/path/dirname.ts | 2 +- .../Functions/path/normalizeSlash.ts | 2 +- src/Components/Layout/hover.ts | 4 ++-- src/Components/Layout/resizer.ts | 20 +++++++++---------- src/Components/Layout/sidebar.ts | 7 +------ src/Components/Open/displayFiles.ts | 6 +++--- src/Components/Open/recent.ts | 6 +++--- src/Components/Setting/About/about.ts | 6 +++--- .../Setting/Appearance/Appearance.ts | 4 ++-- src/Components/Shortcut/shortcut.ts | 2 +- src/Components/Thumbnail/thumbnail.ts | 2 +- src/Helpers/paths.ts | 2 +- src/Service/locales.ts | 2 +- src/Service/operation.ts | 2 +- src/Services/DirectoryService.ts | 2 +- src/Util/constants.ts | 20 +++++++++---------- src/components/Theme/_theme.ts | 14 ++++++------- 24 files changed, 64 insertions(+), 74 deletions(-) diff --git a/src/Components/ContextMenu/contextMenu.ts b/src/Components/ContextMenu/contextMenu.ts index 755fe5b9..0eb4ea92 100644 --- a/src/Components/ContextMenu/contextMenu.ts +++ b/src/Components/ContextMenu/contextMenu.ts @@ -155,8 +155,8 @@ const ContextMenu = (): void => { contextMenu.style.overflowY = "auto"; } - contextMenu.style.left = coorX + "px"; - contextMenu.style.top = coorY + "px"; + contextMenu.style.left = `${coorX}px`; + contextMenu.style.top = `${coorY}px`; contextMenu.scrollTop = 0; document.addEventListener("click", exitContextMenu); @@ -206,8 +206,8 @@ const ContextMenu = (): void => { }px`; submenuElement.style.overflowY = "auto"; } - submenuElement.style.left = submenuCoorX + "px"; - submenuElement.style.top = menuCoordinate.top + "px"; + submenuElement.style.left = `${submenuCoorX}px`; + submenuElement.style.top = `${menuCoordinate.top}px`; submenuElement.scrollTop = 0; } }); diff --git a/src/Components/Drives/drives.ts b/src/Components/Drives/drives.ts index 3f105c8d..8c7293bf 100644 --- a/src/Components/Drives/drives.ts +++ b/src/Components/Drives/drives.ts @@ -37,7 +37,7 @@ const drivesToElements = async (drives: Drive[]): Promise => { : `

${driveName}

` }

${formatBytes(drive.available_space)} ${await Translate("free of")} ${formatBytes(drive.total_space)}

@@ -83,17 +83,12 @@ const writeSidebarDriveItems = async (): Promise => { if (platform === "win32") { const hasName = drive.name && /[^?]/.test(drive.name); driveName = hasName ? drive.name : drive.disk_type; - driveName += " (" + drive.mount_point.replace(/\\$/g, "") + ")"; + driveName += ` (${drive.mount_point.replace(/\\$/g, "")})`; } else driveName = drive.mount_point.split("/").at(-1); const driveType = drive.is_removable ? "usb" : "hard-disk"; const iconPath = await fileThumbnail(driveType, "favorites", false); content += - `\n` + - ` \n" + - ` ${driveName}\n` + - ""; + `\n \n ${driveName}\n`; } const sidebar = await Storage.get("sidebar"); const driveList = driveElement.querySelector(".sidebar-nav-list"); diff --git a/src/Components/Files/File Operation/select.ts b/src/Components/Files/File Operation/select.ts index 94ddf3d5..a6f0d014 100644 --- a/src/Components/Files/File Operation/select.ts +++ b/src/Components/Files/File Operation/select.ts @@ -174,7 +174,7 @@ const SelectInit = (): void => { selectingOrigin = new Point(e.pageX - mainBoxBounds.left, e.pageY - mainBoxBounds.top); if (!(e.target as HTMLElement).className.split(" ").some((c) => /file/.test(c))) { MAIN_BOX_EL.prepend(selectingDiv); - selectingDiv.style.inset = selectingOrigin.y + "px auto " + selectingOrigin.x + "px auto"; + selectingDiv.style.inset = `${selectingOrigin.y}px auto ${selectingOrigin.x}px auto`; selectingDiv.style.width = selectingDiv.style.height = "auto"; } }); @@ -249,8 +249,8 @@ const SelectInit = (): void => { (bottom == "auto" ? " " : "px ") + left + (left == "auto" ? " " : "px "); - selectingDiv.style.height = height + "px"; - selectingDiv.style.width = width + "px"; + selectingDiv.style.height = `${height}px`; + selectingDiv.style.width = `${width}px`; const FILES = MAIN_BOX_EL.getElementsByClassName("file"); diff --git a/src/Components/Files/File Operation/trash.ts b/src/Components/Files/File Operation/trash.ts index 17eadf45..8a9ceff6 100644 --- a/src/Components/Files/File Operation/trash.ts +++ b/src/Components/Files/File Operation/trash.ts @@ -48,7 +48,7 @@ const Trash = async (filePaths: string[]): Promise => { try { DeleteFiles(filePaths); } catch (err) { - PromptError("Failed to delete files/dirs", "Failed to move " + filePaths.join(", ") + ` to trash. [${err}]`); + PromptError("Failed to delete files/dirs", `Failed to move ${filePaths.join(", ")} to trash. [${err}]`); } if (platform !== "darwin") { OperationLog("delete", filePaths); diff --git a/src/Components/Functions/dragElement.ts b/src/Components/Functions/dragElement.ts index 3d468bce..cb8d1504 100644 --- a/src/Components/Functions/dragElement.ts +++ b/src/Components/Functions/dragElement.ts @@ -34,9 +34,9 @@ function dragElement(elmnt: HTMLElement, parentElement: HTMLElement): void { const y = parentElement.offsetTop - parentElement.offsetHeight / 2; // set the element's new position: if (y - pos2 >= 0 && y + parentElement.offsetHeight - pos2 <= window.innerHeight) - parentElement.style.top = parentElement.offsetTop - pos2 + "px"; + parentElement.style.top = `${parentElement.offsetTop - pos2}px`; if (x - pos1 >= 0 && x + parentElement.offsetWidth - pos1 <= window.innerWidth) - parentElement.style.left = parentElement.offsetLeft - pos1 + "px"; + parentElement.style.left = `${parentElement.offsetLeft - pos1}px`; } function closeDragElement() { diff --git a/src/Components/Functions/extractExeIcon.ts b/src/Components/Functions/extractExeIcon.ts index cb066e17..54a01b19 100644 --- a/src/Components/Functions/extractExeIcon.ts +++ b/src/Components/Functions/extractExeIcon.ts @@ -14,7 +14,7 @@ const extractExeIcon = (filePath: string): string => { } fs.mkdirSync(EXE_ICON_CACHE_DIR); } - const ICON_FILE_NAME = path.join(EXE_ICON_CACHE_DIR, basename + ".ico"); + const ICON_FILE_NAME = path.join(EXE_ICON_CACHE_DIR, `${basename}.ico`); // Cache the icon parsed from the exe if (fs.existsSync(ICON_FILE_NAME)) { diff --git a/src/Components/Functions/filesize.ts b/src/Components/Functions/filesize.ts index 517cca59..ecc90da5 100644 --- a/src/Components/Functions/filesize.ts +++ b/src/Components/Functions/filesize.ts @@ -11,7 +11,7 @@ const formatBytes = (bytes: number): string => { const dm = 2; // Decimal digit const sizes = ["Bytes", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"]; const i = Math.floor(Math.log(bytes) / Math.log(k)); - return Number.parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + " " + sizes[i]; + return `${Number.parseFloat((bytes / Math.pow(k, i)).toFixed(dm))} ${sizes[i]}`; }; export default formatBytes; diff --git a/src/Components/Functions/path/dirname.ts b/src/Components/Functions/path/dirname.ts index 385b0bc2..f122b7fc 100644 --- a/src/Components/Functions/path/dirname.ts +++ b/src/Components/Functions/path/dirname.ts @@ -24,6 +24,6 @@ const getDirname = (path: string): string => { if (end === -1) return hasRoot ? "/" : "."; if (hasRoot && end === 1) return "//"; const result = path.slice(0, end); - if (!(result.endsWith("/") || result.endsWith("\\"))) return result + "/"; + if (!(result.endsWith("/") || result.endsWith("\\"))) return `${result}/`; }; export default getDirname; diff --git a/src/Components/Functions/path/normalizeSlash.ts b/src/Components/Functions/path/normalizeSlash.ts index fbf1d6ab..f3f43a3b 100644 --- a/src/Components/Functions/path/normalizeSlash.ts +++ b/src/Components/Functions/path/normalizeSlash.ts @@ -7,7 +7,7 @@ const NormalizeSlash = (path: string): string => { if (path === "\\" || path === "/") return "/"; path = path.replace(/\\/g, "/"); - if (path.length === 2 && /.:/.test(path)) return path + "/"; + if (path.length === 2 && /.:/.test(path)) return `${path}/`; if (path.endsWith("/") && !(path.length === 3 && /.:\//.test(path))) return path.slice(0, path.length - 1); return path; }; diff --git a/src/Components/Layout/hover.ts b/src/Components/Layout/hover.ts index 8c2288aa..6e1ac795 100644 --- a/src/Components/Layout/hover.ts +++ b/src/Components/Layout/hover.ts @@ -75,8 +75,8 @@ const Hover = (): void => { if (hoverPreviewElement.clientWidth > window.innerWidth) hoverPreviewElement.style.width = `${0.5 * window.innerWidth}px`; if (x + 300 > document.body.offsetWidth) x -= hoverPreviewElement.offsetWidth; if (y + hoverPreviewElement.clientHeight > document.body.offsetHeight) y -= hoverPreviewElement.offsetHeight; - hoverPreviewElement.style.top = y + "px"; - hoverPreviewElement.style.left = x + "px"; + hoverPreviewElement.style.top = `${y}px`; + hoverPreviewElement.style.left = `${x}px`; hoverPreviewElement.dataset.path = target.dataset.path; } }, 500); diff --git a/src/Components/Layout/resizer.ts b/src/Components/Layout/resizer.ts index b1055fed..e2ac544d 100644 --- a/src/Components/Layout/resizer.ts +++ b/src/Components/Layout/resizer.ts @@ -27,25 +27,25 @@ export const updateSidebarParameters = (updateSidebar = false) => { size = (size / sidebarDefaultExpandedSizeOld) * sidebarDefaultExpandedSize; const minimized = size < sidebarMinSnap || appearance.preferMinimizedSidebar; - resizeSidebar((minimized ? sidebarMinSize : size) + "px"); - appearance.expandedSidebarWidth = Math.max(size, sidebarMinSnap) + "px"; + resizeSidebar(`${minimized ? sidebarMinSize : size}px`); + appearance.expandedSidebarWidth = `${Math.max(size, sidebarMinSnap)}px`; Storage.set("appearance", appearance); }; export const resizeSidebar = (size?: string) => { if (!size) { if (sidebar.offsetWidth === sidebarMinSize) { - const defaultSidebarWidth = sidebarDefaultExpandedSize + "px"; + const defaultSidebarWidth = `${sidebarDefaultExpandedSize}px`; size = appearance.expandedSidebarWidth || defaultSidebarWidth; appearance.preferMinimizedSidebar = false; } else { - size = sidebarMinSize + "px"; + size = `${sidebarMinSize}px`; appearance.preferMinimizedSidebar = true; } Storage.set("appearance", appearance); } const root = document.documentElement; - if (size === sidebarMinSize + "px") { + if (size === `${sidebarMinSize}px`) { sidebar.classList.add("sidebar-minimized"); settingsSidebar.classList.add("sidebar-minimized"); root.style.setProperty("--sidebar-minimized-width", size); @@ -67,11 +67,11 @@ export const Resizer = async (): Promise => { settingsSidebar = document.querySelector(".settings-sidebar"); appearance = (await Storage.get("appearance")) || {}; updateSidebarParameters(); - const defaultSidebarWidth = sidebarDefaultExpandedSize + "px"; + const defaultSidebarWidth = `${sidebarDefaultExpandedSize}px`; resizeSidebar(appearance.sidebarWidth || defaultSidebarWidth); const resizeWindow = () => { - if (window.innerWidth < windowMinSize) resizeSidebar(sidebarMinSize + "px"); + if (window.innerWidth < windowMinSize) resizeSidebar(`${sidebarMinSize}px`); else if (!appearance.preferMinimizedSidebar) { resizeSidebar(appearance.expandedSidebarWidth || defaultSidebarWidth); } @@ -92,9 +92,9 @@ export const Resizer = async (): Promise => { type MouseMoveEvent = MouseEvent & { target: HTMLElement }; const { clientX: mx, clientY: my, target } = event as MouseMoveEvent; if (resizing) { - let width = mx + "px"; + let width = `${mx}px`; if (mx < sidebarMinSnap) { - width = sidebarMinSize + "px"; + width = `${sidebarMinSize}px`; appearance.preferMinimizedSidebar = true; } else { appearance.expandedSidebarWidth = width; @@ -109,7 +109,7 @@ export const Resizer = async (): Promise => { const sidebarText = target.querySelector(".sidebar-text"); const { offsetTop: y, offsetHeight: h } = sidebarText; const root = document.documentElement; - root.style.setProperty("--sidebar-text-y", my - y - h / 2 + "px"); + root.style.setProperty("--sidebar-text-y", `${my - y - h / 2}px`); } } const { offsetWidth: w } = sidebar; diff --git a/src/Components/Layout/sidebar.ts b/src/Components/Layout/sidebar.ts index 81dc1986..048bca5a 100644 --- a/src/Components/Layout/sidebar.ts +++ b/src/Components/Layout/sidebar.ts @@ -43,12 +43,7 @@ const writeFavoriteItems = async (favorites: Favorites[]): Promise => { iconCategory = isdir ? "folder" : "file"; } content += - `\n` + - ` \n" + - ` ${await Translate(favorite.name)}\n` + - "\n"; + `\n \n ${await Translate(favorite.name)}\n\n`; } const favoriteElement = document.querySelector("#sidebar-favorites"); const favoriteBtnText = favoriteElement.querySelector(".sidebar-text"); diff --git a/src/Components/Open/displayFiles.ts b/src/Components/Open/displayFiles.ts index ede2eb0a..b5b4d162 100644 --- a/src/Components/Open/displayFiles.ts +++ b/src/Components/Open/displayFiles.ts @@ -85,11 +85,11 @@ const displayFiles = async ( switch (layout) { case "m": fileGrid.classList.add("medium-grid-view"); - displayName = file.basename.length > 30 ? file.basename.substring(0, 30) + "..." : file.basename; + displayName = file.basename.length > 30 ? `${file.basename.substring(0, 30)}...` : file.basename; break; case "l": fileGrid.classList.add("large-grid-view"); - displayName = file.basename.length > 40 ? file.basename.substring(0, 40) + "..." : file.basename; + displayName = file.basename.length > 40 ? `${file.basename.substring(0, 40)}...` : file.basename; break; case "d": fileGrid.classList.add("detail-view"); @@ -97,7 +97,7 @@ const displayFiles = async ( break; default: fileGrid.classList.add("small-grid-view"); - displayName = file.basename.length > 20 ? file.basename.substring(0, 20) + "..." : file.basename; + displayName = file.basename.length > 20 ? `${file.basename.substring(0, 20)}...` : file.basename; break; } if (isSearch) displayName = file.file_path; diff --git a/src/Components/Open/recent.ts b/src/Components/Open/recent.ts index 38a28a49..13fe86cf 100644 --- a/src/Components/Open/recent.ts +++ b/src/Components/Open/recent.ts @@ -87,12 +87,12 @@ const Recent = async (): Promise => { case "m": fileGrid.classList.add("medium-grid-view"); displayName = - recent.properties.basename.length > 30 ? recent.properties.basename.substring(0, 30) + "..." : recent.properties.basename; + recent.properties.basename.length > 30 ? `${recent.properties.basename.substring(0, 30)}...` : recent.properties.basename; break; case "l": fileGrid.classList.add("large-grid-view"); displayName = - recent.properties.basename.length > 40 ? recent.properties.basename.substring(0, 40) + "..." : recent.properties.basename; + recent.properties.basename.length > 40 ? `${recent.properties.basename.substring(0, 40)}...` : recent.properties.basename; break; case "d": fileGrid.classList.add("detail-view"); @@ -101,7 +101,7 @@ const Recent = async (): Promise => { default: fileGrid.classList.add("small-grid-view"); displayName = - recent.properties.basename.length > 20 ? recent.properties.basename.substring(0, 20) + "..." : recent.properties.basename; + recent.properties.basename.length > 20 ? `${recent.properties.basename.substring(0, 20)}...` : recent.properties.basename; break; } fileGrid.setAttribute("draggable", "true"); diff --git a/src/Components/Setting/About/about.ts b/src/Components/Setting/About/about.ts index 43414383..1952ce13 100644 --- a/src/Components/Setting/About/about.ts +++ b/src/Components/Setting/About/about.ts @@ -29,7 +29,7 @@ const About = async (): Promise => { Version: ${version} @@ -37,7 +37,7 @@ const About = async (): Promise => { Tauri version: ${tauriVersion} @@ -45,7 +45,7 @@ const About = async (): Promise => { OS: ${platform} ${arch} ${osVersion} diff --git a/src/Components/Setting/Appearance/Appearance.ts b/src/Components/Setting/Appearance/Appearance.ts index d29c223d..dd90d715 100644 --- a/src/Components/Setting/Appearance/Appearance.ts +++ b/src/Components/Setting/Appearance/Appearance.ts @@ -219,7 +219,7 @@ const Appearance = async (): Promise => { settingsMain.querySelectorAll(".number-ctrl").forEach((ctrl) => { const number = ctrl.querySelector(".number-ctrl-input"); ctrl.querySelector(".number-ctrl-minus").addEventListener("click", () => { - number.value = +number.value - 1 + ""; + number.value = `${+number.value - 1}`; const appearance = _appearance ?? {}; appearance.fontSize = `${number.value}px`; document.body.style.fontSize = `${number.value}px`; @@ -227,7 +227,7 @@ const Appearance = async (): Promise => { Storage.set("appearance", appearance); }); ctrl.querySelector(".number-ctrl-plus").addEventListener("click", () => { - number.value = +number.value + 1 + ""; + number.value = `${+number.value + 1}`; const appearance = _appearance ?? {}; appearance.fontSize = `${number.value}px`; document.body.style.fontSize = `${number.value}px`; diff --git a/src/Components/Shortcut/shortcut.ts b/src/Components/Shortcut/shortcut.ts index d26e789b..2adf8aee 100644 --- a/src/Components/Shortcut/shortcut.ts +++ b/src/Components/Shortcut/shortcut.ts @@ -84,7 +84,7 @@ const Shortcut = (): void => { searchingFileName = ""; } searchingFileName += e.key.toLowerCase(); - searchElement.placeholder = "⚡ " + searchingFileName; + searchElement.placeholder = `⚡ ${searchingFileName}`; searchingFiles = null; resetTimer(); unselectAllSelected(); diff --git a/src/Components/Thumbnail/thumbnail.ts b/src/Components/Thumbnail/thumbnail.ts index 4a8d37a4..4b42dd41 100644 --- a/src/Components/Thumbnail/thumbnail.ts +++ b/src/Components/Thumbnail/thumbnail.ts @@ -93,7 +93,7 @@ const fileThumbnail = async (filePath: string, category = "folder", HTMLFormat = const filename = filePath.toLowerCase(); // Lowercase filename if (category === "contextmenu") { - return imageThumbnail(`contextmenu/${filePath + ".svg"}`); + return imageThumbnail(`contextmenu/${`${filePath}.svg`}`); } if (category === "file") { diff --git a/src/Helpers/paths.ts b/src/Helpers/paths.ts index 8115105a..7e0ff463 100644 --- a/src/Helpers/paths.ts +++ b/src/Helpers/paths.ts @@ -9,7 +9,7 @@ export const dirDelimiter = "/"; */ export const getStandardPath = (path: string): string => { if (!path) return dirDelimiter; - if (path[path.length - 1] !== dirDelimiter) return path + "/"; + if (path[path.length - 1] !== dirDelimiter) return `${path}/`; return path.replaceAll("\\", dirDelimiter); }; diff --git a/src/Service/locales.ts b/src/Service/locales.ts index ad3208df..224a7f07 100644 --- a/src/Service/locales.ts +++ b/src/Service/locales.ts @@ -18,7 +18,7 @@ class LocalesAPI { async build(): Promise { this.AVAILABLE_LOCALES = localesInformation.availableLanguages; for (const locale of Object.values(this.AVAILABLE_LOCALES)) { - const localeJSON = await import("../Locales/" + (locale === "en-US" ? "base" : locale) + ".json"); + const localeJSON = await import(`../Locales/${locale === "en-US" ? "base" : locale}.json`); this.LOCALES[locale] = localeJSON; } } diff --git a/src/Service/operation.ts b/src/Service/operation.ts index 1a0f5c7d..99f86732 100644 --- a/src/Service/operation.ts +++ b/src/Service/operation.ts @@ -54,7 +54,7 @@ class OperationAPI { async duplicate(): Promise { this.dest = - this.src.split(".").length > 1 ? this.src.split(".").slice(0, -1) + " - COPY." + this.src.split(".").slice(-1) : this.src + " - COPY"; + this.src.split(".").length > 1 ? `${this.src.split(".").slice(0, -1)} - COPY.${this.src.split(".").slice(-1)}` : `${this.src} - COPY`; return await this.copyFile(); } } diff --git a/src/Services/DirectoryService.ts b/src/Services/DirectoryService.ts index da30ec0c..38c493f9 100644 --- a/src/Services/DirectoryService.ts +++ b/src/Services/DirectoryService.ts @@ -38,7 +38,7 @@ export const makeDirectory = async (dirPath: string): Promise => invoke export const listenDirectory = (callback: (dirPath: string) => void = () => undefined) => { getCurrent().listen("dir_change", (e: { payload: { path: string } }) => { const path = e.payload.path; - const parent_path = path.split("/").slice(0, -1).join("/") + "/"; + const parent_path = `${path.split("/").slice(0, -1).join("/")}/`; callback(parent_path); }); }; diff --git a/src/Util/constants.ts b/src/Util/constants.ts index 0aba6214..66a7876d 100644 --- a/src/Util/constants.ts +++ b/src/Util/constants.ts @@ -1,14 +1,14 @@ export const SERVICE_ENDPOINT = "http://localhost:3030/"; -export const READ_DIR_ENDPOINT = SERVICE_ENDPOINT + "read_dir?path="; -export const GET_FAVORITES_PATH_ENDPOINT = SERVICE_ENDPOINT + "dir/favorites"; -export const CHECK_EXIST_ENDPOINT = SERVICE_ENDPOINT + "check_exist?path="; -export const CHECK_ISDIR_ENDPOINT = SERVICE_ENDPOINT + "check_isdir?path="; -export const OPEN_FILE_ENDPOINT = SERVICE_ENDPOINT + "open_file?path="; -export const GET_AVAILABLE_FONTS_ENDPOINT = SERVICE_ENDPOINT + "get_available_fonts"; -export const GET_DIR_SIZE_ENDPOINT = SERVICE_ENDPOINT + "get_dir_size?path="; -export const GET_DRIVES_ENDPOINT = SERVICE_ENDPOINT + "drives"; -export const GET_PLATFORM_ENDPOINT = SERVICE_ENDPOINT + "platform"; -export const CALCULATE_DIRS_SIZE_ENDPOINT = SERVICE_ENDPOINT + "calculate_dirs_size?paths="; +export const READ_DIR_ENDPOINT = `${SERVICE_ENDPOINT}read_dir?path=`; +export const GET_FAVORITES_PATH_ENDPOINT = `${SERVICE_ENDPOINT}dir/favorites`; +export const CHECK_EXIST_ENDPOINT = `${SERVICE_ENDPOINT}check_exist?path=`; +export const CHECK_ISDIR_ENDPOINT = `${SERVICE_ENDPOINT}check_isdir?path=`; +export const OPEN_FILE_ENDPOINT = `${SERVICE_ENDPOINT}open_file?path=`; +export const GET_AVAILABLE_FONTS_ENDPOINT = `${SERVICE_ENDPOINT}get_available_fonts`; +export const GET_DIR_SIZE_ENDPOINT = `${SERVICE_ENDPOINT}get_dir_size?path=`; +export const GET_DRIVES_ENDPOINT = `${SERVICE_ENDPOINT}drives`; +export const GET_PLATFORM_ENDPOINT = `${SERVICE_ENDPOINT}platform`; +export const CALCULATE_DIRS_SIZE_ENDPOINT = `${SERVICE_ENDPOINT}calculate_dirs_size?paths=`; export const MAIN_BOX_ELEMENT = () => document.querySelector(".main-box"); export const GET_WORKSPACE_ELEMENT = (id: number) => document.getElementById(`workspace-${id}`); diff --git a/src/components/Theme/_theme.ts b/src/components/Theme/_theme.ts index ad8ee67b..63c34307 100644 --- a/src/components/Theme/_theme.ts +++ b/src/components/Theme/_theme.ts @@ -66,7 +66,7 @@ const changeElementTheme = (element: HTMLElement, variable: string, key: string, * @returns {void} */ const hoverHandler = (obj: HTMLElement, theme: string, type: ElementType) => { - changeElementTheme(obj, type + "Background", "background", theme); + changeElementTheme(obj, `${type}Background`, "background", theme); if (obj.getAttribute("being-listened") === "true") return; obj.setAttribute("being-listened", "true"); obj.addEventListener("mousemove", (e) => { @@ -74,7 +74,7 @@ const hoverHandler = (obj: HTMLElement, theme: string, type: ElementType) => { const x = e.clientX - rect.left; const y = e.clientY - rect.top; if (obj.classList.contains("active")) return (obj.onmouseleave = null); - const color = getElementStyle("animation." + type, currentTheme); + const color = getElementStyle(`animation.${type}`, currentTheme); obj.style.background = `radial-gradient(circle at ${x}px ${y}px, ${color})`; obj.onmouseleave = () => (obj.style.background = obj.style.borderImage = null); }); @@ -125,7 +125,7 @@ const changeTheme = async (theme?: string, category?: Category): Promise = // Generate CSS styles from user theme for (const key of Object.keys(IsValid(themeJSON) ? themeJSON : defaultThemeJSON[theme])) { const value = IsValid(themeJSON) ? themeJSON[key] : defaultThemeJSON[theme]?.[key]; - const formalKey = key.replace(/[A-Z]/g, (m) => "-" + m.toLowerCase()); + const formalKey = key.replace(/[A-Z]/g, (m) => `-${m.toLowerCase()}`); const splittedKey = formalKey.split("."); const styleKey = splittedKey[splittedKey.length - 1]; if (key.startsWith("hljs")) { @@ -143,9 +143,9 @@ const changeTheme = async (theme?: string, category?: Category): Promise = content += `:root { ${styleKey}: ${value}; }\n`; break; } - if (!usingClassName) content += "#" + idName; - else if (className !== "") content += "." + className; - else if (_category !== "root") content += "." + _category; + if (!usingClassName) content += `#${idName}`; + else if (className !== "") content += `.${className}`; + else if (_category !== "root") content += `.${_category}`; else content += ":root"; content += `{ ${styleKey}: ${value} }\n`; break; @@ -183,7 +183,7 @@ const getInstalledThemes = async (): Promise => { for (const { name, value } of extension.themes) { themes.push({ name, - identifier: identifier + "@" + identifier, + identifier: `${identifier}@${identifier}`, author, version, description, From aba1071ab3bad54ca6b79eba484d697312d4bbc9 Mon Sep 17 00:00:00 2001 From: curtisy Date: Sun, 14 Apr 2024 19:22:31 +0200 Subject: [PATCH 08/21] style: apply biome style/useNodejsImportProtocol rule --- src/Components/Functions/extractExeIcon.ts | 4 ++-- src/Services/FilesService.ts | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Components/Functions/extractExeIcon.ts b/src/Components/Functions/extractExeIcon.ts index 54a01b19..d8917f8a 100644 --- a/src/Components/Functions/extractExeIcon.ts +++ b/src/Components/Functions/extractExeIcon.ts @@ -1,6 +1,6 @@ const extractExeIcon = (filePath: string): string => { - const fs = require("fs"); - const path = require("path"); + const fs = require("node:fs"); + const path = require("node:path"); const { extractIcon } = require("../../Lib/extracticon/bindings"); const electron = require("electron"); const basename = filePath.split(/[\\/]/)[filePath.split(/[\\/]/).length - 1]; diff --git a/src/Services/FilesService.ts b/src/Services/FilesService.ts index 1c17bf27..4058c3d6 100644 --- a/src/Services/FilesService.ts +++ b/src/Services/FilesService.ts @@ -1,4 +1,4 @@ -import { Buffer } from "buffer"; +import { Buffer } from "node:buffer"; import { invoke } from "@tauri-apps/api/core"; import { convertFileSrc } from "@tauri-apps/api/core"; import { copyFile as copyFileNative, readTextFile, remove as removeNative, rename as renameFileNative } from "@tauri-apps/plugin-fs"; From b508fe78d3aa6c9c2178e5556fcb2f9f8057621d Mon Sep 17 00:00:00 2001 From: curtisy Date: Sun, 14 Apr 2024 21:37:06 +0200 Subject: [PATCH 09/21] style: apply biome style/useExponentiationOperator rule --- src/Components/Functions/filesize.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Components/Functions/filesize.ts b/src/Components/Functions/filesize.ts index ecc90da5..3fb54803 100644 --- a/src/Components/Functions/filesize.ts +++ b/src/Components/Functions/filesize.ts @@ -11,7 +11,7 @@ const formatBytes = (bytes: number): string => { const dm = 2; // Decimal digit const sizes = ["Bytes", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"]; const i = Math.floor(Math.log(bytes) / Math.log(k)); - return `${Number.parseFloat((bytes / Math.pow(k, i)).toFixed(dm))} ${sizes[i]}`; + return `${Number.parseFloat((bytes / k ** i).toFixed(dm))} ${sizes[i]}`; }; export default formatBytes; From 21aad624d5b8473e5d42c13a59f88fcd7e310521 Mon Sep 17 00:00:00 2001 From: curtisy Date: Sun, 14 Apr 2024 21:38:33 +0200 Subject: [PATCH 10/21] style: apply biome complexity/noUselessSwitchCase rule --- src/Components/Drives/drives.ts | 1 - src/Components/Open/displayFiles.ts | 3 --- 2 files changed, 4 deletions(-) diff --git a/src/Components/Drives/drives.ts b/src/Components/Drives/drives.ts index 8c7293bf..99977164 100644 --- a/src/Components/Drives/drives.ts +++ b/src/Components/Drives/drives.ts @@ -56,7 +56,6 @@ const Drives = async (): Promise => { switch (platform) { case "darwin": return ""; // Xplorer does not support drives for macOS currently - case "win32": default: return `
${await drivesToElements(driveInfo.DRIVES)}
`; } diff --git a/src/Components/Open/displayFiles.ts b/src/Components/Open/displayFiles.ts index b5b4d162..4be678df 100644 --- a/src/Components/Open/displayFiles.ts +++ b/src/Components/Open/displayFiles.ts @@ -53,9 +53,6 @@ const displayFiles = async ( case "T": // Filetype files.sort((a, b) => (a.file_type > b.file_type ? 1 : -1)); break; - - case "A": // A-Z - case "Z": // Z-A default: { const compator = new Intl.Collator(undefined, { numeric: true, From 18cc8b288db4b65c218f341e1a8bef04ef7a5589 Mon Sep 17 00:00:00 2001 From: curtisy Date: Sun, 14 Apr 2024 21:40:12 +0200 Subject: [PATCH 11/21] style: apply biome complexity/useLiteralKeys rule --- src/Components/Functions/extractExeIcon.ts | 2 +- src/Components/Open/recent.ts | 4 ++-- src/Components/Setting/Appearance/Appearance.ts | 2 +- src/Components/Setting/setting.ts | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Components/Functions/extractExeIcon.ts b/src/Components/Functions/extractExeIcon.ts index d8917f8a..b482d7c0 100644 --- a/src/Components/Functions/extractExeIcon.ts +++ b/src/Components/Functions/extractExeIcon.ts @@ -4,7 +4,7 @@ const extractExeIcon = (filePath: string): string => { const { extractIcon } = require("../../Lib/extracticon/bindings"); const electron = require("electron"); const basename = filePath.split(/[\\/]/)[filePath.split(/[\\/]/).length - 1]; - const app = electron.app || (electron.remote && electron.remote.app) || null; + const app = electron.app || (electron.remote?.app) || null; const EXE_ICON_CACHE_DIR = path.join(app.getPath("userData"), "Cache/Exe Icon"); // Create cache directory if not exist diff --git a/src/Components/Open/recent.ts b/src/Components/Open/recent.ts index 13fe86cf..87b66568 100644 --- a/src/Components/Open/recent.ts +++ b/src/Components/Open/recent.ts @@ -22,8 +22,8 @@ interface RecentType { const Recent = async (): Promise => { startLoading(); // Preference data - const layout = (await Storage.get("layout"))?.["Recent"] ?? (await Storage.get("appearance"))?.layout ?? "s"; - const sort = (await Storage.get("sort"))?.["Recent"] ?? "F"; + const layout = (await Storage.get("layout"))?.Recent ?? (await Storage.get("appearance"))?.layout ?? "s"; + const sort = (await Storage.get("sort"))?.Recent ?? "F"; // Get the main element const MAIN_ELEMENT = GET_TAB_ELEMENT(); MAIN_ELEMENT.innerHTML = ""; diff --git a/src/Components/Setting/Appearance/Appearance.ts b/src/Components/Setting/Appearance/Appearance.ts index dd90d715..b4e491ef 100644 --- a/src/Components/Setting/Appearance/Appearance.ts +++ b/src/Components/Setting/Appearance/Appearance.ts @@ -319,7 +319,7 @@ const Appearance = async (): Promise => { }); settingsMain.querySelector('[name="theme"]')?.addEventListener("change", async (event: Event & { target: HTMLInputElement }) => { const themes = (await Storage.get("theme")) ?? {}; - themes["theme"] = event.target.value; + themes.theme = event.target.value; Storage.set("theme", themes); updateTheme("*"); }); diff --git a/src/Components/Setting/setting.ts b/src/Components/Setting/setting.ts index babd266f..16007d21 100644 --- a/src/Components/Setting/setting.ts +++ b/src/Components/Setting/setting.ts @@ -53,12 +53,12 @@ const Setting = async (): Promise => { break; } const appearance = (await Storage.get("appearance")) ?? {}; - appearance["activeSettingsTab"] = item; + appearance.activeSettingsTab = item; Storage.set("appearance", appearance); }); } const appearance = (await Storage.get("appearance")) ?? {}; - const activeSettingsTab = appearance["activeSettingsTab"] ?? defaultTab; + const activeSettingsTab = appearance.activeSettingsTab ?? defaultTab; setActiveTab(activeSettingsTab); switch (activeSettingsTab) { case "Appearance": From 6ccdf2b2e34fa53b7ddfd2e5b7b9bd1764bec46d Mon Sep 17 00:00:00 2001 From: curtisy Date: Sun, 14 Apr 2024 21:48:11 +0200 Subject: [PATCH 12/21] style: apply biome style/useSingleVarDeclarator rule --- src/Components/Files/File Operation/select.ts | 12 ++++++------ src/Components/Functions/dragElement.ts | 8 ++++---- src/Components/Properties/properties.ts | 9 ++++++++- 3 files changed, 18 insertions(+), 11 deletions(-) diff --git a/src/Components/Files/File Operation/select.ts b/src/Components/Files/File Operation/select.ts index a6f0d014..808a9433 100644 --- a/src/Components/Files/File Operation/select.ts +++ b/src/Components/Files/File Operation/select.ts @@ -195,12 +195,12 @@ const SelectInit = (): void => { const POSITION = new Point(e.pageX - mainBoxBounds.left, e.pageY - mainBoxBounds.top); if (isSelecting) { const DIRECTION = await getSelectingDivDirection(selectingOrigin, POSITION); - let top, - right, - bottom, - left, - height = Math.abs(selectingOrigin.y - POSITION.y), - width = Math.abs(selectingOrigin.x - POSITION.x); + let top: number; + let right: number; + let bottom: number; + let left: number; + const height = Math.abs(selectingOrigin.y - POSITION.y); + const width = Math.abs(selectingOrigin.x - POSITION.x); switch (DIRECTION.y) { case 0: diff --git a/src/Components/Functions/dragElement.ts b/src/Components/Functions/dragElement.ts index cb8d1504..f0a7c9fe 100644 --- a/src/Components/Functions/dragElement.ts +++ b/src/Components/Functions/dragElement.ts @@ -5,10 +5,10 @@ * @returns {void} */ function dragElement(elmnt: HTMLElement, parentElement: HTMLElement): void { - let pos1 = 0, - pos2 = 0, - pos3 = 0, - pos4 = 0; + let pos1 = 0; + let pos2 = 0; + let pos3 = 0; + let pos4 = 0; elmnt.onmousedown = dragMouseDown; function dragMouseDown(e: MouseEvent) { diff --git a/src/Components/Properties/properties.ts b/src/Components/Properties/properties.ts index 79b10468..02f06e45 100644 --- a/src/Components/Properties/properties.ts +++ b/src/Components/Properties/properties.ts @@ -35,7 +35,14 @@ const RenderProperties = (options: Record) => { const Properties = async (filePath: string): Promise => { const fileElement = document.querySelector(`[data-path="${encodeURI(filePath)}"]`); - let size, createdAt, modifiedAt, accessedAt, fileType, isHidden, isSystem, isReadonly; + let size: string; + let createdAt: string | undefined; + let modifiedAt: string | undefined; + let accessedAt: string | undefined; + let fileType: string; + let isHidden: boolean | undefined; + let isSystem: boolean | undefined; + let isReadonly: boolean | undefined; if (fileElement.classList.contains("file")) { size = fileElement.querySelector(".file-size").innerHTML; From 792e93a49a3f4c77bcc1477a439beb2ebe102800 Mon Sep 17 00:00:00 2001 From: curtisy Date: Sun, 14 Apr 2024 21:54:13 +0200 Subject: [PATCH 13/21] style: apply biome suspicious/noDoubleEquals rule --- src/Components/Files/File Operation/select.ts | 34 +++++++++---------- src/Util/is-tauri.ts | 2 +- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/src/Components/Files/File Operation/select.ts b/src/Components/Files/File Operation/select.ts index 808a9433..3771ebff 100644 --- a/src/Components/Files/File Operation/select.ts +++ b/src/Components/Files/File Operation/select.ts @@ -150,8 +150,8 @@ const SelectInit = (): void => { if ( !(e.target as HTMLElement).className.split(" ").some((c) => /file/.test(c)) && //If user doesn't drag the mouse - e.pageX - mainBoxBounds.left == selectingOrigin.x && - e.pageY - mainBoxBounds.top == selectingOrigin.y + e.pageX - mainBoxBounds.left === selectingOrigin.x && + e.pageY - mainBoxBounds.top === selectingOrigin.y ) { unselectAllSelected(); latestSelected = null; @@ -195,10 +195,10 @@ const SelectInit = (): void => { const POSITION = new Point(e.pageX - mainBoxBounds.left, e.pageY - mainBoxBounds.top); if (isSelecting) { const DIRECTION = await getSelectingDivDirection(selectingOrigin, POSITION); - let top: number; - let right: number; - let bottom: number; - let left: number; + let top: number | string; + let right: number | string; + let bottom: number | string; + let left: number | string; const height = Math.abs(selectingOrigin.y - POSITION.y); const width = Math.abs(selectingOrigin.x - POSITION.x); @@ -233,22 +233,22 @@ const SelectInit = (): void => { } //Updating selecting div bounds manually so we don't call getBoundingClientRect each mousemove - selectingDivBounds.bottom = bottom == "auto" ? mainBoxBounds.height - (top as number) - height : (bottom as number); - selectingDivBounds.top = top == "auto" ? mainBoxBounds.height - (bottom as number) - height : (top as number); - selectingDivBounds.left = left == "auto" ? mainBoxBounds.width - (right as number) - width : (left as number); - selectingDivBounds.right = right == "auto" ? mainBoxBounds.width - (left as number) - width : (right as number); + selectingDivBounds.bottom = bottom === "auto" ? mainBoxBounds.height - (top as number) - height : (bottom as number); + selectingDivBounds.top = top === "auto" ? mainBoxBounds.height - (bottom as number) - height : (top as number); + selectingDivBounds.left = left === "auto" ? mainBoxBounds.width - (right as number) - width : (left as number); + selectingDivBounds.right = right === "auto" ? mainBoxBounds.width - (left as number) - width : (right as number); selectingDivBounds.width = width; selectingDivBounds.height = height; selectingDiv.style.inset = top + - (top == "auto" ? " " : "px ") + + (top === "auto" ? " " : "px ") + right + - (right == "auto" ? " " : "px ") + + (right === "auto" ? " " : "px ") + bottom + - (bottom == "auto" ? " " : "px ") + + (bottom === "auto" ? " " : "px ") + left + - (left == "auto" ? " " : "px "); + (left === "auto" ? " " : "px "); selectingDiv.style.height = `${height}px`; selectingDiv.style.width = `${width}px`; @@ -278,7 +278,7 @@ const SelectInit = (): void => { } } } - if (selected == 0) unselectAllSelected(); + if (selected === 0) unselectAllSelected(); } }); @@ -324,8 +324,8 @@ const getSelectingDivDirection = async (origin: Point, last: Point): Promise 0 ? -1 : 1, - y: delta.y == 0 ? 0 : delta.y > 0 ? -1 : 1, + x: delta.x === 0 ? 0 : delta.x > 0 ? -1 : 1, + y: delta.y === 0 ? 0 : delta.y > 0 ? -1 : 1, }; }; /** diff --git a/src/Util/is-tauri.ts b/src/Util/is-tauri.ts index c6366470..4a92eee6 100644 --- a/src/Util/is-tauri.ts +++ b/src/Util/is-tauri.ts @@ -3,6 +3,6 @@ * Check if it's running on Tauri */ const isTauri = Boolean( - typeof window !== "undefined" && window != undefined && (window as any).__TAURI__ !== undefined && (window as any).promisified !== null, + typeof window !== "undefined" && window !== undefined && (window as any).__TAURI__ !== undefined && (window as any).promisified !== null, ); export default isTauri; From f66ba5e2bb3a7111372fa719ad3edf93adfc59c3 Mon Sep 17 00:00:00 2001 From: curtisy Date: Sun, 14 Apr 2024 21:56:06 +0200 Subject: [PATCH 14/21] style: apply biome suspicious/noImplicitAnyLet rule --- src/Components/Files/File Preview/preview.ts | 2 +- src/Components/Functions/path/joinPath.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Components/Files/File Preview/preview.ts b/src/Components/Files/File Preview/preview.ts index 97042387..7b759877 100644 --- a/src/Components/Files/File Preview/preview.ts +++ b/src/Components/Files/File Preview/preview.ts @@ -12,7 +12,7 @@ import ConfirmDialog from "../../Prompt/confirm"; import PromptError from "../../Prompt/error"; const isValidURL = (text: string) => { - let url; + let url: URL; try { url = new URL(text); } catch (_) { diff --git a/src/Components/Functions/path/joinPath.ts b/src/Components/Functions/path/joinPath.ts index 3a7edd76..b708c8bc 100644 --- a/src/Components/Functions/path/joinPath.ts +++ b/src/Components/Functions/path/joinPath.ts @@ -5,7 +5,7 @@ */ const joinPath = (...args: string[]): string => { if (args.length === 0) return "."; - let joined; + let joined: string | undefined; for (let i = 0; i < args.length; i++) { const arg = args[i]; if (arg.length > 0) { From fc7c3b5fa3a683f3281e1519b010d9ed9f4db2cc Mon Sep 17 00:00:00 2001 From: curtisy Date: Sun, 14 Apr 2024 22:00:50 +0200 Subject: [PATCH 15/21] style!: apply biome suspicious/noMisleadingCharacterClass rule This replaces unicode regex mechanism for diacritics --- src/Components/Shortcut/shortcut.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Components/Shortcut/shortcut.ts b/src/Components/Shortcut/shortcut.ts index 2adf8aee..d917d43b 100644 --- a/src/Components/Shortcut/shortcut.ts +++ b/src/Components/Shortcut/shortcut.ts @@ -74,7 +74,7 @@ const Shortcut = (): void => { .querySelector("#file-filename") ?.textContent.toLowerCase() .normalize("NFD") - .replace(/[\u0300-\u036f]/gu, "") + .replace(/\p{Diacritic}/gu, "") .startsWith(searchingFileName); }; @@ -295,7 +295,7 @@ const Shortcut = (): void => { .querySelector("#file-filename") .innerHTML.toLowerCase() .normalize("NFD") - .replace(/[\u0300-\u036f]/g, "") + .replace(/\p{Diacritic}/g, "") .startsWith(searchingFileName); }); for (let i = 0; i < _files.length; i++) { @@ -313,11 +313,11 @@ const Shortcut = (): void => { unselectAllSelected(); for (const _file of _files) { const _fileName = _file.querySelector("#file-filename").innerHTML.toLowerCase(); - console.log(_fileName.normalize("NFD").replace(/[\u0300-\u036f]/g, "")); + console.log(_fileName.normalize("NFD").replace(/\p{Diacritic}/g, "")); if ( _fileName .normalize("NFD") - .replace(/[\u0300-\u036f]/g, "") + .replace(/\p{Diacritic}/g, "") .startsWith(searchingFileName) ) { Select(_file as HTMLElement, false, false); From 6cd28d168fdd954e5e423ad903141dc87043b008 Mon Sep 17 00:00:00 2001 From: curtisy Date: Sun, 14 Apr 2024 22:05:01 +0200 Subject: [PATCH 16/21] style: apply biome correctness/noSwitchDeclarations rule --- src/Store/Reducers/TabReducer.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/Store/Reducers/TabReducer.ts b/src/Store/Reducers/TabReducer.ts index 49e79b2d..92b2b5bd 100644 --- a/src/Store/Reducers/TabReducer.ts +++ b/src/Store/Reducers/TabReducer.ts @@ -30,7 +30,7 @@ const reducer = (state = initialState, action: Actions): ITabReducerState => { [action.tab.id]: action.tab, }, }; - case "UPDATE_TAB": + case "UPDATE_TAB": { const newTabs: INewTabs = {}; Object.entries(state.tabs).forEach(([name, tab]) => { if (tab.id === action.tab.id) { @@ -47,13 +47,15 @@ const reducer = (state = initialState, action: Actions): ITabReducerState => { ...state, tabs: newTabs, }; - case "DELETE_TAB": + } + case "DELETE_TAB": { const newTabsList = omit(state.tabs, action.id); return { ...state, tabs: newTabsList, activeTab: state.activeTab.id === action.id ? newTabsList[Object.keys(newTabsList)[0]] : state.activeTab, }; + } case "SET_ACTIVE_TAB": return { ...state, From 61bf504bf1749b73ad698dbcd3d3643dfcc84171 Mon Sep 17 00:00:00 2001 From: curtisy Date: Sun, 14 Apr 2024 22:16:47 +0200 Subject: [PATCH 17/21] style: apply biome correctness/useExhaustiveDependencies rule --- src/App.tsx | 8 +++----- src/Components/Header/SubHeader.tsx | 2 +- src/Components/Preview/PdfViewer.tsx | 2 +- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/src/App.tsx b/src/App.tsx index 2d0c2b85..1a0756a2 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -26,15 +26,13 @@ const App = () => { const [isLoaded, setIsLoaded] = useState(false); // TODO REPLACE WITH SKELETON LOADING - const setCurrentDirectory = (path: string) => dispatch(setActiveTab({ ...activeTab, path })); - // Waits for homeDirectory to load on initial favorites request useEffect(() => { - if (homeDirectory) { + if (homeDirectory && activeTab.path !== homeDirectory) { setIsLoaded(true); - setCurrentDirectory(homeDirectory); + dispatch(setActiveTab({ ...activeTab, path: homeDirectory })); } - }, [homeDirectory]); + }, [homeDirectory, dispatch, activeTab]); if (!isLoaded) return
Loading...
; diff --git a/src/Components/Header/SubHeader.tsx b/src/Components/Header/SubHeader.tsx index 03626451..5da3ce55 100644 --- a/src/Components/Header/SubHeader.tsx +++ b/src/Components/Header/SubHeader.tsx @@ -19,7 +19,7 @@ const SubHeader = ({ activeTab, handleBack, handleForward, handlePathChange, han useEffect(() => { if (JSON.stringify(activeTab) === JSON.stringify(tempTab)) return; setTempTab(activeTab); - }, [activeTab]); + }, [activeTab, tempTab]); const handleFormSubmit = (e: FormEvent) => { e.preventDefault(); diff --git a/src/Components/Preview/PdfViewer.tsx b/src/Components/Preview/PdfViewer.tsx index 611611bc..c8878e49 100644 --- a/src/Components/Preview/PdfViewer.tsx +++ b/src/Components/Preview/PdfViewer.tsx @@ -14,7 +14,7 @@ const PdfViewer = ({ filePath }: IPdfViewerProps): JSX.Element => { useEffect(() => { dispatch(readAssetRequest(filePath)); - }, [filePath]); + }, [filePath, dispatch]); if (!content) return
Loading...
; From 28649e3ab6d82b916e768a921f1ceb0e77443610 Mon Sep 17 00:00:00 2001 From: curtisy Date: Sun, 14 Apr 2024 22:22:16 +0200 Subject: [PATCH 18/21] style: apply biome suspicious/noShadowRestrictedNames rule --- src/Components/Open/open.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Components/Open/open.ts b/src/Components/Open/open.ts index 925fb117..218d8db6 100644 --- a/src/Components/Open/open.ts +++ b/src/Components/Open/open.ts @@ -18,7 +18,6 @@ import Home from "../Layout/home"; import { UpdateInfo } from "../Layout/infobar"; import { reload } from "../Layout/windowManager"; import PromptError from "../Prompt/error"; -import Error from "../Prompt/error"; import { updateTheme } from "../Theme/theme"; import displayFiles from "./displayFiles"; import Recent from "./recent"; @@ -202,7 +201,7 @@ const OpenHandler = async (e: MouseEvent): Promise => { const filePath = decodeURI(element.dataset.path); if ((await focusingPath()) === "xplorer://Trash" && element.dataset.isdir !== "true") { - Error("Error opening trashed file", "Please restore the file first in order to open it."); + PromptError("Error opening trashed file", "Please restore the file first in order to open it."); } // Open the file if it's not directory From 9cae1e9483e29f962fc87810cbf82118e2f017ee Mon Sep 17 00:00:00 2001 From: curtisy Date: Sun, 14 Apr 2024 22:24:03 +0200 Subject: [PATCH 19/21] style: apply biome a11y/useKeyWithClickEvents rule --- src/Components/Sidebar/index.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Components/Sidebar/index.tsx b/src/Components/Sidebar/index.tsx index 6cf6a6c5..7a75995d 100644 --- a/src/Components/Sidebar/index.tsx +++ b/src/Components/Sidebar/index.tsx @@ -68,6 +68,7 @@ const Sidebar = () => { data-path={mount_point} className="sidebar-hover-effect sidebar-nav-item drive-item" onClick={() => navigateToPath(mount_point.replace(/\\/g, "/"))} + onKeyUp={() => navigateToPath(mount_point.replace(/\\/g, "/"))} key={mount_point + name} >
From 0a9ea285feca70ec819cbf0272a2901ac8709436 Mon Sep 17 00:00:00 2001 From: curtisy Date: Sun, 14 Apr 2024 22:30:44 +0200 Subject: [PATCH 20/21] style: set different to fix errors to emit warnings These should gradually be investigated and fixed without negatively impacting productivity --- biome.json | 63 ++++++++++++++++++++++++++++++++---------------------- 1 file changed, 37 insertions(+), 26 deletions(-) diff --git a/biome.json b/biome.json index 3239e615..735abe7e 100644 --- a/biome.json +++ b/biome.json @@ -1,28 +1,39 @@ { - "$schema": "https://biomejs.dev/schemas/1.6.4/schema.json", - "files": { - "ignore": [ - "node_modules", - "out", - "src-tauri", - "build", - "dist", - "*.min.js" - ] - }, - "organizeImports": { - "enabled": true - }, - "linter": { - "enabled": true, - "rules": { - "recommended": true - } - }, - "formatter": { - "enabled": true, - "indentStyle": "space", - "indentWidth": 4, - "lineWidth": 150 - } + "$schema": "https://biomejs.dev/schemas/1.6.4/schema.json", + "files": { + "ignore": ["node_modules", "out", "src-tauri", "build", "dist", "*.min.js"] + }, + "organizeImports": { + "enabled": true + }, + "linter": { + "enabled": true, + "rules": { + "recommended": true, + "style": { + "useDefaultParameterLast": "warn", + "noParameterAssign": "warn" + }, + "complexity": { + "noForEach": "warn" + }, + "suspicious": { + "noExplicitAny": "warn", + "noAssignInExpressions": "warn" + }, + "a11y": { + "useValidAnchor": "warn" + }, + "performance": { + "noAccumulatingSpread": "warn", + "noDelete": "warn" + } + } + }, + "formatter": { + "enabled": true, + "indentStyle": "space", + "indentWidth": 4, + "lineWidth": 150 + } } From 355576a95ac128c7672587014ef568e296f43932 Mon Sep 17 00:00:00 2001 From: curtisy Date: Sun, 14 Apr 2024 23:08:07 +0200 Subject: [PATCH 21/21] style: re-apply lint rules --- src/Components/Drives/drives.ts | 11 +- src/Components/Files/File Operation/paste.ts | 4 +- src/Components/Files/File Operation/redo.ts | 4 +- src/Components/Files/File Operation/search.ts | 3 +- src/Components/Files/File Operation/undo.ts | 4 +- src/Components/Functions/changePosition.ts | 3 +- src/Components/Functions/extractExeIcon.ts | 8 +- src/Components/Functions/validChecker.ts | 6 +- src/Components/Layout/sidebar.ts | 9 +- src/Components/Preview/index.tsx | 23 +-- src/Components/Thumbnail/thumbnail.ts | 20 +-- src/Icon/index.tsx | 12 +- src/Service/app.ts | 4 +- src/Service/clipboard.ts | 4 +- src/Service/directory.ts | 8 +- src/Service/files.ts | 18 +-- src/Service/operation.ts | 2 +- src/Service/storage.ts | 28 ++-- src/Service/window.ts | 8 +- .../ActionCreators/FilesActionCreators.ts | 132 +++++++++--------- src/components/Infobar/index.tsx | 2 +- src/components/OperationBar/index.tsx | 2 +- 22 files changed, 167 insertions(+), 148 deletions(-) diff --git a/src/Components/Drives/drives.ts b/src/Components/Drives/drives.ts index 99977164..59ad5e9d 100644 --- a/src/Components/Drives/drives.ts +++ b/src/Components/Drives/drives.ts @@ -36,9 +36,9 @@ const drivesToElements = async (drives: Drive[]): Promise => { ? `

${drive.name && /[^?]/.test(drive.name) ? drive.name : drive.disk_type} (${driveName})

` //eslint-disable-line : `

${driveName}

` } -
+

${formatBytes(drive.available_space)} ${await Translate("free of")} ${formatBytes(drive.total_space)}

@@ -86,8 +86,9 @@ const writeSidebarDriveItems = async (): Promise => { } else driveName = drive.mount_point.split("/").at(-1); const driveType = drive.is_removable ? "usb" : "hard-disk"; const iconPath = await fileThumbnail(driveType, "favorites", false); - content += - `\n \n ${driveName}\n`; + content += `\n \n ${driveName}\n`; } const sidebar = await Storage.get("sidebar"); const driveList = driveElement.querySelector(".sidebar-nav-list"); diff --git a/src/Components/Files/File Operation/paste.ts b/src/Components/Files/File Operation/paste.ts index 5357da6d..e84ceb86 100644 --- a/src/Components/Files/File Operation/paste.ts +++ b/src/Components/Files/File Operation/paste.ts @@ -61,8 +61,8 @@ const Paste = async (target: string): Promise => { )) ) return; - - await new OperationAPI(dest).unlink(); + + await new OperationAPI(dest).unlink(); } await new OperationAPI(file, dest).cut(); break; diff --git a/src/Components/Files/File Operation/redo.ts b/src/Components/Files/File Operation/redo.ts index 62eb728c..4fff770d 100644 --- a/src/Components/Files/File Operation/redo.ts +++ b/src/Components/Files/File Operation/redo.ts @@ -38,8 +38,8 @@ const Redo = async (): Promise => { )) ) return; - - await new OperationAPI(dest).unlink(); + + await new OperationAPI(dest).unlink(); } await new OperationAPI(source, dest).rename(); } diff --git a/src/Components/Files/File Operation/search.ts b/src/Components/Files/File Operation/search.ts index e4fa3e2b..ea15e48d 100644 --- a/src/Components/Files/File Operation/search.ts +++ b/src/Components/Files/File Operation/search.ts @@ -91,7 +91,8 @@ const Search = async (): Promise => { clearTimeout(listener); if (e.ctrlKey && e.key === "f") { return; - }if (e.key === "Enter") { + } + if (e.key === "Enter") { const value = (e.target as HTMLInputElement).value; if (value !== being_watch) { processSearch(value, await getFocusingPath()); diff --git a/src/Components/Files/File Operation/undo.ts b/src/Components/Files/File Operation/undo.ts index 2f8b898e..48846905 100644 --- a/src/Components/Files/File Operation/undo.ts +++ b/src/Components/Files/File Operation/undo.ts @@ -40,8 +40,8 @@ const Undo = async (): Promise => { )) ) return; - - await new OperationAPI(source).unlink(); + + await new OperationAPI(source).unlink(); } await new OperationAPI(dest, source).rename(); break; diff --git a/src/Components/Functions/changePosition.ts b/src/Components/Functions/changePosition.ts index a9adfe26..bcd8c9bd 100644 --- a/src/Components/Functions/changePosition.ts +++ b/src/Components/Functions/changePosition.ts @@ -23,7 +23,8 @@ const changePosition = async (newPath: string, forceChange = false, writeHistory if (newPath === _focusingTab.history[_focusingTab.currentIndex] && !forceChange) { return; - }if (newPath === _focusingTab.history[_focusingTab.currentIndex + 1]) { + } + if (newPath === _focusingTab.history[_focusingTab.currentIndex + 1]) { _focusingTab.currentIndex += 1; } else if (newPath === _focusingTab.history[_focusingTab.currentIndex - 1]) { _focusingTab.currentIndex -= 1; diff --git a/src/Components/Functions/extractExeIcon.ts b/src/Components/Functions/extractExeIcon.ts index b482d7c0..b6b97788 100644 --- a/src/Components/Functions/extractExeIcon.ts +++ b/src/Components/Functions/extractExeIcon.ts @@ -4,7 +4,7 @@ const extractExeIcon = (filePath: string): string => { const { extractIcon } = require("../../Lib/extracticon/bindings"); const electron = require("electron"); const basename = filePath.split(/[\\/]/)[filePath.split(/[\\/]/).length - 1]; - const app = electron.app || (electron.remote?.app) || null; + const app = electron.app || electron.remote?.app || null; const EXE_ICON_CACHE_DIR = path.join(app.getPath("userData"), "Cache/Exe Icon"); // Create cache directory if not exist @@ -20,8 +20,8 @@ const extractExeIcon = (filePath: string): string => { if (fs.existsSync(ICON_FILE_NAME)) { return ICON_FILE_NAME; } - const buffer = extractIcon(filePath, "large"); - fs.writeFileSync(ICON_FILE_NAME, buffer); - return ICON_FILE_NAME; + const buffer = extractIcon(filePath, "large"); + fs.writeFileSync(ICON_FILE_NAME, buffer); + return ICON_FILE_NAME; }; export default extractExeIcon; diff --git a/src/Components/Functions/validChecker.ts b/src/Components/Functions/validChecker.ts index 617c98c9..8d743b0c 100644 --- a/src/Components/Functions/validChecker.ts +++ b/src/Components/Functions/validChecker.ts @@ -10,10 +10,12 @@ const IsValid = (obj: any): boolean => { if (Array.isArray(obj)) { if (obj.length === 0) return false; return true; - }if (typeof obj === "object") { + } + if (typeof obj === "object") { if (Object.keys(obj).length === 0) return false; return true; - }if (obj) return true; + } + if (obj) return true; return false; }; export default IsValid; diff --git a/src/Components/Layout/sidebar.ts b/src/Components/Layout/sidebar.ts index 048bca5a..ce6c2f53 100644 --- a/src/Components/Layout/sidebar.ts +++ b/src/Components/Layout/sidebar.ts @@ -42,8 +42,13 @@ const writeFavoriteItems = async (favorites: Favorites[]): Promise => { if (!isDefault && favorite.path !== "xplorer://Home") { iconCategory = isdir ? "folder" : "file"; } - content += - `\n \n ${await Translate(favorite.name)}\n\n`; + content += `\n \n ${await Translate(favorite.name)}\n\n`; } const favoriteElement = document.querySelector("#sidebar-favorites"); const favoriteBtnText = favoriteElement.querySelector(".sidebar-text"); diff --git a/src/Components/Preview/index.tsx b/src/Components/Preview/index.tsx index 361117a7..2f82f131 100644 --- a/src/Components/Preview/index.tsx +++ b/src/Components/Preview/index.tsx @@ -45,22 +45,29 @@ const Preview = ({ filePath }: IPreviewProps): JSX.Element => { if (extensionMatches(PDF_TYPES, extension)) { return ; - }if (extensionMatches(HTML_TYPES, extension)) { + } + if (extensionMatches(HTML_TYPES, extension)) { return ; - }if (extensionMatches(DOCX_TYPES, extension)) { + } + if (extensionMatches(DOCX_TYPES, extension)) { return ; - }if (extensionMatches(XLSX_TYPES, extension)) { + } + if (extensionMatches(XLSX_TYPES, extension)) { return ; - }if (extensionMatches(IMAGE_TYPES, extension)) { + } + if (extensionMatches(IMAGE_TYPES, extension)) { return ; - }if (extensionMatches(VIDEO_TYPES, extension)) { + } + if (extensionMatches(VIDEO_TYPES, extension)) { return ; - }if (extensionMatches(PLAINTEXT_TYPES, extension)) { + } + if (extensionMatches(PLAINTEXT_TYPES, extension)) { return ; - }if (extensionMatches(MARKDOWN_TYPES, extension)) { + } + if (extensionMatches(MARKDOWN_TYPES, extension)) { return ; } - return
{JSON.stringify(file)}
; + return
{JSON.stringify(file)}
; }; export default Preview; diff --git a/src/Components/Thumbnail/thumbnail.ts b/src/Components/Thumbnail/thumbnail.ts index 4b42dd41..ea293b77 100644 --- a/src/Components/Thumbnail/thumbnail.ts +++ b/src/Components/Thumbnail/thumbnail.ts @@ -82,11 +82,13 @@ const fileThumbnail = async (filePath: string, category = "folder", HTMLFormat = if (imageAsThumbnail) { return imageThumbnail(filePath, HTMLFormat, true); } - return imageThumbnail(DEFAULT_IMAGE_THUMBNAIL, HTMLFormat); - }if (VIDEO_TYPES.indexOf(ext) !== -1) { + return imageThumbnail(DEFAULT_IMAGE_THUMBNAIL, HTMLFormat); + } + if (VIDEO_TYPES.indexOf(ext) !== -1) { const assetSrc = new FileAPI(filePath).readAsset(); return HTMLFormat ? await videoPreview(assetSrc) : assetSrc; - }if ((appearance?.extractExeIcon ?? false) && (ext === "exe" || ext === "msi")) { + } + if ((appearance?.extractExeIcon ?? false) && (ext === "exe" || ext === "msi")) { return imageThumbnail(await new FileAPI(filePath).extractIcon(), HTMLFormat, true); } } @@ -102,13 +104,13 @@ const fileThumbnail = async (filePath: string, category = "folder", HTMLFormat = HTMLFormat, ); } - if (category !== "folder") { - const _key = `${category}-${filename}`; - if (Object.keys(customThumbnail).indexOf(_key) !== -1) { - return imageThumbnail(customThumbnail[_key], HTMLFormat); - } + if (category !== "folder") { + const _key = `${category}-${filename}`; + if (Object.keys(customThumbnail).indexOf(_key) !== -1) { + return imageThumbnail(customThumbnail[_key], HTMLFormat); } - return imageThumbnail(folderThumbnailTrie.search(basename) ?? defaultThumbnail.DEFAULT_FOLDER_THUMBNAIL, HTMLFormat); + } + return imageThumbnail(folderThumbnailTrie.search(basename) ?? defaultThumbnail.DEFAULT_FOLDER_THUMBNAIL, HTMLFormat); }; export default fileThumbnail; diff --git a/src/Icon/index.tsx b/src/Icon/index.tsx index 6f716f87..0cbb78fb 100644 --- a/src/Icon/index.tsx +++ b/src/Icon/index.tsx @@ -28,7 +28,7 @@ export const CopyIcon = ({ fillColor = "currentColor", size = 24 }) => ( + /> ); @@ -46,7 +46,7 @@ export const PasteIcon = ({ fillColor = "currentColor", size = 24 }) => ( + /> ); @@ -64,7 +64,7 @@ export const RenameIcon = ({ fillColor = "currentColor", size = 24 }) => ( + /> ); export const CutIcon = ({ fillColor = "currentColor", size = 24 }) => ( @@ -80,14 +80,14 @@ export const CutIcon = ({ fillColor = "currentColor", size = 24 }) => ( + /> + /> + /> ); diff --git a/src/Service/app.ts b/src/Service/app.ts index 3e3f0354..7dd52a45 100644 --- a/src/Service/app.ts +++ b/src/Service/app.ts @@ -21,8 +21,8 @@ const getAvailableFonts = async (): Promise => { const { invoke } = require("@tauri-apps/api"); return await invoke("get_available_fonts"); } - const fonts = await (await fetch(GET_AVAILABLE_FONTS_ENDPOINT, { method: "GET" })).json(); - return fonts; + const fonts = await (await fetch(GET_AVAILABLE_FONTS_ENDPOINT, { method: "GET" })).json(); + return fonts; }; let listened = false; const listenStylesheetChange = async (cb: (stylesheet: JSON) => void): Promise => { diff --git a/src/Service/clipboard.ts b/src/Service/clipboard.ts index d6ada8b9..cad0a006 100644 --- a/src/Service/clipboard.ts +++ b/src/Service/clipboard.ts @@ -10,7 +10,7 @@ const writeTextToClipboard = async (text: string): Promise => { const { clipboard } = require("@tauri-apps/api"); return await clipboard.writeText(text); } - return await navigator.clipboard.writeText(text); + return await navigator.clipboard.writeText(text); }; /** @@ -22,6 +22,6 @@ const readTextFromClipboard = async (): Promise => { const { clipboard } = require("@tauri-apps/api"); return await clipboard.readText(); } - return await navigator.clipboard.readText(); + return await navigator.clipboard.readText(); }; export { writeTextToClipboard, readTextFromClipboard }; diff --git a/src/Service/directory.ts b/src/Service/directory.ts index 3b433aa4..321f39c0 100644 --- a/src/Service/directory.ts +++ b/src/Service/directory.ts @@ -81,8 +81,8 @@ class DirectoryAPI { const { invoke } = require("@tauri-apps/api"); return await invoke("file_exist", { filePath: this.dirName }); } - const exists = await (await fetch(CHECK_EXIST_ENDPOINT + this.dirName, { method: "GET" })).json(); - return exists; + const exists = await (await fetch(CHECK_EXIST_ENDPOINT + this.dirName, { method: "GET" })).json(); + return exists; } /** * Create dir if not exists @@ -135,8 +135,8 @@ class DirectoryAPI { const { invoke } = require("@tauri-apps/api"); return await invoke("get_dir_size", { dir: this.dirName }); } - const size = await (await fetch(GET_DIR_SIZE_ENDPOINT + this.dirName, { method: "GET" })).json(); - return size; + const size = await (await fetch(GET_DIR_SIZE_ENDPOINT + this.dirName, { method: "GET" })).json(); + return size; } /** diff --git a/src/Service/files.ts b/src/Service/files.ts index 570c4f73..697f34fe 100644 --- a/src/Service/files.ts +++ b/src/Service/files.ts @@ -60,8 +60,8 @@ class FileAPI { const { invoke } = require("@tauri-apps/api"); return await invoke("open_file", { filePath: this.fileName }); } - await fetch(OPEN_FILE_ENDPOINT + this.fileName, { method: "GET" }); - return; + await fetch(OPEN_FILE_ENDPOINT + this.fileName, { method: "GET" }); + return; } /** * Get tauri url of local assets @@ -91,8 +91,8 @@ class FileAPI { const { invoke } = require("@tauri-apps/api"); return await invoke("file_exist", { filePath: this.fileName }); } - const exists = await (await fetch(CHECK_EXIST_ENDPOINT + this.fileName, { method: "GET" })).json(); - return exists; + const exists = await (await fetch(CHECK_EXIST_ENDPOINT + this.fileName, { method: "GET" })).json(); + return exists; } /** * Create file if it doesn't exist @@ -107,7 +107,7 @@ class FileAPI { }); return await invoke("create_file", { filePath: this.fileName }); } - return; + return; } } /** @@ -160,10 +160,10 @@ class FileAPI { files: this.fileName, }); } - const paths = Array.isArray(this.fileName) ? this.fileName.join("%2c-%2c") : this.fileName; - console.log(paths); - const size = await (await fetch(CALCULATE_DIRS_SIZE_ENDPOINT + paths, { method: "GET" })).json(); - return size; + const paths = Array.isArray(this.fileName) ? this.fileName.join("%2c-%2c") : this.fileName; + console.log(paths); + const size = await (await fetch(CALCULATE_DIRS_SIZE_ENDPOINT + paths, { method: "GET" })).json(); + return size; } /** diff --git a/src/Service/operation.ts b/src/Service/operation.ts index 99f86732..74f8857e 100644 --- a/src/Service/operation.ts +++ b/src/Service/operation.ts @@ -48,7 +48,7 @@ class OperationAPI { if (await new DirectoryAPI(this.src).isDir()) { return await invoke("remove_dir", { path: this.src }); } - return await invoke("remove_file", { path: this.src }); + return await invoke("remove_file", { path: this.src }); } } diff --git a/src/Service/storage.ts b/src/Service/storage.ts index 653cd306..eb3d57b1 100644 --- a/src/Service/storage.ts +++ b/src/Service/storage.ts @@ -17,8 +17,8 @@ const set = async (key: string, value: any): Promise => { const { invoke } = require("@tauri-apps/api"); return await invoke("write_data", { key, value }); } - data[key] = value; - localStorage.setItem(key, JSON.stringify(value)); + data[key] = value; + localStorage.setItem(key, JSON.stringify(value)); }; /** @@ -35,18 +35,18 @@ const get = async (key: string, force?: boolean): Promise => { if (Object.keys(data).includes(key) && !force) { return data[key]; } - if (isTauri) { - const { invoke } = require("@tauri-apps/api"); - const returnedData = (await invoke("read_data", { key })) as returnedType; - data[key] = returnedData.data; - return returnedData.status ? returnedData.data : {}; - } - const storedData = localStorage.getItem(key); - if (storedData) { - data[key] = JSON.parse(storedData); - return data[key]; - } - return {}; + if (isTauri) { + const { invoke } = require("@tauri-apps/api"); + const returnedData = (await invoke("read_data", { key })) as returnedType; + data[key] = returnedData.data; + return returnedData.status ? returnedData.data : {}; + } + const storedData = localStorage.getItem(key); + if (storedData) { + data[key] = JSON.parse(storedData); + return data[key]; + } + return {}; }; /** diff --git a/src/Service/window.ts b/src/Service/window.ts index 5e23c51e..6d00c853 100644 --- a/src/Service/window.ts +++ b/src/Service/window.ts @@ -16,11 +16,11 @@ const listenWindowClose = (): Promise => { }); }); } - return new Promise((resolve) => { - window.addEventListener("beforeunload", () => { - resolve(); - }); + return new Promise((resolve) => { + window.addEventListener("beforeunload", () => { + resolve(); }); + }); }; const createNewWindow = (): void => { diff --git a/src/Store/ActionCreators/FilesActionCreators.ts b/src/Store/ActionCreators/FilesActionCreators.ts index bcfb4702..74989f95 100644 --- a/src/Store/ActionCreators/FilesActionCreators.ts +++ b/src/Store/ActionCreators/FilesActionCreators.ts @@ -1,73 +1,73 @@ import type FileMetaData from "../../Typings/fileMetaData"; import { - FileTrashMeta, - TrashData, - CalculateFileSizeFailure, - CalculateFileSizeRequest, - CalculateFileSizeSuccess, - CopyFileFailure, - CopyFileRequest, - CopyFileSuccess, - CreateFileFailure, - CreateFileRequest, - CreateFileSuccess, - CutFileFailure, - CutFileRequest, - CutFileSuccess, - DeleteFilesFailure, - DeleteFilesRequest, - DeleteFilesSuccess, - ExtractIconFailure, - ExtractIconRequest, - ExtractIconSuccess, - FetchFilePropertiesFailure, - FetchFilePropertiesRequest, - FetchFilePropertiesSuccess, - GetTrashedFilesFailure, - GetTrashedFilesRequest, - GetTrashedFilesSuccess, - IsDirectoryFailure, - IsDirectoryRequest, - IsDirectorySuccess, - OpenFileFailure, - OpenFileRequest, - OpenFileSuccess, - PurgeFilesFailure, - PurgeFilesRequest, - PurgeFilesSuccess, - ReadAssetFailure, - ReadAssetRequest, - ReadAssetSuccess, - ReadBufferFailure, - ReadBufferRequest, - ReadBufferSuccess, - ReadFileFailure, - ReadFileRequest, - ReadFileSuccess, - ReadJsonFileFailure, - ReadJsonFileRequest, - ReadJsonFileSuccess, - RemoveFileFailure, - RemoveFileRequest, - RemoveFileSuccess, - RenameFileFailure, - RenameFileRequest, - RenameFileSuccess, - RestoreFileFailure, - RestoreFileRequest, - RestoreFilesFailure, - RestoreFilesRequest, - RestoreFilesSuccess, - RestoreFileSuccess, - RevealFileFailure, - RevealFileRequest, - RevealFileSuccess, - OpenFilePreviewSuccess, - CloseFilePreviewSuccess, - FileOperationSuccess, + type FileTrashMeta, + type TrashData, + type CalculateFileSizeFailure, + type CalculateFileSizeRequest, + type CalculateFileSizeSuccess, + type CopyFileFailure, + type CopyFileRequest, + type CopyFileSuccess, + type CreateFileFailure, + type CreateFileRequest, + type CreateFileSuccess, + type CutFileFailure, + type CutFileRequest, + type CutFileSuccess, + type DeleteFilesFailure, + type DeleteFilesRequest, + type DeleteFilesSuccess, + type ExtractIconFailure, + type ExtractIconRequest, + type ExtractIconSuccess, + type FetchFilePropertiesFailure, + type FetchFilePropertiesRequest, + type FetchFilePropertiesSuccess, + type GetTrashedFilesFailure, + type GetTrashedFilesRequest, + type GetTrashedFilesSuccess, + type IsDirectoryFailure, + type IsDirectoryRequest, + type IsDirectorySuccess, + type OpenFileFailure, + type OpenFileRequest, + type OpenFileSuccess, + type PurgeFilesFailure, + type PurgeFilesRequest, + type PurgeFilesSuccess, + type ReadAssetFailure, + type ReadAssetRequest, + type ReadAssetSuccess, + type ReadBufferFailure, + type ReadBufferRequest, + type ReadBufferSuccess, + type ReadFileFailure, + type ReadFileRequest, + type ReadFileSuccess, + type ReadJsonFileFailure, + type ReadJsonFileRequest, + type ReadJsonFileSuccess, + type RemoveFileFailure, + type RemoveFileRequest, + type RemoveFileSuccess, + type RenameFileFailure, + type RenameFileRequest, + type RenameFileSuccess, + type RestoreFileFailure, + type RestoreFileRequest, + type RestoreFilesFailure, + type RestoreFilesRequest, + type RestoreFilesSuccess, + type RestoreFileSuccess, + type RevealFileFailure, + type RevealFileRequest, + type RevealFileSuccess, + type OpenFilePreviewSuccess, + type CloseFilePreviewSuccess, + type FileOperationSuccess, FileOperationFailure, - IOperation, + type IOperation, } from "../../Typings/Store/files"; export const readFileRequest = (fileName: string): ReadFileRequest => ({ diff --git a/src/components/Infobar/index.tsx b/src/components/Infobar/index.tsx index dd4b2d7e..8f2c9bce 100644 --- a/src/components/Infobar/index.tsx +++ b/src/components/Infobar/index.tsx @@ -1,6 +1,6 @@ import React, { useEffect } from "react"; import { useSelector } from "react-redux"; -import { IAppState } from "../../Store/Reducers"; +import type { IAppState } from "../../Store/Reducers"; import formatBytes from "../Functions/filesize"; const Infobar = () => { diff --git a/src/components/OperationBar/index.tsx b/src/components/OperationBar/index.tsx index b6c4bbc8..d621e184 100644 --- a/src/components/OperationBar/index.tsx +++ b/src/components/OperationBar/index.tsx @@ -4,7 +4,7 @@ import { ThemedButton, ThemedDiv } from "../Theme"; import { useDispatch } from "react-redux"; import { fileOperation } from "../../Store/ActionCreators/FilesActionCreators"; import { useSelector } from "react-redux"; -import { IAppState } from "../../Store/Reducers"; +import type { IAppState } from "../../Store/Reducers"; const OperationBar = () => { const dispatch = useDispatch();
Calculating...${options[key]}
${key}: