From 8b3996272f82aa7e90440a5dc00e95946f9d5209 Mon Sep 17 00:00:00 2001 From: Blodhgarm Date: Wed, 30 Sep 2026 18:54:07 -0500 Subject: [PATCH 01/18] feat: Start Refactors for Sidebar Style file browser mode for file tab - Use DockView for split pane of the sidebar and main file/folder browser - Start work on sidebar folder browser and the needed layout changes - Add ability to toggle expanded view for file browser to instead of being within centered column, adjust it to take all the width possible. - Add ability to make modals into pullout containers - Fix issues with small resolutions allowing for the background elements to be scrolled leading to double scrolling with modal. - Resolve minor sizing bug that lead to gap at the bottom or clipping of bottom element on odd scaling and resolutions. --- .../src/pages/instance/files/index.vue | 21 +- apps/frontend/package.json | 7 +- apps/frontend/src/app.vue | 35 +- .../src/pages/hosting/manage/[id].vue | 6 +- .../src/pages/hosting/manage/[id]/files.vue | 6 + packages/ui/package.json | 15 +- packages/ui/src/components/base/NavTabs.vue | 6 +- .../ui/src/components/floating/Tooltip.vue | 24 +- packages/ui/src/components/modal/NewModal.vue | 125 +++++- .../components/servers/backups/BackupItem.vue | 178 ++++---- packages/ui/src/composables/modal-stack.ts | 13 +- .../ui/src/composables/use-ready-state.ts | 4 +- packages/ui/src/composables/virtual-scroll.ts | 4 +- .../files-tab/components/FileActionBar.vue | 326 ++++++++++++++ .../files-tab/components/FileBrowserPanel.vue | 235 ++++++++++ .../files-tab/components/FileNavbar.vue | 421 +++++------------- .../files-tab/components/FileSideBar.vue | 132 ++++++ .../components/FileSidebarHeader.vue | 73 +++ .../files-tab/components/FileTableHeader.vue | 17 +- .../files-tab/components/FileTableRow.vue | 187 +++++--- .../components/editor/FileEditor.vue | 2 +- .../src/layouts/shared/files-tab/layout.vue | 414 +++++++++-------- .../files-tab/providers/file-browser-ui.ts | 88 ++++ .../files-tab/providers/file-manager.ts | 24 +- .../layouts/wrapped/hosting/manage/files.vue | 93 ++-- .../layouts/wrapped/hosting/manage/root.vue | 42 +- packages/ui/src/locales.eager.ts | 2 +- packages/ui/src/providers/app-root.ts | 8 + packages/ui/src/providers/tooltip.ts | 37 +- packages/ui/src/utils/common-messages.ts | 4 + 30 files changed, 1817 insertions(+), 732 deletions(-) create mode 100644 packages/ui/src/layouts/shared/files-tab/components/FileActionBar.vue create mode 100644 packages/ui/src/layouts/shared/files-tab/components/FileBrowserPanel.vue create mode 100644 packages/ui/src/layouts/shared/files-tab/components/FileSideBar.vue create mode 100644 packages/ui/src/layouts/shared/files-tab/components/FileSidebarHeader.vue create mode 100644 packages/ui/src/layouts/shared/files-tab/providers/file-browser-ui.ts create mode 100644 packages/ui/src/providers/app-root.ts diff --git a/apps/app-frontend/src/pages/instance/files/index.vue b/apps/app-frontend/src/pages/instance/files/index.vue index be579b82737..a75268ede23 100644 --- a/apps/app-frontend/src/pages/instance/files/index.vue +++ b/apps/app-frontend/src/pages/instance/files/index.vue @@ -12,7 +12,7 @@ import { } from '@modrinth/ui' import { useQuery } from '@tanstack/vue-query' import { invoke } from '@tauri-apps/api/core' -import { computed, ref, watch } from 'vue' +import {computed, Ref, ref, watch} from 'vue' import { useAppEvent } from '@/composables/use-app-event' import { get_full_path } from '@/helpers/instance' @@ -113,9 +113,13 @@ await instanceRootQuery.suspense() await directoryQuery.refetch() firstPaintPending.value = false +const isRefreshing = ref(false) + async function refresh() { debug('refresh: called, currentPath =', currentPath.value, 'instanceRoot =', instanceRoot.value) + isRefreshing.value = true; await directoryQuery.refetch() + isRefreshing.value = false; } function navigateTo(path: string) { @@ -302,10 +306,22 @@ watch(instanceId, async () => { await refresh() }) +const directories: Record> = {}; +const expandedDirectories: Ref = ref([]); + provideFileManager({ isReadOnly, readOnlyReason: computed(() => formatMessage(messages.readOnly)), - items, + currentItems: items, + directoryTree: { + prefetch(path: string) { + + }, + getEntries(path: string) { + + }, + expandedEntries: expandedDirectories + }, loading, error, currentPath, @@ -325,6 +341,7 @@ provideFileManager({ uploadState, extractFile: handleExtractFile, refresh, + isRefreshing, basePath: instanceRoot, openInFolder: (path: string) => highlightInFolder(path), downloadButtonLabel: formatMessage(messages.saveAs), diff --git a/apps/frontend/package.json b/apps/frontend/package.json index 638a52f8e8a..6c1c71b24b9 100644 --- a/apps/frontend/package.json +++ b/apps/frontend/package.json @@ -39,6 +39,7 @@ }, "dependencies": { "@contentauth/c2pa-web": "^0.13.1", + "@floating-ui/vue": "^2.0.1", "@formatjs/intl-localematcher": "^0.5.4", "@ltd/j-toml": "^1.38.0", "@modrinth/api-client": "workspace:*", @@ -47,6 +48,9 @@ "@modrinth/moderation": "workspace:*", "@modrinth/ui": "workspace:*", "@modrinth/utils": "workspace:*", + "@run-slicer/cfr": "0.1.8-0.152", + "@run-slicer/procyon": "0.1.2-0.6.0", + "@run-slicer/vf": "0.6.4-1.12.0", "@sentry/nuxt": "^10.33.0", "@tanstack/vue-query": "5.101.4", "@types/three": "^0.172.0", @@ -60,7 +64,7 @@ "chart.js": "^4.5.1", "dayjs": "^1.11.7", "dompurify": "^3.1.7", - "@floating-ui/vue": "^2.0.1", + "file-type": "^22.1.0", "fuse.js": "^6.6.2", "highlight.js": "^11.7.0", "intl-messageformat": "^10.7.7", @@ -68,6 +72,7 @@ "jose": "^6.2.2", "js-yaml": "^4.1.0", "jszip": "^3.10.1", + "krakatau-web": "1.1.0-beta", "lru-cache": "^11.2.4", "markdown-it": "14.1.0", "pathe": "^1.1.2", diff --git a/apps/frontend/src/app.vue b/apps/frontend/src/app.vue index 3741d3f1027..dbb3cad299c 100644 --- a/apps/frontend/src/app.vue +++ b/apps/frontend/src/app.vue @@ -1,16 +1,18 @@ diff --git a/packages/ui/package.json b/packages/ui/package.json index 8978e7a6f7c..dca78062dcf 100644 --- a/packages/ui/package.json +++ b/packages/ui/package.json @@ -61,11 +61,15 @@ "@codemirror/language": "^6.9.3", "@codemirror/state": "^6.3.2", "@codemirror/view": "^6.22.1", + "@floating-ui/vue": "^2.0.1", "@intercom/messenger-js-sdk": "^0.0.14", "@modrinth/api-client": "workspace:*", "@modrinth/assets": "workspace:*", "@modrinth/blog": "workspace:*", "@modrinth/utils": "workspace:*", + "@run-slicer/cfr": "0.1.8-0.152", + "@run-slicer/procyon": "0.1.2-0.6.0", + "@run-slicer/vf": "0.6.4-1.12.0", "@tanstack/vue-query": "5.101.4", "@tresjs/cientos": "^4.3.0", "@tresjs/core": "^4.3.4", @@ -78,25 +82,32 @@ "@xterm/addon-fit": "^0.11.0", "@xterm/addon-search": "^0.16.0", "@xterm/xterm": "^6.0.0", + "@zip.js/zip.js": "^2.8.34", "ace-builds": "^1.43.5", "apexcharts": "^4.0.0", "colord": "^2.9.3", "dayjs": "^1.11.10", + "dockview": "^8.3.1", + "dockview-vue": "^8.2.0", "dompurify": "^3.1.7", "es-toolkit": "^1.44.0", - "flatpickr": "^4.6.13", "fabric": "^7.4.0", - "@floating-ui/vue": "^2.0.1", + "file-type": "^22.1.0", + "flatpickr": "^4.6.13", "fuse.js": "^6.6.2", "highlight.js": "^11.9.0", "intl-messageformat": "^10.7.7", + "js-yaml": "^4.1.1", "jszip": "^3.10.1", + "krakatau-web": "1.1.0-beta", "lru-cache": "^11.2.4", "markdown-it": "^13.0.2", + "mime": "^4.1.0", "motion-v": "^2.2.1", "overlayscrollbars": "^2.15.1", "postprocessing": "^6.37.6", "qrcode.vue": "^3.4.1", + "smol-toml": "^1.8.0", "three": "^0.172.0", "vue-i18n": "^10.0.0", "vue-select": "4.0.0-beta.6", diff --git a/packages/ui/src/components/base/NavTabs.vue b/packages/ui/src/components/base/NavTabs.vue index 1958a4498b8..ff37cac63e5 100644 --- a/packages/ui/src/components/base/NavTabs.vue +++ b/packages/ui/src/components/base/NavTabs.vue @@ -1,7 +1,7 @@