summaryrefslogtreecommitdiff
path: root/packages/frontend/src
diff options
context:
space:
mode:
authorかっこかり <67428053+kakkokari-gtyih@users.noreply.github.com>2024-07-30 14:42:46 +0900
committerGitHub <noreply@github.com>2024-07-30 14:42:46 +0900
commit45f909ef33056ac8f429d2a1707d1d7da96d2970 (patch)
tree64e0888519c7121064a649318c96957e95f4cf00 /packages/frontend/src
parentenhance(frontend): デッキのアンテナ・リスト選択画面からそ... (diff)
downloadsharkey-45f909ef33056ac8f429d2a1707d1d7da96d2970.tar.gz
sharkey-45f909ef33056ac8f429d2a1707d1d7da96d2970.tar.bz2
sharkey-45f909ef33056ac8f429d2a1707d1d7da96d2970.zip
enhance(frontend): ドライブのファイル・フォルダをドラッグしなくても移動できるように (#14318)
* feat(drive): ファイルをフォルダに移動するメニューを実装 (cherry picked from commit b89c2af6945c6a9f9f10e83f54d2bcf0f240b0b4) * tweak ui * Update Changelog * ファイル詳細からも移動できるように * feat(drive) フォルダのネストを移動するメニューを実装 (cherry picked from commit 8a7d710c6acb83f50c83f050bd1423c764d60a99) * Update Changelog * Update Changelog * lint * tweak ui --------- Co-authored-by: nafu-at <satsuki@nafusoft.dev> Co-authored-by: syuilo <4439005+syuilo@users.noreply.github.com>
Diffstat (limited to 'packages/frontend/src')
-rw-r--r--packages/frontend/src/components/MkDrive.folder.vue70
-rw-r--r--packages/frontend/src/components/MkDrive.vue6
-rw-r--r--packages/frontend/src/pages/drive.file.info.vue43
-rw-r--r--packages/frontend/src/scripts/get-drive-file-menu.ts13
4 files changed, 115 insertions, 17 deletions
diff --git a/packages/frontend/src/components/MkDrive.folder.vue b/packages/frontend/src/components/MkDrive.folder.vue
index c940596cde..d6dfaf34e5 100644
--- a/packages/frontend/src/components/MkDrive.folder.vue
+++ b/packages/frontend/src/components/MkDrive.folder.vue
@@ -27,7 +27,9 @@ SPDX-License-Identifier: AGPL-3.0-only
<p v-if="defaultStore.state.uploadFolder == folder.id" :class="$style.upload">
{{ i18n.ts.uploadFolder }}
</p>
- <button v-if="selectMode" class="_button" :class="[$style.checkbox, { [$style.checked]: isSelected }]" @click.prevent.stop="checkboxClicked"></button>
+ <button v-if="selectMode" class="_button" :class="$style.checkboxWrapper" @click.prevent.stop="checkboxClicked">
+ <div :class="[$style.checkbox, { [$style.checked]: isSelected }]"></div>
+ </button>
</div>
</template>
@@ -53,6 +55,7 @@ const props = withDefaults(defineProps<{
const emit = defineEmits<{
(ev: 'chosen', v: Misskey.entities.DriveFolder): void;
+ (ev: 'unchose', v: Misskey.entities.DriveFolder): void;
(ev: 'move', v: Misskey.entities.DriveFolder): void;
(ev: 'upload', file: File, folder: Misskey.entities.DriveFolder);
(ev: 'removeFile', v: Misskey.entities.DriveFile['id']): void;
@@ -68,7 +71,11 @@ const isDragging = ref(false);
const title = computed(() => props.folder.name);
function checkboxClicked() {
- emit('chosen', props.folder);
+ if (props.isSelected) {
+ emit('unchose', props.folder);
+ } else {
+ emit('chosen', props.folder);
+ }
}
function onClick() {
@@ -222,6 +229,17 @@ function rename() {
});
}
+function move() {
+ os.selectDriveFolder(false).then(folder => {
+ if (folder[0] && folder[0].id === props.folder.id) return;
+
+ misskeyApi('drive/folders/update', {
+ folderId: props.folder.id,
+ parentId: folder[0] ? folder[0].id : null,
+ });
+ });
+}
+
function deleteFolder() {
misskeyApi('drive/folders/delete', {
folderId: props.folder.id,
@@ -267,6 +285,10 @@ function onContextmenu(ev: MouseEvent) {
text: i18n.ts.rename,
icon: 'ti ti-forms',
action: rename,
+ }, {
+ text: i18n.ts.move,
+ icon: 'ti ti ti-folder-symlink',
+ action: move,
}, { type: 'divider' }, {
text: i18n.ts.delete,
icon: 'ti ti-trash',
@@ -310,17 +332,43 @@ function onContextmenu(ev: MouseEvent) {
}
}
-.checkbox {
+.checkboxWrapper {
position: absolute;
- bottom: 8px;
- right: 8px;
- width: 16px;
- height: 16px;
- background: #fff;
- border: solid 1px #000;
+ border-radius: 50%;
+ bottom: 2px;
+ right: 2px;
+ padding: 8px;
+ box-sizing: border-box;
+
+ > .checkbox {
+ position: relative;
+ width: 18px;
+ height: 18px;
+ background: #fff;
+ border: solid 2px var(--divider);
+ border-radius: 4px;
+ box-sizing: border-box;
+
+ &.checked {
+ border-color: var(--accent);
+ background: var(--accent);
+
+ &::after {
+ content: "\ea5e";
+ font-family: 'tabler-icons';
+ position: absolute;
+ top: 50%;
+ left: 50%;
+ transform: translate(-50%, -50%);
+ color: #fff;
+ font-size: 12px;
+ line-height: 22px;
+ }
+ }
+ }
- &.checked {
- background: var(--accent);
+ &:hover {
+ background: var(--accentedBg);
}
}
diff --git a/packages/frontend/src/components/MkDrive.vue b/packages/frontend/src/components/MkDrive.vue
index a9717b4fb7..dbb4917069 100644
--- a/packages/frontend/src/components/MkDrive.vue
+++ b/packages/frontend/src/components/MkDrive.vue
@@ -52,6 +52,7 @@ SPDX-License-Identifier: AGPL-3.0-only
:selectMode="select === 'folder'"
:isSelected="selectedFolders.some(x => x.id === f.id)"
@chosen="chooseFolder"
+ @unchose="unchoseFolder"
@move="move"
@upload="upload"
@removeFile="removeFile"
@@ -428,6 +429,11 @@ function chooseFolder(folderToChoose: Misskey.entities.DriveFolder) {
}
}
+function unchoseFolder(folderToUnchose: Misskey.entities.DriveFolder) {
+ selectedFolders.value = selectedFolders.value.filter(f => f.id !== folderToUnchose.id);
+ emit('change-selection', selectedFolders.value);
+}
+
function move(target?: Misskey.entities.DriveFolder | Misskey.entities.DriveFolder['id' | 'parentId']) {
if (!target) {
goRoot();
diff --git a/packages/frontend/src/pages/drive.file.info.vue b/packages/frontend/src/pages/drive.file.info.vue
index a774412f83..3026d00a2c 100644
--- a/packages/frontend/src/pages/drive.file.info.vue
+++ b/packages/frontend/src/pages/drive.file.info.vue
@@ -37,11 +37,17 @@ SPDX-License-Identifier: AGPL-3.0-only
</button>
</div>
</div>
- <div>
- <button class="_button" :class="$style.fileAltEditBtn" @click="describe()">
+ <div class="_gaps_s">
+ <button class="_button" :class="$style.kvEditBtn" @click="move()">
+ <MkKeyValue>
+ <template #key>{{ i18n.ts.folder }}</template>
+ <template #value>{{ folderHierarchy.join(' > ') }}<i class="ti ti-pencil" :class="$style.kvEditIcon"></i></template>
+ </MkKeyValue>
+ </button>
+ <button class="_button" :class="$style.kvEditBtn" @click="describe()">
<MkKeyValue>
<template #key>{{ i18n.ts.description }}</template>
- <template #value>{{ file.comment ? file.comment : `(${i18n.ts.none})` }}<i class="ti ti-pencil" :class="$style.fileAltEditIcon"></i></template>
+ <template #value>{{ file.comment ? file.comment : `(${i18n.ts.none})` }}<i class="ti ti-pencil" :class="$style.kvEditIcon"></i></template>
</MkKeyValue>
</button>
<MkKeyValue :class="$style.fileMetaDataChildren">
@@ -90,6 +96,18 @@ const props = defineProps<{
const fetching = ref(true);
const file = ref<Misskey.entities.DriveFile>();
+const folderHierarchy = computed(() => {
+ if (!file.value) return [i18n.ts.drive];
+ const folderNames = [i18n.ts.drive];
+
+ function get(folder: Misskey.entities.DriveFolder) {
+ if (folder.parent) get(folder.parent);
+ folderNames.push(folder.name);
+ }
+
+ if (file.value.folder) get(file.value.folder);
+ return folderNames;
+});
const isImage = computed(() => file.value?.type.startsWith('image/'));
async function fetch() {
@@ -122,6 +140,19 @@ function crop() {
});
}
+function move() {
+ if (!file.value) return;
+
+ os.selectDriveFolder(false).then(folder => {
+ misskeyApi('drive/files/update', {
+ fileId: file.value.id,
+ folderId: folder[0] ? folder[0].id : null,
+ }).then(async () => {
+ await fetch();
+ });
+ });
+}
+
function toggleSensitive() {
if (!file.value) return;
@@ -282,14 +313,14 @@ onMounted(async () => {
padding: .5rem 1rem;
}
-.fileAltEditBtn {
+.kvEditBtn {
text-align: start;
display: block;
width: 100%;
padding: .5rem 1rem;
border-radius: var(--radius);
- .fileAltEditIcon {
+ .kvEditIcon {
display: inline-block;
color: transparent;
visibility: hidden;
@@ -300,7 +331,7 @@ onMounted(async () => {
color: var(--accent);
background-color: var(--accentedBg);
- .fileAltEditIcon {
+ .kvEditIcon {
color: var(--accent);
visibility: visible;
}
diff --git a/packages/frontend/src/scripts/get-drive-file-menu.ts b/packages/frontend/src/scripts/get-drive-file-menu.ts
index 7c6c4b4db4..108648d640 100644
--- a/packages/frontend/src/scripts/get-drive-file-menu.ts
+++ b/packages/frontend/src/scripts/get-drive-file-menu.ts
@@ -41,6 +41,15 @@ function describe(file: Misskey.entities.DriveFile) {
});
}
+function move(file: Misskey.entities.DriveFile) {
+ os.selectDriveFolder(false).then(folder => {
+ misskeyApi('drive/files/update', {
+ fileId: file.id,
+ folderId: folder[0] ? folder[0].id : null,
+ });
+ });
+}
+
function toggleSensitive(file: Misskey.entities.DriveFile) {
misskeyApi('drive/files/update', {
fileId: file.id,
@@ -89,6 +98,10 @@ export function getDriveFileMenu(file: Misskey.entities.DriveFile, folder?: Miss
icon: 'ti ti-forms',
action: () => rename(file),
}, {
+ text: i18n.ts.move,
+ icon: 'ti ti-folder-symlink',
+ action: () => move(file),
+ }, {
text: file.isSensitive ? i18n.ts.unmarkAsSensitive : i18n.ts.markAsSensitive,
icon: file.isSensitive ? 'ti ti-eye' : 'ti ti-eye-exclamation',
action: () => toggleSensitive(file),