enhance(frontend): ファイルアップロード処理のリファクタと設定の簡略化

This commit is contained in:
syuilo 2025-03-28 09:47:34 +09:00
parent 61e09d483e
commit a25fa62d64
11 changed files with 57 additions and 90 deletions

4
locales/index.d.ts vendored
View File

@ -5358,6 +5358,10 @@ export interface Locale extends ILocale {
* *
*/ */
"migrateOldSettings_description": string; "migrateOldSettings_description": string;
/**
*
*/
"compress": string;
"_chat": { "_chat": {
/** /**
* *

View File

@ -1335,6 +1335,7 @@ information: "情報"
chat: "チャット" chat: "チャット"
migrateOldSettings: "旧設定情報を移行" migrateOldSettings: "旧設定情報を移行"
migrateOldSettings_description: "通常これは自動で行われていますが、何らかの理由により上手く移行されなかった場合は手動で移行処理をトリガーできます。現在の設定情報は上書きされます。" migrateOldSettings_description: "通常これは自動で行われていますが、何らかの理由により上手く移行されなかった場合は手動で移行処理をトリガーできます。現在の設定情報は上書きされます。"
compress: "圧縮"
_chat: _chat:
noMessagesYet: "まだメッセージはありません" noMessagesYet: "まだメッセージはありません"

View File

@ -4,7 +4,8 @@ SPDX-License-Identifier: AGPL-3.0-only
--> -->
<template> <template>
<div :class="$style.root"> <MkStickyContainer>
<template #header>
<nav :class="$style.nav"> <nav :class="$style.nav">
<div :class="$style.navPath" @contextmenu.prevent.stop="() => {}"> <div :class="$style.navPath" @contextmenu.prevent.stop="() => {}">
<XNavFolder <XNavFolder
@ -32,6 +33,8 @@ SPDX-License-Identifier: AGPL-3.0-only
</div> </div>
<button class="_button" :class="$style.navMenu" @click="showMenu"><i class="ti ti-dots"></i></button> <button class="_button" :class="$style.navMenu" @click="showMenu"><i class="ti ti-dots"></i></button>
</nav> </nav>
</template>
<div <div
ref="main" ref="main"
:class="[$style.main, { [$style.uploading]: uploadings.length > 0, [$style.fetching]: fetching }]" :class="[$style.main, { [$style.uploading]: uploadings.length > 0, [$style.fetching]: fetching }]"
@ -91,8 +94,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<MkLoading v-if="fetching"/> <MkLoading v-if="fetching"/>
</div> </div>
<div v-if="draghover" :class="$style.dropzone"></div> <div v-if="draghover" :class="$style.dropzone"></div>
<input ref="fileInput" style="display: none;" type="file" accept="*/*" multiple tabindex="-1" @change="onChangeFileInput"/> </MkStickyContainer>
</div>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
@ -110,6 +112,7 @@ import { i18n } from '@/i18n.js';
import { uploadFile, uploads } from '@/utility/upload.js'; import { uploadFile, uploads } from '@/utility/upload.js';
import { claimAchievement } from '@/utility/achievements.js'; import { claimAchievement } from '@/utility/achievements.js';
import { prefer } from '@/preferences.js'; import { prefer } from '@/preferences.js';
import { chooseFileFromPc } from '@/utility/select-file.js';
const props = withDefaults(defineProps<{ const props = withDefaults(defineProps<{
initialFolder?: Misskey.entities.DriveFolder; initialFolder?: Misskey.entities.DriveFolder;
@ -130,7 +133,6 @@ const emit = defineEmits<{
}>(); }>();
const loadMoreFiles = useTemplateRef('loadMoreFiles'); const loadMoreFiles = useTemplateRef('loadMoreFiles');
const fileInput = useTemplateRef('fileInput');
const folder = ref<Misskey.entities.DriveFolder | null>(null); const folder = ref<Misskey.entities.DriveFolder | null>(null);
const files = ref<Misskey.entities.DriveFile[]>([]); const files = ref<Misskey.entities.DriveFile[]>([]);
@ -142,7 +144,6 @@ const selectedFiles = ref<Misskey.entities.DriveFile[]>([]);
const selectedFolders = ref<Misskey.entities.DriveFolder[]>([]); const selectedFolders = ref<Misskey.entities.DriveFolder[]>([]);
const uploadings = uploads; const uploadings = uploads;
const connection = useStream().useChannel('drive'); const connection = useStream().useChannel('drive');
const keepOriginal = ref<boolean>(prefer.s.keepOriginalUploading); // $ref使
// //
const draghover = ref(false); const draghover = ref(false);
@ -304,10 +305,6 @@ function onDrop(ev: DragEvent) {
//#endregion //#endregion
} }
function selectLocalFile() {
fileInput.value?.click();
}
function urlUpload() { function urlUpload() {
os.inputText({ os.inputText({
title: i18n.ts.uploadFromUrl, title: i18n.ts.uploadFromUrl,
@ -383,15 +380,8 @@ function deleteFolder(folderToDelete: Misskey.entities.DriveFolder) {
}); });
} }
function onChangeFileInput() { function upload(file: File, folderToUpload?: Misskey.entities.DriveFolder | null, keepOriginal?: boolean) {
if (!fileInput.value?.files) return; uploadFile(file, (folderToUpload && typeof folderToUpload === 'object') ? folderToUpload.id : null, undefined, keepOriginal).then(res => {
for (const file of Array.from(fileInput.value.files)) {
upload(file, folder.value);
}
}
function upload(file: File, folderToUpload?: Misskey.entities.DriveFolder | null) {
uploadFile(file, (folderToUpload && typeof folderToUpload === 'object') ? folderToUpload.id : null, undefined, keepOriginal.value).then(res => {
addFile(res, true); addFile(res, true);
}); });
} }
@ -630,16 +620,20 @@ function getMenu() {
const menu: MenuItem[] = []; const menu: MenuItem[] = [];
menu.push({ menu.push({
type: 'switch',
text: i18n.ts.keepOriginalUploading,
ref: keepOriginal,
}, { type: 'divider' }, {
text: i18n.ts.addFile, text: i18n.ts.addFile,
type: 'label', type: 'label',
}, {
text: i18n.ts.upload + ' (' + i18n.ts.compress + ')',
icon: 'ti ti-upload',
action: () => {
chooseFileFromPc(true, { keepOriginal: false });
},
}, { }, {
text: i18n.ts.upload, text: i18n.ts.upload,
icon: 'ti ti-upload', icon: 'ti ti-upload',
action: () => { selectLocalFile(); }, action: () => {
chooseFileFromPc(true, { keepOriginal: true });
},
}, { }, {
text: i18n.ts.fromUrl, text: i18n.ts.fromUrl,
icon: 'ti ti-link', icon: 'ti ti-link',
@ -751,22 +745,17 @@ onBeforeUnmount(() => {
</script> </script>
<style lang="scss" module> <style lang="scss" module>
.root {
display: flex;
flex-direction: column;
height: 100%;
}
.nav { .nav {
display: flex; display: flex;
z-index: 2;
width: 100%; width: 100%;
padding: 0 8px; padding: 0 8px;
box-sizing: border-box; box-sizing: border-box;
overflow: auto; overflow: auto;
font-size: 0.9em; font-size: 0.9em;
box-shadow: 0 1px 0 var(--MI_THEME-divider); background: color(from var(--MI_THEME-bg) srgb r g b / 0.75);
user-select: none; -webkit-backdrop-filter: var(--MI-blur, blur(15px));
backdrop-filter: var(--MI-blur, blur(15px));
border-bottom: solid 0.5px var(--MI_THEME-divider);
} }
.navPath { .navPath {

View File

@ -18,11 +18,6 @@ SPDX-License-Identifier: AGPL-3.0-only
</option> </option>
</MkSelect> </MkSelect>
<MkSwitch v-model="keepOriginalUploading">
<template #label>{{ i18n.ts.keepOriginalUploading }}</template>
<template #caption>{{ i18n.ts.keepOriginalUploadingDescription }}</template>
</MkSwitch>
<MkSwitch v-model="directoryToCategory"> <MkSwitch v-model="directoryToCategory">
<template #label>{{ i18n.ts._customEmojisManager._local._register.directoryToCategoryLabel }}</template> <template #label>{{ i18n.ts._customEmojisManager._local._register.directoryToCategoryLabel }}</template>
<template #caption>{{ i18n.ts._customEmojisManager._local._register.directoryToCategoryCaption }}</template> <template #caption>{{ i18n.ts._customEmojisManager._local._register.directoryToCategoryCaption }}</template>
@ -245,7 +240,6 @@ function setupGrid(): GridSetting {
const uploadFolders = ref<FolderItem[]>([]); const uploadFolders = ref<FolderItem[]>([]);
const gridItems = ref<GridItem[]>([]); const gridItems = ref<GridItem[]>([]);
const selectedFolderId = ref(prefer.s.uploadFolder); const selectedFolderId = ref(prefer.s.uploadFolder);
const keepOriginalUploading = ref(prefer.s.keepOriginalUploading);
const directoryToCategory = ref<boolean>(false); const directoryToCategory = ref<boolean>(false);
const registerButtonDisabled = ref<boolean>(false); const registerButtonDisabled = ref<boolean>(false);
const requestLogs = ref<RequestLogItem[]>([]); const requestLogs = ref<RequestLogItem[]>([]);
@ -338,7 +332,7 @@ async function onDrop(ev: DragEvent) {
it.file, it.file,
selectedFolderId.value, selectedFolderId.value,
it.file.name.replace(/\.[^.]+$/, ''), it.file.name.replace(/\.[^.]+$/, ''),
keepOriginalUploading.value, true,
), ),
}), }),
), ),
@ -373,7 +367,7 @@ async function onFileSelectClicked() {
true, true,
{ {
uploadFolder: selectedFolderId.value, uploadFolder: selectedFolderId.value,
keepOriginal: keepOriginalUploading.value, keepOriginal: true,
// //
nameConverter: (file) => file.name.replace(/\.[a-zA-Z0-9]+$/, ''), nameConverter: (file) => file.name.replace(/\.[a-zA-Z0-9]+$/, ''),
}, },

View File

@ -5,7 +5,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<template> <template>
<div> <div>
<XDrive ref="drive" @cd="x => folder = x"/> <XDrive @cd="x => folder = x"/>
</div> </div>
</template> </template>

View File

@ -53,15 +53,6 @@ SPDX-License-Identifier: AGPL-3.0-only
{{ i18n.ts.drivecleaner }} {{ i18n.ts.drivecleaner }}
</FormLink> </FormLink>
<SearchMarker :keywords="['keep', 'original', 'raw', 'upload']">
<MkPreferenceContainer k="keepOriginalUploading">
<MkSwitch v-model="keepOriginalUploading">
<template #label><SearchLabel>{{ i18n.ts.keepOriginalUploading }}</SearchLabel></template>
<template #caption><SearchKeyword>{{ i18n.ts.keepOriginalUploadingDescription }}</SearchKeyword></template>
</MkSwitch>
</MkPreferenceContainer>
</SearchMarker>
<SearchMarker :keywords="['keep', 'original', 'filename']"> <SearchMarker :keywords="['keep', 'original', 'filename']">
<MkPreferenceContainer k="keepOriginalFilename"> <MkPreferenceContainer k="keepOriginalFilename">
<MkSwitch v-model="keepOriginalFilename"> <MkSwitch v-model="keepOriginalFilename">
@ -130,7 +121,6 @@ const meterStyle = computed(() => {
}; };
}); });
const keepOriginalUploading = prefer.model('keepOriginalUploading');
const keepOriginalFilename = prefer.model('keepOriginalFilename'); const keepOriginalFilename = prefer.model('keepOriginalFilename');
misskeyApi('drive').then(info => { misskeyApi('drive').then(info => {

View File

@ -66,7 +66,6 @@ export function migrateOldSettings() {
prefer.commit('collapseRenotes', store.s.collapseRenotes); prefer.commit('collapseRenotes', store.s.collapseRenotes);
prefer.commit('rememberNoteVisibility', store.s.rememberNoteVisibility); prefer.commit('rememberNoteVisibility', store.s.rememberNoteVisibility);
prefer.commit('uploadFolder', store.s.uploadFolder); prefer.commit('uploadFolder', store.s.uploadFolder);
prefer.commit('keepOriginalUploading', store.s.keepOriginalUploading);
prefer.commit('menu', store.s.menu); prefer.commit('menu', store.s.menu);
prefer.commit('statusbars', store.s.statusbars); prefer.commit('statusbars', store.s.statusbars);
prefer.commit('pinnedUserLists', store.s.pinnedUserLists); prefer.commit('pinnedUserLists', store.s.pinnedUserLists);

View File

@ -118,9 +118,6 @@ export const PREF_DEF = {
keepCw: { keepCw: {
default: true, default: true,
}, },
keepOriginalUploading: {
default: false,
},
rememberNoteVisibility: { rememberNoteVisibility: {
default: false, default: false,
}, },

View File

@ -759,21 +759,16 @@ export const searchIndexes: SearchIndexItem[] = [
}, },
{ {
id: 'goQdtf3dD', id: 'goQdtf3dD',
label: i18n.ts.keepOriginalUploading,
keywords: ['keep', 'original', 'raw', 'upload', i18n.ts.keepOriginalUploadingDescription],
},
{
id: '83xRo0XJl',
label: i18n.ts.keepOriginalFilename, label: i18n.ts.keepOriginalFilename,
keywords: ['keep', 'original', 'filename', i18n.ts.keepOriginalFilenameDescription], keywords: ['keep', 'original', 'filename', i18n.ts.keepOriginalFilenameDescription],
}, },
{ {
id: 'wf77yRQQq', id: '83xRo0XJl',
label: i18n.ts.alwaysMarkSensitive, label: i18n.ts.alwaysMarkSensitive,
keywords: ['always', 'default', 'mark', 'nsfw', 'sensitive', 'media', 'file'], keywords: ['always', 'default', 'mark', 'nsfw', 'sensitive', 'media', 'file'],
}, },
{ {
id: '3pxwNB8e4', id: 'BrBqZL35E',
label: i18n.ts.enableAutoSensitive, label: i18n.ts.enableAutoSensitive,
keywords: ['auto', 'nsfw', 'sensitive', 'media', 'file', i18n.ts.enableAutoSensitiveDescription], keywords: ['auto', 'nsfw', 'sensitive', 'media', 'file', i18n.ts.enableAutoSensitiveDescription],
}, },

View File

@ -21,7 +21,7 @@ export function chooseFileFromPc(
}, },
): Promise<Misskey.entities.DriveFile[]> { ): Promise<Misskey.entities.DriveFile[]> {
const uploadFolder = options?.uploadFolder ?? prefer.s.uploadFolder; const uploadFolder = options?.uploadFolder ?? prefer.s.uploadFolder;
const keepOriginal = options?.keepOriginal ?? prefer.s.keepOriginalUploading; const keepOriginal = options?.keepOriginal ?? false;
const nameConverter = options?.nameConverter ?? (() => undefined); const nameConverter = options?.nameConverter ?? (() => undefined);
return new Promise((res, rej) => { return new Promise((res, rej) => {
@ -96,19 +96,17 @@ export function chooseFileFromUrl(): Promise<Misskey.entities.DriveFile> {
function select(src: HTMLElement | EventTarget | null, label: string | null, multiple: boolean): Promise<Misskey.entities.DriveFile[]> { function select(src: HTMLElement | EventTarget | null, label: string | null, multiple: boolean): Promise<Misskey.entities.DriveFile[]> {
return new Promise((res, rej) => { return new Promise((res, rej) => {
const keepOriginal = ref(prefer.s.keepOriginalUploading);
os.popupMenu([label ? { os.popupMenu([label ? {
text: label, text: label,
type: 'label', type: 'label',
} : undefined, { } : undefined, {
type: 'switch', text: i18n.ts.upload + ' (' + i18n.ts.compress + ')',
text: i18n.ts.keepOriginalUploading, icon: 'ti ti-upload',
ref: keepOriginal, action: () => chooseFileFromPc(multiple, { keepOriginal: false }).then(files => res(files)),
}, { }, {
text: i18n.ts.upload, text: i18n.ts.upload,
icon: 'ti ti-upload', icon: 'ti ti-upload',
action: () => chooseFileFromPc(multiple, { keepOriginal: keepOriginal.value }).then(files => res(files)), action: () => chooseFileFromPc(multiple, { keepOriginal: true }).then(files => res(files)),
}, { }, {
text: i18n.ts.fromDrive, text: i18n.ts.fromDrive,
icon: 'ti ti-cloud', icon: 'ti ti-cloud',

View File

@ -34,7 +34,7 @@ export function uploadFile(
file: File, file: File,
folder?: string | Misskey.entities.DriveFolder | null, folder?: string | Misskey.entities.DriveFolder | null,
name?: string, name?: string,
keepOriginal: boolean = prefer.s.keepOriginalUploading, keepOriginal = false,
): Promise<Misskey.entities.DriveFile> { ): Promise<Misskey.entities.DriveFile> {
if ($i == null) throw new Error('Not logged in'); if ($i == null) throw new Error('Not logged in');