This commit is contained in:
syuilo 2025-05-10 18:18:05 +09:00
parent 6d5e9506e4
commit 90ac029317
10 changed files with 121 additions and 38 deletions

View File

@ -230,7 +230,7 @@ function rename() {
}
function move() {
os.selectDriveFolder(false).then(folder => {
os.selectDriveFolder().then(folder => {
if (folder[0] && folder[0].id === props.folder.id) return;
misskeyApi('drive/folders/update', {

View File

@ -36,6 +36,25 @@ SPDX-License-Identifier: AGPL-3.0-only
</template>
<div>
<div v-if="select === 'folder'">
<template v-if="folder == null">
<MkButton v-if="!isRootSelected" @click="isRootSelected = true">
<i class="ti ti-square"></i> {{ i18n.ts.selectThisFolder }}
</MkButton>
<MkButton v-else @click="isRootSelected = false">
<i class="ti ti-checkbox"></i> {{ i18n.ts.unselectThisFolder }}
</MkButton>
</template>
<template v-else>
<MkButton v-if="!selectedFolders.some(f => f.id === folder.id)" @click="selectedFolders.push(folder)">
<i class="ti ti-square"></i> {{ i18n.ts.selectThisFolder }}
</MkButton>
<MkButton v-else @click="selectedFolders = selectedFolders.filter(f => f.id !== folder.id)">
<i class="ti ti-checkbox"></i> {{ i18n.ts.unselectThisFolder }}
</MkButton>
</template>
</div>
<div
ref="main"
:class="[$style.main, { [$style.uploading]: uploadings.length > 0, [$style.fetching]: fetching }]"
@ -85,7 +104,7 @@ SPDX-License-Identifier: AGPL-3.0-only
:folder="folder"
:selectMode="select === 'file' || isEditMode"
:isSelected="selectedFiles.some(x => x.id === file.id)"
@chosen="chooseFile"
@chosen="onChooseFile"
@dragstart="isDragSource = true"
@dragend="isDragSource = false"
/>
@ -134,7 +153,7 @@ import { isSeparatorNeeded, getSeparatorInfo, makeDateGroupedTimelineComputedRef
import { usePagination } from '@/composables/use-pagination.js';
const props = withDefaults(defineProps<{
initialFolder?: Misskey.entities.DriveFolder;
initialFolder?: Misskey.entities.DriveFolder['id'] | null;
type?: string;
multiple?: boolean;
select?: 'file' | 'folder' | null;
@ -144,8 +163,8 @@ const props = withDefaults(defineProps<{
});
const emit = defineEmits<{
(ev: 'selected', v: Misskey.entities.DriveFile | Misskey.entities.DriveFolder): void;
(ev: 'change-selection', v: Misskey.entities.DriveFile[] | Misskey.entities.DriveFolder[]): void;
(ev: 'changeSelectedFiles', v: Misskey.entities.DriveFile[]): void;
(ev: 'changeSelectedFolders', v: (Misskey.entities.DriveFolder | null)[]): void;
(ev: 'move-root'): void;
(ev: 'cd', v: Misskey.entities.DriveFolder | null): void;
(ev: 'open-folder', v: Misskey.entities.DriveFolder): void;
@ -153,8 +172,6 @@ const emit = defineEmits<{
const folder = ref<Misskey.entities.DriveFolder | null>(null);
const hierarchyFolders = ref<Misskey.entities.DriveFolder[]>([]);
const selectedFiles = ref<Misskey.entities.DriveFile[]>([]);
const selectedFolders = ref<Misskey.entities.DriveFolder[]>([]);
const uploadings = uploads;
//
@ -166,6 +183,18 @@ const isDragSource = ref(false);
const isEditMode = ref(false);
const selectedFiles = ref<Misskey.entities.DriveFile[]>([]);
const selectedFolders = ref<Misskey.entities.DriveFolder[]>([]);
const isRootSelected = ref(false);
watch(selectedFiles, () => {
emit('changeSelectedFiles', selectedFiles.value);
});
watch([selectedFolders, isRootSelected], () => {
emit('changeSelectedFolders', isRootSelected.value ? [null, ...selectedFolders.value] : selectedFolders.value);
});
const fetching = ref(true);
const sortModeSelect = ref<NonNullable<Misskey.entities.DriveFilesRequest['sort']>>('+createdAt');
@ -403,7 +432,7 @@ function upload(file: File, folderToUpload?: Misskey.entities.DriveFolder | null
});
}
function chooseFile(file: Misskey.entities.DriveFile) {
function onChooseFile(file: Misskey.entities.DriveFile) {
const isAlreadySelected = selectedFiles.value.some(f => f.id === file.id);
if (isEditMode.value) {
@ -421,13 +450,11 @@ function chooseFile(file: Misskey.entities.DriveFile) {
} else {
selectedFiles.value.push(file);
}
emit('change-selection', selectedFiles.value);
} else {
if (isAlreadySelected) {
emit('selected', file);
//emit('selected', file);
} else {
selectedFiles.value = [file];
emit('change-selection', [file]);
}
}
}
@ -440,20 +467,17 @@ function chooseFolder(folderToChoose: Misskey.entities.DriveFolder) {
} else {
selectedFolders.value.push(folderToChoose);
}
emit('change-selection', selectedFolders.value);
} else {
if (isAlreadySelected) {
emit('selected', folderToChoose);
//emit('selected', folderToChoose);
} else {
selectedFolders.value = [folderToChoose];
emit('change-selection', [folderToChoose]);
}
}
}
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']) {
@ -487,7 +511,7 @@ function move(target?: Misskey.entities.DriveFolder | Misskey.entities.DriveFold
async function moveFilesBulk() {
if (selectedFiles.value.length === 0) return;
const toFolder = await os.selectDriveFolder(false);
const toFolder = await os.selectDriveFolder(folder.value ? folder.value.id : null);
os.apiWithDialog('drive/files/move-bulk', {
fileIds: selectedFiles.value.map(f => f.id),

View File

@ -3,5 +3,5 @@
* SPDX-License-Identifier: AGPL-3.0-only
*/
import MkDriveSelectDialog from './MkDriveSelectDialog.vue';
import MkDriveSelectDialog from './MkDriveFileSelectDialog.vue';
void MkDriveSelectDialog;

View File

@ -9,43 +9,41 @@ SPDX-License-Identifier: AGPL-3.0-only
:width="800"
:height="500"
:withOkButton="true"
:okButtonDisabled="(type === 'file') && (selected.length === 0)"
:okButtonDisabled="selected.length === 0"
@click="cancel()"
@close="cancel()"
@ok="ok()"
@closed="emit('closed')"
>
<template #header>
{{ multiple ? ((type === 'file') ? i18n.ts.selectFiles : i18n.ts.selectFolders) : ((type === 'file') ? i18n.ts.selectFile : i18n.ts.selectFolder) }}
<span v-if="selected.length > 0" style="margin-left: 8px; opacity: 0.5;">({{ number(selected.length) }})</span>
{{ multiple ? i18n.ts.selectFiles : i18n.ts.selectFile }}
<span v-if="selected.length > 0" style="margin-left: 8px; opacity: 0.5;">({{ selected.length }})</span>
</template>
<XDrive :multiple="multiple" :select="type" @changeSelection="onChangeSelection" @selected="ok()"/>
<MkDrive :multiple="multiple" select="file" :initialFolder="initialFolder" @changeSelection="onChangeSelection"/>
</MkModalWindow>
</template>
<script lang="ts" setup>
import { ref, useTemplateRef } from 'vue';
import * as Misskey from 'misskey-js';
import XDrive from '@/components/MkDrive.vue';
import MkDrive from '@/components/MkDrive.vue';
import MkModalWindow from '@/components/MkModalWindow.vue';
import number from '@/filters/number.js';
import { i18n } from '@/i18n.js';
withDefaults(defineProps<{
type?: 'file' | 'folder';
initialFolder?: Misskey.entities.DriveFolder['id'] | null;
multiple: boolean;
}>(), {
type: 'file',
});
const emit = defineEmits<{
(ev: 'done', r?: Misskey.entities.DriveFile[] | Misskey.entities.DriveFolder[]): void;
(ev: 'done', r?: Misskey.entities.DriveFile[]): void;
(ev: 'closed'): void;
}>();
const dialog = useTemplateRef('dialog');
const selected = ref<Misskey.entities.DriveFile[] | Misskey.entities.DriveFolder[]>([]);
const selected = ref<Misskey.entities.DriveFile[]>([]);
function ok() {
emit('done', selected.value);
@ -57,7 +55,7 @@ function cancel() {
dialog.value?.close();
}
function onChangeSelection(v: Misskey.entities.DriveFile[] | Misskey.entities.DriveFolder[]) {
function onChangeSelection(v: Misskey.entities.DriveFile[]) {
selected.value = v;
}
</script>

View File

@ -0,0 +1,63 @@
<!--
SPDX-FileCopyrightText: syuilo and misskey-project
SPDX-License-Identifier: AGPL-3.0-only
-->
<template>
<MkModalWindow
ref="dialog"
:width="800"
:height="500"
:withOkButton="true"
:okButtonDisabled="selected.length === 0"
@click="cancel()"
@close="cancel()"
@ok="ok()"
@closed="emit('closed')"
>
<template #header>
{{ multiple ? i18n.ts.selectFolders : i18n.ts.selectFolder }}
<span v-if="multiple && selected.length > 0" style="margin-left: 8px; opacity: 0.5;">({{ selected.length }})</span>
</template>
<MkDrive :multiple="multiple" select="folder" :initialFolder="initialFolder" @changeSelection="onChangeSelection"/>
</MkModalWindow>
</template>
<script lang="ts" setup>
import { ref, useTemplateRef } from 'vue';
import * as Misskey from 'misskey-js';
import MkDrive from '@/components/MkDrive.vue';
import MkModalWindow from '@/components/MkModalWindow.vue';
import { i18n } from '@/i18n.js';
withDefaults(defineProps<{
initialFolder?: Misskey.entities.DriveFolder['id'] | null;
multiple?: boolean;
}>(), {
initialFolder: null,
multiple: false,
});
const emit = defineEmits<{
(ev: 'done', r?: Misskey.entities.DriveFolder[]): void;
(ev: 'closed'): void;
}>();
const dialog = useTemplateRef('dialog');
const selected = ref<Misskey.entities.DriveFolder[]>([]);
function ok() {
emit('done', selected.value);
dialog.value?.close();
}
function cancel() {
emit('done');
dialog.value?.close();
}
function onChangeSelection(v: Misskey.entities.DriveFolder[]) {
selected.value = v;
}
</script>

View File

@ -594,8 +594,7 @@ export async function selectUser(opts: { includeSelf?: boolean; localOnly?: bool
export async function selectDriveFile(multiple: boolean): Promise<Misskey.entities.DriveFile[]> {
return new Promise(resolve => {
const { dispose } = popup(defineAsyncComponent(() => import('@/components/MkDriveSelectDialog.vue')), {
type: 'file',
const { dispose } = popup(defineAsyncComponent(() => import('@/components/MkDriveFileSelectDialog.vue')), {
multiple,
}, {
done: files => {
@ -608,11 +607,10 @@ export async function selectDriveFile(multiple: boolean): Promise<Misskey.entiti
});
}
export async function selectDriveFolder(multiple: boolean): Promise<Misskey.entities.DriveFolder[]> {
export async function selectDriveFolder(initialFolder: Misskey.entities.DriveFolder['id'] | null): Promise<Misskey.entities.DriveFolder[]> {
return new Promise(resolve => {
const { dispose } = popup(defineAsyncComponent(() => import('@/components/MkDriveSelectDialog.vue')), {
type: 'folder',
multiple,
const { dispose } = popup(defineAsyncComponent(() => import('@/components/MkDriveFolderSelectDialog.vue')), {
initialFolder,
}, {
done: folders => {
if (folders) {

View File

@ -139,7 +139,7 @@ function crop() {
function move() {
if (!file.value) return;
os.selectDriveFolder(false).then(folder => {
os.selectDriveFolder().then(folder => {
misskeyApi('drive/files/update', {
fileId: file.value.id,
folderId: folder[0] ? folder[0].id : null,

View File

@ -138,7 +138,7 @@ if (prefer.s.uploadFolder) {
}
function chooseUploadFolder() {
os.selectDriveFolder(false).then(async folder => {
os.selectDriveFolder().then(async folder => {
prefer.commit('uploadFolder', folder[0] ? folder[0].id : null);
os.success();
if (prefer.s.uploadFolder) {

View File

@ -42,7 +42,7 @@ function describe(file: Misskey.entities.DriveFile) {
}
function move(file: Misskey.entities.DriveFile) {
os.selectDriveFolder(false).then(folder => {
os.selectDriveFolder().then(folder => {
misskeyApi('drive/files/update', {
fileId: file.id,
folderId: folder[0] ? folder[0].id : null,

View File

@ -93,7 +93,7 @@ const fetch = () => {
};
const choose = () => {
os.selectDriveFolder(false).then(folder => {
os.selectDriveFolder().then(folder => {
if (folder[0] == null) {
return;
}