mirror of
https://github.com/filebrowser/filebrowser.git
synced 2026-01-23 02:35:10 +00:00
feat: added cut, copy, paste and show command palette functions in header (#5648)
This commit is contained in:
parent
550a73b6ba
commit
785b7abb7b
3 changed files with 105 additions and 1 deletions
|
|
@ -185,3 +185,7 @@ html[dir="rtl"] .breadcrumbs a {
|
||||||
.vfm-modal {
|
.vfm-modal {
|
||||||
z-index: 9999999 !important;
|
z-index: 9999999 !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
body > div[style*="z-index: 9990"] {
|
||||||
|
z-index: 10000 !important;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -51,6 +51,20 @@ export function copy(data: ClipboardArgs, opts?: ClipboardOpts) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function read() {
|
||||||
|
return new Promise<string>((resolve, reject) => {
|
||||||
|
if (
|
||||||
|
// Clipboard API requires secure context
|
||||||
|
window.isSecureContext &&
|
||||||
|
typeof navigator.clipboard !== "undefined"
|
||||||
|
) {
|
||||||
|
navigator.clipboard.readText().then(resolve).catch(reject);
|
||||||
|
} else {
|
||||||
|
reject();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function getPermission(name: string) {
|
function getPermission(name: string) {
|
||||||
return new Promise<void>((resolve, reject) => {
|
return new Promise<void>((resolve, reject) => {
|
||||||
typeof navigator.permissions !== "undefined" &&
|
typeof navigator.permissions !== "undefined" &&
|
||||||
|
|
|
||||||
|
|
@ -41,7 +41,30 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<template v-else>
|
<template v-else>
|
||||||
<Breadcrumbs base="/files" noLink />
|
<div class="editor-header">
|
||||||
|
<Breadcrumbs base="/files" noLink />
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<button
|
||||||
|
:disabled="isSelectionEmpty"
|
||||||
|
@click="executeEditorCommand('copy')"
|
||||||
|
>
|
||||||
|
<span><i class="material-icons">content_copy</i></span>
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
:disabled="isSelectionEmpty"
|
||||||
|
@click="executeEditorCommand('cut')"
|
||||||
|
>
|
||||||
|
<span><i class="material-icons">content_cut</i></span>
|
||||||
|
</button>
|
||||||
|
<button @click="executeEditorCommand('paste')">
|
||||||
|
<span><i class="material-icons">content_paste</i></span>
|
||||||
|
</button>
|
||||||
|
<button @click="executeEditorCommand('openCommandPalette')">
|
||||||
|
<span><i class="material-icons">more_vert</i></span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
v-show="isPreview && isMarkdownFile"
|
v-show="isPreview && isMarkdownFile"
|
||||||
|
|
@ -74,6 +97,7 @@ import { marked } from "marked";
|
||||||
import { inject, onBeforeUnmount, onMounted, ref, watchEffect } from "vue";
|
import { inject, onBeforeUnmount, onMounted, ref, watchEffect } from "vue";
|
||||||
import { useI18n } from "vue-i18n";
|
import { useI18n } from "vue-i18n";
|
||||||
import { onBeforeRouteUpdate, useRoute, useRouter } from "vue-router";
|
import { onBeforeRouteUpdate, useRoute, useRouter } from "vue-router";
|
||||||
|
import { read, copy } from "@/utils/clipboard";
|
||||||
|
|
||||||
const $showError = inject<IToastError>("$showError")!;
|
const $showError = inject<IToastError>("$showError")!;
|
||||||
|
|
||||||
|
|
@ -95,6 +119,35 @@ const isMarkdownFile =
|
||||||
fileStore.req?.name.endsWith(".md") ||
|
fileStore.req?.name.endsWith(".md") ||
|
||||||
fileStore.req?.name.endsWith(".markdown");
|
fileStore.req?.name.endsWith(".markdown");
|
||||||
|
|
||||||
|
const isSelectionEmpty = ref(true);
|
||||||
|
|
||||||
|
const executeEditorCommand = (name: string) => {
|
||||||
|
if (name == "paste") {
|
||||||
|
read()
|
||||||
|
.then((data) => {
|
||||||
|
editor.value?.execCommand("paste", {
|
||||||
|
text: data,
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
if (
|
||||||
|
document.queryCommandSupported &&
|
||||||
|
document.queryCommandSupported("paste")
|
||||||
|
) {
|
||||||
|
document.execCommand("paste");
|
||||||
|
} else {
|
||||||
|
console.warn("the clipboard api is not supported", e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (name == "copy" || name == "cut") {
|
||||||
|
const selectedText = editor.value?.getCopyText();
|
||||||
|
copy({ text: selectedText });
|
||||||
|
}
|
||||||
|
editor.value?.execCommand(name);
|
||||||
|
};
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
window.addEventListener("keydown", keyEvent);
|
window.addEventListener("keydown", keyEvent);
|
||||||
window.addEventListener("beforeunload", handlePageChange);
|
window.addEventListener("beforeunload", handlePageChange);
|
||||||
|
|
@ -132,6 +185,11 @@ onMounted(() => {
|
||||||
|
|
||||||
editor.value.setFontSize(fontSize.value);
|
editor.value.setFontSize(fontSize.value);
|
||||||
editor.value.focus();
|
editor.value.focus();
|
||||||
|
|
||||||
|
editor.value.getSelection().on("changeSelection", () => {
|
||||||
|
isSelectionEmpty.value =
|
||||||
|
editor.value == null || editor.value.getSelectedText().length == 0;
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
onBeforeUnmount(() => {
|
onBeforeUnmount(() => {
|
||||||
|
|
@ -250,4 +308,32 @@ const preview = () => {
|
||||||
margin: 0 0.5em;
|
margin: 0 0.5em;
|
||||||
color: var(--fg);
|
color: var(--fg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.editor-header {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
|
||||||
|
.editor-header > div > button {
|
||||||
|
background: transparent;
|
||||||
|
color: var(--action);
|
||||||
|
border: none;
|
||||||
|
outline: none;
|
||||||
|
opacity: 0.8;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.editor-header > div > button:hover:not(:disabled) {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.editor-header > div > button:disabled {
|
||||||
|
opacity: 0.5;
|
||||||
|
cursor: not-allowed;
|
||||||
|
}
|
||||||
|
|
||||||
|
.editor-header > div > button > span > i {
|
||||||
|
font-size: 1.2rem;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue