diff --git a/frontend/package.json b/frontend/package.json index aedaa499..1ebaaaa1 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -42,7 +42,6 @@ "videojs-hotkeys": "^0.2.28", "videojs-mobile-ui": "^1.1.1", "vue": "^3.5.17", - "vue-final-modal": "^4.5.5", "vue-i18n": "^11.1.10", "vue-lazyload": "^3.0.0", "vue-reader": "^1.2.17", diff --git a/frontend/pnpm-lock.yaml b/frontend/pnpm-lock.yaml index daa46285..cc488cd3 100644 --- a/frontend/pnpm-lock.yaml +++ b/frontend/pnpm-lock.yaml @@ -83,9 +83,6 @@ importers: vue: specifier: ^3.5.17 version: 3.5.28(typescript@5.9.3) - vue-final-modal: - specifier: ^4.5.5 - version: 4.5.5(@vueuse/core@14.2.1(vue@3.5.28(typescript@5.9.3)))(@vueuse/integrations@14.2.1(focus-trap@8.0.0)(jwt-decode@4.0.0)(vue@3.5.28(typescript@5.9.3)))(focus-trap@8.0.0)(vue@3.5.28(typescript@5.9.3)) vue-i18n: specifier: ^11.1.10 version: 11.2.8(vue@3.5.28(typescript@5.9.3)) @@ -2640,14 +2637,6 @@ packages: peerDependencies: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 - vue-final-modal@4.5.5: - resolution: {integrity: sha512-A6xgsXqE6eLw9e6Tq/W6pxDBmimPuSuvq20WL9TOZpZy7itPdGeNn8e1P15PCGqP2yHM3q2gJIchPY9ZJd8YsA==} - peerDependencies: - '@vueuse/core': '>=10.0.0' - '@vueuse/integrations': '>=10.0.0' - focus-trap: '>=7.2.0' - vue: '>=3.2.0' - vue-i18n@11.2.8: resolution: {integrity: sha512-vJ123v/PXCZntd6Qj5Jumy7UBmIuE92VrtdX+AXr+1WzdBHojiBxnAxdfctUFL+/JIN+VQH4BhsfTtiGsvVObg==} engines: {node: '>= 16'} @@ -4562,6 +4551,7 @@ snapshots: focus-trap@8.0.0: dependencies: tabbable: 6.4.0 + optional: true fraction.js@5.3.4: {} @@ -5053,7 +5043,8 @@ snapshots: systemjs@6.15.1: {} - tabbable@6.4.0: {} + tabbable@6.4.0: + optional: true tar-mini@0.2.0: {} @@ -5228,13 +5219,6 @@ snapshots: transitivePeerDependencies: - supports-color - vue-final-modal@4.5.5(@vueuse/core@14.2.1(vue@3.5.28(typescript@5.9.3)))(@vueuse/integrations@14.2.1(focus-trap@8.0.0)(jwt-decode@4.0.0)(vue@3.5.28(typescript@5.9.3)))(focus-trap@8.0.0)(vue@3.5.28(typescript@5.9.3)): - dependencies: - '@vueuse/core': 14.2.1(vue@3.5.28(typescript@5.9.3)) - '@vueuse/integrations': 14.2.1(focus-trap@8.0.0)(jwt-decode@4.0.0)(vue@3.5.28(typescript@5.9.3)) - focus-trap: 8.0.0 - vue: 3.5.28(typescript@5.9.3) - vue-i18n@11.2.8(vue@3.5.28(typescript@5.9.3)): dependencies: '@intlify/core-base': 11.2.8 diff --git a/frontend/src/components/prompts/BaseModal.vue b/frontend/src/components/prompts/BaseModal.vue index d92f0f73..1d4d9684 100644 --- a/frontend/src/components/prompts/BaseModal.vue +++ b/frontend/src/components/prompts/BaseModal.vue @@ -1,21 +1,61 @@ + + diff --git a/frontend/src/components/prompts/CreateFilePath.vue b/frontend/src/components/prompts/CreateFilePath.vue index 166240d0..71b87584 100644 --- a/frontend/src/components/prompts/CreateFilePath.vue +++ b/frontend/src/components/prompts/CreateFilePath.vue @@ -35,12 +35,17 @@ const props = defineProps({ type: Boolean, default: false, }, + path: { + type: String, + default: null, + }, }); const container = ref(null); const path = computed(() => { - let basePath = fileStore.isFiles ? route.path : url.removeLastDir(route.path); + const routePath = props.path || route.path; + let basePath = fileStore.isFiles ? routePath : url.removeLastDir(routePath); if (!basePath.endsWith("/")) { basePath += "/"; } diff --git a/frontend/src/components/prompts/FileList.vue b/frontend/src/components/prompts/FileList.vue index 69478734..b2a1c6a2 100644 --- a/frontend/src/components/prompts/FileList.vue +++ b/frontend/src/components/prompts/FileList.vue @@ -168,7 +168,13 @@ export default { this.showHover({ prompt: "newDir", action: null, - confirm: null, + confirm: (url) => { + const paths = url.split("/"); + this.items.push({ + name: paths[paths.length - 2], + url: url, + }); + }, props: { redirect: false, base: this.current === this.$route.path ? null : this.current, diff --git a/frontend/src/components/prompts/NewDir.vue b/frontend/src/components/prompts/NewDir.vue index 85d47bb8..daa1b221 100644 --- a/frontend/src/components/prompts/NewDir.vue +++ b/frontend/src/components/prompts/NewDir.vue @@ -14,7 +14,7 @@ v-model.trim="name" tabindex="1" /> - +
@@ -41,7 +41,7 @@ diff --git a/frontend/src/css/base.css b/frontend/src/css/base.css index f0b8ef0c..cdb3319b 100644 --- a/frontend/src/css/base.css +++ b/frontend/src/css/base.css @@ -182,10 +182,11 @@ html[dir="rtl"] .breadcrumbs a { background: var(--textSecondary) !important; } -.vfm-modal { - z-index: 9999999 !important; -} - body > div[style*="z-index: 9990"] { z-index: 10000 !important; } + +#modal-background .button:focus { + outline: 1px solid #2195f32d; + outline-offset: 1px; +} diff --git a/frontend/src/css/styles.css b/frontend/src/css/styles.css index 5ac7d8d5..bab7cd19 100644 --- a/frontend/src/css/styles.css +++ b/frontend/src/css/styles.css @@ -1,6 +1,5 @@ @import "normalize.css/normalize.css"; @import "vue-toastification/dist/index.css"; -@import "vue-final-modal/style.css"; @import "./_variables.css"; @import "./_buttons.css"; @import "./_inputs.css"; diff --git a/frontend/src/main.ts b/frontend/src/main.ts index 42f44205..f6b7ac78 100644 --- a/frontend/src/main.ts +++ b/frontend/src/main.ts @@ -2,7 +2,6 @@ import { disableExternal } from "@/utils/constants"; import { createApp } from "vue"; import VueNumberInput from "@chenfengyuan/vue-number-input"; import VueLazyload from "vue-lazyload"; -import { createVfm } from "vue-final-modal"; import Toast, { POSITION, useToast } from "vue-toastification"; import type { ToastOptions, @@ -27,7 +26,6 @@ dayjs.extend(relativeTime); dayjs.extend(duration); const pinia = createPinia(router); -const vfm = createVfm(); const app = createApp(App); @@ -39,7 +37,6 @@ app.use(Toast, { newestOnTop: true, } satisfies PluginOptions); -app.use(vfm); app.use(i18n); app.use(pinia); app.use(router); diff --git a/frontend/src/stores/layout.ts b/frontend/src/stores/layout.ts index 372fca06..fbd6d99f 100644 --- a/frontend/src/stores/layout.ts +++ b/frontend/src/stores/layout.ts @@ -76,7 +76,7 @@ export const useLayoutStore = defineStore("layout", { }); }, closeHovers() { - this.prompts.shift()?.close?.(); + this.prompts.pop()?.close?.(); }, // easily reset state using `$reset` clearLayout() { diff --git a/frontend/src/views/files/Editor.vue b/frontend/src/views/files/Editor.vue index dbde609e..2b2852d3 100644 --- a/frontend/src/views/files/Editor.vue +++ b/frontend/src/views/files/Editor.vue @@ -121,7 +121,7 @@ const isMarkdownFile = fileStore.req?.name.endsWith(".markdown"); const katexOptions = { output: "mathml" as const, - throwOnError: false + throwOnError: false, }; marked.use(markedKatex(katexOptions)); @@ -233,6 +233,11 @@ const initEditor = (fileContent: string) => { editor.value.setFontSize(fontSize.value); editor.value.focus(); + + const selection = editor.value?.getSelection(); + selection.on("changeSelection", function () { + isSelectionEmpty.value = selection.isEmpty(); + }); }; const keyEvent = (event: KeyboardEvent) => { @@ -296,6 +301,7 @@ const close = () => { prompt: "discardEditorChanges", confirm: (event: Event) => { event.preventDefault(); + editor.value?.session.getUndoManager().reset(); finishClose(); }, saveAction: async () => {