Compare commits

...

8 Commits

Author SHA1 Message Date
syuilo bff910c620 Update MkDrive.vue 2025-05-14 19:38:12 +09:00
syuilo 3902fe89aa Update MkDrive.vue 2025-05-14 19:31:43 +09:00
syuilo 4f57fd3e14 wip 2025-05-14 15:52:12 +09:00
syuilo 36725b3e8c Update MkUploaderDialog.vue 2025-05-14 15:40:49 +09:00
syuilo 0f789a519f wip 2025-05-14 15:28:38 +09:00
syuilo 0c2c5688db wip 2025-05-14 13:11:06 +09:00
syuilo 291659f462 Update MkUploaderDialog.vue 2025-05-14 13:04:22 +09:00
syuilo 2d8779402a wip 2025-05-14 12:40:10 +09:00
17 changed files with 287 additions and 149 deletions

8
locales/index.d.ts vendored
View File

@ -8535,10 +8535,6 @@ export interface Locale extends ILocale {
* *
*/ */
"inputBorder": string; "inputBorder": string;
/**
*
*/
"driveFolderBg": string;
/** /**
* *
*/ */
@ -11903,6 +11899,10 @@ export interface Locale extends ILocale {
* *
*/ */
"doneConfirm": string; "doneConfirm": string;
/**
* {x}
*/
"maxFileSizeIsX": ParameterizedString<"x">;
}; };
"_clientPerformanceIssueTip": { "_clientPerformanceIssueTip": {
/** /**

View File

@ -2237,7 +2237,6 @@ _theme:
buttonBg: "ボタンの背景" buttonBg: "ボタンの背景"
buttonHoverBg: "ボタンの背景 (ホバー)" buttonHoverBg: "ボタンの背景 (ホバー)"
inputBorder: "入力ボックスの縁取り" inputBorder: "入力ボックスの縁取り"
driveFolderBg: "ドライブフォルダーの背景"
badge: "バッジ" badge: "バッジ"
messageBg: "チャットの背景" messageBg: "チャットの背景"
fgHighlighted: "強調された文字" fgHighlighted: "強調された文字"
@ -3184,6 +3183,7 @@ _uploader:
savedXPercent: "{x}%節約" savedXPercent: "{x}%節約"
abortConfirm: "アップロードされていないファイルがありますが、中止しますか?" abortConfirm: "アップロードされていないファイルがありますが、中止しますか?"
doneConfirm: "アップロードされていないファイルがありますが、完了しますか?" doneConfirm: "アップロードされていないファイルがありますが、完了しますか?"
maxFileSizeIsX: "アップロード可能な最大ファイルサイズは{x}です。"
_clientPerformanceIssueTip: _clientPerformanceIssueTip:
title: "バッテリー消費が多いと感じたら" title: "バッテリー消費が多いと感じたら"

View File

@ -61,7 +61,6 @@
switchOnFg: '@accent', switchOnFg: '@accent',
inputBorder: 'rgba(255, 255, 255, 0.1)', inputBorder: 'rgba(255, 255, 255, 0.1)',
inputBorderHover: 'rgba(255, 255, 255, 0.2)', inputBorderHover: 'rgba(255, 255, 255, 0.2)',
driveFolderBg: ':alpha<0.3<@accent',
badge: '#31b1ce', badge: '#31b1ce',
messageBg: '@bg', messageBg: '@bg',
success: '#86b300', success: '#86b300',

View File

@ -61,7 +61,6 @@
switchOnFg: '@fgOnAccent', switchOnFg: '@fgOnAccent',
inputBorder: 'rgba(0, 0, 0, 0.1)', inputBorder: 'rgba(0, 0, 0, 0.1)',
inputBorderHover: 'rgba(0, 0, 0, 0.2)', inputBorderHover: 'rgba(0, 0, 0, 0.2)',
driveFolderBg: ':alpha<0.3<@accent',
badge: '#31b1ce', badge: '#31b1ce',
messageBg: '@bg', messageBg: '@bg',
success: '#86b300', success: '#86b300',

View File

@ -38,7 +38,6 @@
navIndicator: '@accent', navIndicator: '@accent',
buttonGradateA: '@accent', buttonGradateA: '@accent',
buttonGradateB: ':hue<-20<@accent', buttonGradateB: ':hue<-20<@accent',
driveFolderBg: ':alpha<0.3<@accent',
fgHighlighted: ':lighten<3<@fg', fgHighlighted: ':lighten<3<@fg',
panelHeaderBg: ':lighten<3<@panel', panelHeaderBg: ':lighten<3<@panel',
panelHeaderFg: '@fg', panelHeaderFg: '@fg',

View File

@ -47,7 +47,6 @@
inputBorder: 'rgba(255, 255, 255, 0.1)', inputBorder: 'rgba(255, 255, 255, 0.1)',
panelBorder: '" solid 1px var(--MI_THEME-divider)', panelBorder: '" solid 1px var(--MI_THEME-divider)',
navIndicator: '@indicator', navIndicator: '@indicator',
driveFolderBg: ':alpha<0.3<@accent',
fgHighlighted: ':lighten<3<@fg', fgHighlighted: ':lighten<3<@fg',
panelHeaderBg: ':lighten<3<@panel', panelHeaderBg: ':lighten<3<@panel',
panelHeaderFg: '@fg', panelHeaderFg: '@fg',

View File

@ -49,7 +49,6 @@
panelBorder: '" solid 1px var(--MI_THEME-divider)', panelBorder: '" solid 1px var(--MI_THEME-divider)',
navIndicator: '@indicator', navIndicator: '@indicator',
buttonHoverBg: '#0000001a', buttonHoverBg: '#0000001a',
driveFolderBg: ':alpha<0.3<@accent',
fgHighlighted: ':lighten<3<@fg', fgHighlighted: ':lighten<3<@fg',
panelHeaderBg: ':lighten<3<@panel', panelHeaderBg: ':lighten<3<@panel',
panelHeaderFg: '@fg', panelHeaderFg: '@fg',

View File

@ -39,7 +39,6 @@
inputBorderHover: 'rgba(0, 0, 0, 0.2)', inputBorderHover: 'rgba(0, 0, 0, 0.2)',
panelBorder: '" solid 1px var(--MI_THEME-divider)', panelBorder: '" solid 1px var(--MI_THEME-divider)',
navIndicator: '@accent', navIndicator: '@accent',
driveFolderBg: ':alpha<0.3<@accent',
fgHighlighted: ':darken<3<@fg', fgHighlighted: ':darken<3<@fg',
fgOnWhite: '@accent', fgOnWhite: '@accent',
panelHeaderBg: ':lighten<3<@panel', panelHeaderBg: ':lighten<3<@panel',

View File

@ -8,7 +8,6 @@ SPDX-License-Identifier: AGPL-3.0-only
:class="[$style.root, { [$style.isSelected]: isSelected }]" :class="[$style.root, { [$style.isSelected]: isSelected }]"
draggable="true" draggable="true"
:title="title" :title="title"
@click="onClick"
@contextmenu.stop="onContextmenu" @contextmenu.stop="onContextmenu"
@dragstart="onDragstart" @dragstart="onDragstart"
@dragend="onDragend" @dragend="onDragend"
@ -46,24 +45,17 @@ import * as os from '@/os.js';
import { i18n } from '@/i18n.js'; import { i18n } from '@/i18n.js';
import { $i } from '@/i.js'; import { $i } from '@/i.js';
import { getDriveFileMenu } from '@/utility/get-drive-file-menu.js'; import { getDriveFileMenu } from '@/utility/get-drive-file-menu.js';
import { deviceKind } from '@/utility/device-kind.js';
import { useRouter } from '@/router.js';
import { setDragData } from '@/drag-and-drop.js'; import { setDragData } from '@/drag-and-drop.js';
const router = useRouter();
const props = withDefaults(defineProps<{ const props = withDefaults(defineProps<{
file: Misskey.entities.DriveFile; file: Misskey.entities.DriveFile;
folder: Misskey.entities.DriveFolder | null; folder: Misskey.entities.DriveFolder | null;
isSelected?: boolean; isSelected?: boolean;
selectMode?: boolean;
}>(), { }>(), {
isSelected: false, isSelected: false,
selectMode: false,
}); });
const emit = defineEmits<{ const emit = defineEmits<{
(ev: 'chosen', r: Misskey.entities.DriveFile): void;
(ev: 'dragstart', dragEvent: DragEvent): void; (ev: 'dragstart', dragEvent: DragEvent): void;
(ev: 'dragend'): void; (ev: 'dragend'): void;
}>(); }>();
@ -72,18 +64,6 @@ const isDragging = ref(false);
const title = computed(() => `${props.file.name}\n${props.file.type} ${bytes(props.file.size)}`); const title = computed(() => `${props.file.name}\n${props.file.type} ${bytes(props.file.size)}`);
function onClick(ev: MouseEvent) {
if (props.selectMode) {
emit('chosen', props.file);
} else {
if (deviceKind === 'desktop') {
router.push(`/my/drive/file/${props.file.id}`);
} else {
os.popupMenu(getDriveFileMenu(props.file, props.folder), (ev.currentTarget ?? ev.target ?? undefined) as HTMLElement | undefined);
}
}
}
function onContextmenu(ev: MouseEvent) { function onContextmenu(ev: MouseEvent) {
os.contextMenu(getDriveFileMenu(props.file, props.folder), ev); os.contextMenu(getDriveFileMenu(props.file, props.folder), ev);
} }

View File

@ -19,7 +19,7 @@ SPDX-License-Identifier: AGPL-3.0-only
@dragend="onDragend" @dragend="onDragend"
> >
<svg :class="[$style.shape]" viewBox="0 0 200 150" preserveAspectRatio="none"> <svg :class="[$style.shape]" viewBox="0 0 200 150" preserveAspectRatio="none">
<path d="M190,25C195.523,25 200,29.477 200,35C200,58.415 200,116.585 200,140C200,145.523 195.523,150 190,150C155.86,150 44.14,150 10,150C4.477,150 0,145.523 0,140C0,112.727 0,37.273 0,10C0,4.477 4.477,0 10,-0C26.642,0 59.332,0 70.858,0C73.51,-0 76.054,1.054 77.929,2.929C82.74,7.74 92.26,17.26 97.071,22.071C98.946,23.946 101.49,25 104.142,25C118.808,25 168.535,25 190,25Z" style="fill:var(--MI_THEME-driveFolderBg);"/> <path d="M190,25C195.523,25 200,29.477 200,35C200,58.415 200,116.585 200,140C200,145.523 195.523,150 190,150C155.86,150 44.14,150 10,150C4.477,150 0,145.523 0,140C0,112.727 0,37.273 0,10C0,4.477 4.477,0 10,-0C26.642,0 59.332,0 70.858,0C73.51,-0 76.054,1.054 77.929,2.929C82.74,7.74 92.26,17.26 97.071,22.071C98.946,23.946 101.49,25 104.142,25C118.808,25 168.535,25 190,25Z" style="fill:var(--MI_THEME-accentedBg);"/>
</svg> </svg>
<div :class="$style.name">{{ folder.name }}</div> <div :class="$style.name">{{ folder.name }}</div>
<div v-if="prefer.s.uploadFolder == folder.id" :class="$style.upload"> <div v-if="prefer.s.uploadFolder == folder.id" :class="$style.upload">

View File

@ -60,8 +60,10 @@ SPDX-License-Identifier: AGPL-3.0-only
@drop.prevent.stop="onDrop" @drop.prevent.stop="onDrop"
@contextmenu.stop="onContextmenu" @contextmenu.stop="onContextmenu"
> >
<MkInfo v-if="!store.r.readDriveTip.value" closable @close="closeTip()"><div v-html="i18n.ts.driveAboutTip"></div></MkInfo> <div v-if="!store.r.readDriveTip.value" style="padding: 8px;">
<div v-show="foldersPaginator.items.value.length > 0"> <MkInfo closable @close="closeTip()"><div v-html="i18n.ts.driveAboutTip"></div></MkInfo>
</div>
<div :class="$style.folders"> <div :class="$style.folders">
<XFolder <XFolder
v-for="(f, i) in foldersPaginator.items.value" v-for="(f, i) in foldersPaginator.items.value"
@ -80,9 +82,7 @@ SPDX-License-Identifier: AGPL-3.0-only
/> />
</div> </div>
<MkButton v-if="foldersPaginator.canFetchOlder.value" primary rounded @click="foldersPaginator.fetchOlder()">{{ i18n.ts.loadMore }}</MkButton> <MkButton v-if="foldersPaginator.canFetchOlder.value" primary rounded @click="foldersPaginator.fetchOlder()">{{ i18n.ts.loadMore }}</MkButton>
</div>
<div v-show="filesPaginator.items.value.length > 0">
<MkStickyContainer v-for="(item, i) in filesTimeline" :key="`${item.date.getFullYear()}/${item.date.getMonth() + 1}`"> <MkStickyContainer v-for="(item, i) in filesTimeline" :key="`${item.date.getFullYear()}/${item.date.getMonth() + 1}`">
<template #header> <template #header>
<div :class="$style.date"> <div :class="$style.date">
@ -104,16 +104,14 @@ SPDX-License-Identifier: AGPL-3.0-only
:class="$style.file" :class="$style.file"
:file="file" :file="file"
:folder="folder" :folder="folder"
:selectMode="select === 'file' || isEditMode"
:isSelected="selectedFiles.some(x => x.id === file.id)" :isSelected="selectedFiles.some(x => x.id === file.id)"
@chosen="onChooseFile" @click="onFileClick($event, file)"
@dragstart="onFileDragstart(file, $event)" @dragstart="onFileDragstart(file, $event)"
@dragend="isDragSource = false" @dragend="isDragSource = false"
/> />
</TransitionGroup> </TransitionGroup>
</MkStickyContainer> </MkStickyContainer>
<MkButton v-show="filesPaginator.canFetchOlder.value" :class="$style.loadMore" primary rounded @click="filesPaginator.fetchOlder()">{{ i18n.ts.loadMore }}</MkButton> <MkButton v-show="filesPaginator.canFetchOlder.value" :class="$style.loadMore" primary rounded @click="filesPaginator.fetchOlder()">{{ i18n.ts.loadMore }}</MkButton>
</div>
<div v-if="filesPaginator.items.value.length == 0 && foldersPaginator.items.value.length == 0 && !fetching" :class="$style.empty"> <div v-if="filesPaginator.items.value.length == 0 && foldersPaginator.items.value.length == 0 && !fetching" :class="$style.empty">
<div v-if="draghover">{{ i18n.ts['empty-draghover'] }}</div> <div v-if="draghover">{{ i18n.ts['empty-draghover'] }}</div>
@ -154,6 +152,7 @@ import { isSeparatorNeeded, getSeparatorInfo, makeDateGroupedTimelineComputedRef
import { usePagination } from '@/composables/use-pagination.js'; import { usePagination } from '@/composables/use-pagination.js';
import { globalEvents, useGlobalEvent } from '@/events.js'; import { globalEvents, useGlobalEvent } from '@/events.js';
import { checkDragDataType, getDragData, setDragData } from '@/drag-and-drop.js'; import { checkDragDataType, getDragData, setDragData } from '@/drag-and-drop.js';
import { getDriveFileMenu } from '@/utility/get-drive-file-menu.js';
const props = withDefaults(defineProps<{ const props = withDefaults(defineProps<{
initialFolder?: Misskey.entities.DriveFolder['id'] | null; initialFolder?: Misskey.entities.DriveFolder['id'] | null;
@ -458,7 +457,12 @@ function deleteFolder(folderToDelete: Misskey.entities.DriveFolder) {
}); });
} }
function onChooseFile(file: Misskey.entities.DriveFile) { function onFileClick(ev: MouseEvent, file: Misskey.entities.DriveFile) {
if (ev.shiftKey) {
isEditMode.value = true;
}
if (props.select === 'file' || isEditMode.value) {
const isAlreadySelected = selectedFiles.value.some(f => f.id === file.id); const isAlreadySelected = selectedFiles.value.some(f => f.id === file.id);
if (isEditMode.value) { if (isEditMode.value) {
@ -483,6 +487,9 @@ function onChooseFile(file: Misskey.entities.DriveFile) {
selectedFiles.value = [file]; selectedFiles.value = [file];
} }
} }
} else {
os.popupMenu(getDriveFileMenu(file, folder.value), (ev.currentTarget ?? ev.target ?? undefined) as HTMLElement | undefined);
}
} }
function chooseFolder(folderToChoose: Misskey.entities.DriveFolder) { function chooseFolder(folderToChoose: Misskey.entities.DriveFolder) {
@ -816,7 +823,14 @@ onBeforeUnmount(() => {
display: grid; display: grid;
grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
grid-gap: 12px; grid-gap: 12px;
padding: var(--MI-margin); padding: 16px 32px;
}
@container (max-width: 600px) {
.folders,
.files {
padding: 16px;
}
} }
.date { .date {

View File

@ -15,7 +15,10 @@ SPDX-License-Identifier: AGPL-3.0-only
<i class="ti ti-upload"></i> {{ i18n.tsx.uploadNFiles({ n: files.length }) }} <i class="ti ti-upload"></i> {{ i18n.tsx.uploadNFiles({ n: files.length }) }}
</template> </template>
<div :class="$style.root" class="_gaps_s"> <div :class="$style.root">
<div :class="[$style.overallProgress, canRetry ? $style.overallProgressError : null]" :style="{ '--op': `${overallProgress}%` }"></div>
<div :class="$style.main" class="_gaps_s">
<div :class="$style.items" class="_gaps_s"> <div :class="$style.items" class="_gaps_s">
<div <div
v-for="ctx in items" v-for="ctx in items"
@ -25,12 +28,12 @@ SPDX-License-Identifier: AGPL-3.0-only
:style="{ '--p': ctx.progress != null ? `${ctx.progress.value / ctx.progress.max * 100}%` : '0%' }" :style="{ '--p': ctx.progress != null ? `${ctx.progress.value / ctx.progress.max * 100}%` : '0%' }"
> >
<div :class="$style.itemInner"> <div :class="$style.itemInner">
<div> <div :class="$style.itemActionWrapper">
<MkButton :iconOnly="true" rounded @click="showMenu($event, ctx)"><i class="ti ti-dots"></i></MkButton> <MkButton :iconOnly="true" rounded @click="showMenu($event, ctx)"><i class="ti ti-dots"></i></MkButton>
</div> </div>
<div :class="$style.itemThumbnail" :style="{ backgroundImage: `url(${ ctx.thumbnail })` }"></div> <div :class="$style.itemThumbnail" :style="{ backgroundImage: `url(${ ctx.thumbnail })` }"></div>
<div :class="$style.itemBody"> <div :class="$style.itemBody">
<div>{{ ctx.name }}</div> <div><MkCondensedLine :minScale="2 / 3">{{ ctx.name }}</MkCondensedLine></div>
<div :class="$style.itemInfo"> <div :class="$style.itemInfo">
<span>{{ ctx.file.type }}</span> <span>{{ ctx.file.type }}</span>
<span>{{ bytes(ctx.file.size) }}</span> <span>{{ bytes(ctx.file.size) }}</span>
@ -39,7 +42,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<div> <div>
</div> </div>
</div> </div>
<div> <div :class="$style.itemIconWrapper">
<MkSystemIcon v-if="ctx.uploading" :class="$style.itemIcon" type="waiting"/> <MkSystemIcon v-if="ctx.uploading" :class="$style.itemIcon" type="waiting"/>
<MkSystemIcon v-else-if="ctx.uploaded" :class="$style.itemIcon" type="success"/> <MkSystemIcon v-else-if="ctx.uploaded" :class="$style.itemIcon" type="success"/>
<MkSystemIcon v-else-if="ctx.uploadFailed" :class="$style.itemIcon" type="error"/> <MkSystemIcon v-else-if="ctx.uploadFailed" :class="$style.itemIcon" type="error"/>
@ -60,6 +63,9 @@ SPDX-License-Identifier: AGPL-3.0-only
> >
<template #label>{{ i18n.ts.compress }}</template> <template #label>{{ i18n.ts.compress }}</template>
</MkSelect> </MkSelect>
<div>{{ i18n.tsx._uploader.maxFileSizeIsX({ x: $i.policies.maxFileSizeMb + 'MB' }) }}</div>
</div>
</div> </div>
<template #footer> <template #footer>
@ -91,6 +97,9 @@ import MkSelect from '@/components/MkSelect.vue';
import { isWebpSupported } from '@/utility/isWebpSupported.js'; import { isWebpSupported } from '@/utility/isWebpSupported.js';
import { uploadFile } from '@/utility/drive.js'; import { uploadFile } from '@/utility/drive.js';
import * as os from '@/os.js'; import * as os from '@/os.js';
import { ensureSignin } from '@/i.js';
const $i = ensureSignin();
const COMPRESSION_SUPPORTED_TYPES = [ const COMPRESSION_SUPPORTED_TYPES = [
'image/jpeg', 'image/jpeg',
@ -144,6 +153,16 @@ const firstUploadAttempted = ref(false);
const isUploading = computed(() => items.value.some(item => item.uploading)); const isUploading = computed(() => items.value.some(item => item.uploading));
const canRetry = computed(() => firstUploadAttempted.value && !items.value.some(item => item.uploading || item.waiting) && items.value.some(item => item.uploaded == null)); const canRetry = computed(() => firstUploadAttempted.value && !items.value.some(item => item.uploading || item.waiting) && items.value.some(item => item.uploaded == null));
const canDone = computed(() => items.value.some(item => item.uploaded != null)); const canDone = computed(() => items.value.some(item => item.uploaded != null));
const overallProgress = computed(() => {
const max = items.value.length;
if (max === 0) return 0;
const v = items.value.reduce((acc, item) => {
if (item.uploaded) return acc + 1;
if (item.progress) return acc + (item.progress.value / item.progress.max);
return acc;
}, 0);
return Math.round((v / max) * 100);
});
const compressionLevel = ref<0 | 1 | 2 | 3>(2); const compressionLevel = ref<0 | 1 | 2 | 3>(2);
const compressionSettings = computed(() => { const compressionSettings = computed(() => {
@ -319,6 +338,25 @@ onMounted(() => {
<style lang="scss" module> <style lang="scss" module>
.root { .root {
position: relative;
}
.overallProgress {
position: absolute;
top: 0;
left: 0;
width: var(--op);
height: 4px;
background: var(--MI_THEME-accent);
border-radius: 0 999px 999px 0;
transition: width 0.2s ease;
&.overallProgressError {
background: var(--MI_THEME-warn);
}
}
.main {
padding: 12px; padding: 12px;
} }
@ -406,12 +444,6 @@ onMounted(() => {
min-width: 0; min-width: 0;
} }
@container (max-width: 500px) {
.itemBody {
font-size: 90%;
}
}
.itemInfo { .itemInfo {
opacity: 0.7; opacity: 0.7;
margin-top: 4px; margin-top: 4px;
@ -423,4 +455,34 @@ onMounted(() => {
.itemIcon { .itemIcon {
width: 35px; width: 35px;
} }
@container (max-width: 500px) {
.itemInner {
flex-direction: column;
gap: 8px;
}
.itemBody {
font-size: 90%;
text-align: center;
width: 100%;
min-width: 0;
}
.itemActionWrapper {
position: absolute;
top: 8px;
left: 8px;
}
.itemInfo {
justify-content: center;
}
.itemIconWrapper {
position: absolute;
top: 8px;
right: 8px;
}
}
</style> </style>

View File

@ -1247,6 +1247,12 @@ type DriveFilesFindRequest = operations['drive___files___find']['requestBody']['
// @public (undocumented) // @public (undocumented)
type DriveFilesFindResponse = operations['drive___files___find']['responses']['200']['content']['application/json']; type DriveFilesFindResponse = operations['drive___files___find']['responses']['200']['content']['application/json'];
// @public (undocumented)
type DriveFilesMoveBulkRequest = operations['drive___files___move-bulk']['requestBody']['content']['application/json'];
// @public (undocumented)
type DriveFilesMoveBulkResponse = operations['drive___files___move-bulk']['responses']['200']['content']['application/json'];
// @public (undocumented) // @public (undocumented)
type DriveFilesRequest = operations['drive___files']['requestBody']['content']['application/json']; type DriveFilesRequest = operations['drive___files']['requestBody']['content']['application/json'];
@ -1732,6 +1738,8 @@ declare namespace entities {
DriveFilesFindResponse, DriveFilesFindResponse,
DriveFilesFindByHashRequest, DriveFilesFindByHashRequest,
DriveFilesFindByHashResponse, DriveFilesFindByHashResponse,
DriveFilesMoveBulkRequest,
DriveFilesMoveBulkResponse,
DriveFilesShowRequest, DriveFilesShowRequest,
DriveFilesShowResponse, DriveFilesShowResponse,
DriveFilesUpdateRequest, DriveFilesUpdateRequest,

View File

@ -2073,6 +2073,17 @@ declare module '../api.js' {
credential?: string | null, credential?: string | null,
): Promise<SwitchCaseResponseType<E, P>>; ): Promise<SwitchCaseResponseType<E, P>>;
/**
* No description provided.
*
* **Credential required**: *Yes* / **Permission**: *write:drive*
*/
request<E extends 'drive/files/move-bulk', P extends Endpoints[E]['req']>(
endpoint: E,
params: P,
credential?: string | null,
): Promise<SwitchCaseResponseType<E, P>>;
/** /**
* Show the properties of a drive file. * Show the properties of a drive file.
* *

View File

@ -282,6 +282,8 @@ import type {
DriveFilesFindResponse, DriveFilesFindResponse,
DriveFilesFindByHashRequest, DriveFilesFindByHashRequest,
DriveFilesFindByHashResponse, DriveFilesFindByHashResponse,
DriveFilesMoveBulkRequest,
DriveFilesMoveBulkResponse,
DriveFilesShowRequest, DriveFilesShowRequest,
DriveFilesShowResponse, DriveFilesShowResponse,
DriveFilesUpdateRequest, DriveFilesUpdateRequest,
@ -823,6 +825,7 @@ export type Endpoints = {
'drive/files/delete': { req: DriveFilesDeleteRequest; res: EmptyResponse }; 'drive/files/delete': { req: DriveFilesDeleteRequest; res: EmptyResponse };
'drive/files/find': { req: DriveFilesFindRequest; res: DriveFilesFindResponse }; 'drive/files/find': { req: DriveFilesFindRequest; res: DriveFilesFindResponse };
'drive/files/find-by-hash': { req: DriveFilesFindByHashRequest; res: DriveFilesFindByHashResponse }; 'drive/files/find-by-hash': { req: DriveFilesFindByHashRequest; res: DriveFilesFindByHashResponse };
'drive/files/move-bulk': { req: DriveFilesMoveBulkRequest; res: DriveFilesMoveBulkResponse };
'drive/files/show': { req: DriveFilesShowRequest; res: DriveFilesShowResponse }; 'drive/files/show': { req: DriveFilesShowRequest; res: DriveFilesShowResponse };
'drive/files/update': { req: DriveFilesUpdateRequest; res: DriveFilesUpdateResponse }; 'drive/files/update': { req: DriveFilesUpdateRequest; res: DriveFilesUpdateResponse };
'drive/files/upload-from-url': { req: DriveFilesUploadFromUrlRequest; res: EmptyResponse }; 'drive/files/upload-from-url': { req: DriveFilesUploadFromUrlRequest; res: EmptyResponse };

View File

@ -285,6 +285,8 @@ export type DriveFilesFindRequest = operations['drive___files___find']['requestB
export type DriveFilesFindResponse = operations['drive___files___find']['responses']['200']['content']['application/json']; export type DriveFilesFindResponse = operations['drive___files___find']['responses']['200']['content']['application/json'];
export type DriveFilesFindByHashRequest = operations['drive___files___find-by-hash']['requestBody']['content']['application/json']; export type DriveFilesFindByHashRequest = operations['drive___files___find-by-hash']['requestBody']['content']['application/json'];
export type DriveFilesFindByHashResponse = operations['drive___files___find-by-hash']['responses']['200']['content']['application/json']; export type DriveFilesFindByHashResponse = operations['drive___files___find-by-hash']['responses']['200']['content']['application/json'];
export type DriveFilesMoveBulkRequest = operations['drive___files___move-bulk']['requestBody']['content']['application/json'];
export type DriveFilesMoveBulkResponse = operations['drive___files___move-bulk']['responses']['200']['content']['application/json'];
export type DriveFilesShowRequest = operations['drive___files___show']['requestBody']['content']['application/json']; export type DriveFilesShowRequest = operations['drive___files___show']['requestBody']['content']['application/json'];
export type DriveFilesShowResponse = operations['drive___files___show']['responses']['200']['content']['application/json']; export type DriveFilesShowResponse = operations['drive___files___show']['responses']['200']['content']['application/json'];
export type DriveFilesUpdateRequest = operations['drive___files___update']['requestBody']['content']['application/json']; export type DriveFilesUpdateRequest = operations['drive___files___update']['requestBody']['content']['application/json'];

View File

@ -1799,6 +1799,15 @@ export type paths = {
*/ */
post: operations['drive___files___find-by-hash']; post: operations['drive___files___find-by-hash'];
}; };
'/drive/files/move-bulk': {
/**
* drive/files/move-bulk
* @description No description provided.
*
* **Credential required**: *Yes* / **Permission**: *write:drive*
*/
post: operations['drive___files___move-bulk'];
};
'/drive/files/show': { '/drive/files/show': {
/** /**
* drive/files/show * drive/files/show
@ -16845,6 +16854,61 @@ export type operations = {
}; };
}; };
}; };
/**
* drive/files/move-bulk
* @description No description provided.
*
* **Credential required**: *Yes* / **Permission**: *write:drive*
*/
'drive___files___move-bulk': {
requestBody: {
content: {
'application/json': {
fileIds: string[];
/** Format: misskey:id */
folderId?: string | null;
};
};
};
responses: {
/** @description OK (with results) */
200: {
content: {
'application/json': unknown;
};
};
/** @description Client error */
400: {
content: {
'application/json': components['schemas']['Error'];
};
};
/** @description Authentication error */
401: {
content: {
'application/json': components['schemas']['Error'];
};
};
/** @description Forbidden error */
403: {
content: {
'application/json': components['schemas']['Error'];
};
};
/** @description I'm Ai */
418: {
content: {
'application/json': components['schemas']['Error'];
};
};
/** @description Internal server error */
500: {
content: {
'application/json': components['schemas']['Error'];
};
};
};
};
/** /**
* drive/files/show * drive/files/show
* @description Show the properties of a drive file. * @description Show the properties of a drive file.