Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

enhance(frontend): ドライブのファイル・フォルダをドラッグしなくても移動できるように #14318

Merged
merged 11 commits into from
Jul 30, 2024
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
- Enhance: AiScriptを0.19.0にアップデート
- Enhance: Allow negative delay for MFM animation elements (`tada`, `jelly`, `twitch`, `shake`, `spin`, `jump`, `bounce`, `rainbow`)
- Enhance: センシティブなメディアを開く際に確認ダイアログを出せるように
- Enhance: ドライブのファイル・フォルダをドラッグしなくても移動できるように
(Cherry-picked from https://github.com/nafu-at/misskey/commit/b89c2af6945c6a9f9f10e83f54d2bcf0f240b0b4, https://github.com/nafu-at/misskey/commit/8a7d710c6acb83f50c83f050bd1423c764d60a99)
- Enhance: デッキのアンテナ・リスト選択画面からそれぞれを新規作成できるように
- Fix: `/about#federation` ページなどで各インスタンスのチャートが表示されなくなっていた問題を修正
- Fix: ユーザーページの追加情報のラベルを投稿者のサーバーの絵文字で表示する (#13968)
Expand Down
72 changes: 60 additions & 12 deletions packages/frontend/src/components/MkDrive.folder.vue
Original file line number Diff line number Diff line change
Expand Up @@ -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>

Expand All @@ -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;
Expand All @@ -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() {
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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',
Expand Down Expand Up @@ -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;

&.checked {
background: var(--accent);
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;
}
}
}

&:hover {
background: var(--accentedBg);
}
}

Expand Down
6 changes: 6 additions & 0 deletions packages/frontend/src/components/MkDrive.vue
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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();
Expand Down
43 changes: 37 additions & 6 deletions packages/frontend/src/pages/drive.file.info.vue
Original file line number Diff line number Diff line change
Expand Up @@ -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">
Expand Down Expand Up @@ -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() {
Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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;
Expand All @@ -300,7 +331,7 @@ onMounted(async () => {
color: var(--accent);
background-color: var(--accentedBg);

.fileAltEditIcon {
.kvEditIcon {
color: var(--accent);
visibility: visible;
}
Expand Down
13 changes: 13 additions & 0 deletions packages/frontend/src/scripts/get-drive-file-menu.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -88,6 +97,10 @@ export function getDriveFileMenu(file: Misskey.entities.DriveFile, folder?: Miss
text: i18n.ts.rename,
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',
Expand Down
Loading