mirror of
https://github.com/filebrowser/filebrowser.git
synced 2026-01-22 18:27:42 +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 {
|
||||
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) {
|
||||
return new Promise<void>((resolve, reject) => {
|
||||
typeof navigator.permissions !== "undefined" &&
|
||||
|
|
|
|||
|
|
@ -41,7 +41,30 @@
|
|||
</div>
|
||||
</div>
|
||||
<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
|
||||
v-show="isPreview && isMarkdownFile"
|
||||
|
|
@ -74,6 +97,7 @@ import { marked } from "marked";
|
|||
import { inject, onBeforeUnmount, onMounted, ref, watchEffect } from "vue";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import { onBeforeRouteUpdate, useRoute, useRouter } from "vue-router";
|
||||
import { read, copy } from "@/utils/clipboard";
|
||||
|
||||
const $showError = inject<IToastError>("$showError")!;
|
||||
|
||||
|
|
@ -95,6 +119,35 @@ const isMarkdownFile =
|
|||
fileStore.req?.name.endsWith(".md") ||
|
||||
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(() => {
|
||||
window.addEventListener("keydown", keyEvent);
|
||||
window.addEventListener("beforeunload", handlePageChange);
|
||||
|
|
@ -132,6 +185,11 @@ onMounted(() => {
|
|||
|
||||
editor.value.setFontSize(fontSize.value);
|
||||
editor.value.focus();
|
||||
|
||||
editor.value.getSelection().on("changeSelection", () => {
|
||||
isSelectionEmpty.value =
|
||||
editor.value == null || editor.value.getSelectedText().length == 0;
|
||||
});
|
||||
});
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
|
|
@ -250,4 +308,32 @@ const preview = () => {
|
|||
margin: 0 0.5em;
|
||||
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>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue