enhance(frontend): ファイルアップロード処理のリファクタと設定の簡略化
This commit is contained in:
parent
61e09d483e
commit
a25fa62d64
|
@ -5358,6 +5358,10 @@ export interface Locale extends ILocale {
|
||||||
* 通常これは自動で行われていますが、何らかの理由により上手く移行されなかった場合は手動で移行処理をトリガーできます。現在の設定情報は上書きされます。
|
* 通常これは自動で行われていますが、何らかの理由により上手く移行されなかった場合は手動で移行処理をトリガーできます。現在の設定情報は上書きされます。
|
||||||
*/
|
*/
|
||||||
"migrateOldSettings_description": string;
|
"migrateOldSettings_description": string;
|
||||||
|
/**
|
||||||
|
* 圧縮
|
||||||
|
*/
|
||||||
|
"compress": string;
|
||||||
"_chat": {
|
"_chat": {
|
||||||
/**
|
/**
|
||||||
* まだメッセージはありません
|
* まだメッセージはありません
|
||||||
|
|
|
@ -1335,6 +1335,7 @@ information: "情報"
|
||||||
chat: "チャット"
|
chat: "チャット"
|
||||||
migrateOldSettings: "旧設定情報を移行"
|
migrateOldSettings: "旧設定情報を移行"
|
||||||
migrateOldSettings_description: "通常これは自動で行われていますが、何らかの理由により上手く移行されなかった場合は手動で移行処理をトリガーできます。現在の設定情報は上書きされます。"
|
migrateOldSettings_description: "通常これは自動で行われていますが、何らかの理由により上手く移行されなかった場合は手動で移行処理をトリガーできます。現在の設定情報は上書きされます。"
|
||||||
|
compress: "圧縮"
|
||||||
|
|
||||||
_chat:
|
_chat:
|
||||||
noMessagesYet: "まだメッセージはありません"
|
noMessagesYet: "まだメッセージはありません"
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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]+$/, ''),
|
||||||
},
|
},
|
||||||
|
|
|
@ -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>
|
||||||
|
|
||||||
|
|
|
@ -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 => {
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -118,9 +118,6 @@ export const PREF_DEF = {
|
||||||
keepCw: {
|
keepCw: {
|
||||||
default: true,
|
default: true,
|
||||||
},
|
},
|
||||||
keepOriginalUploading: {
|
|
||||||
default: false,
|
|
||||||
},
|
|
||||||
rememberNoteVisibility: {
|
rememberNoteVisibility: {
|
||||||
default: false,
|
default: false,
|
||||||
},
|
},
|
||||||
|
|
|
@ -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],
|
||||||
},
|
},
|
||||||
|
|
|
@ -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',
|
||||||
|
|
|
@ -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');
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue