Merge branch 'preferences-registry' into pizzax-indexeddb

This commit is contained in:
tamaina
2022-04-28 03:12:44 +00:00
24 changed files with 606 additions and 255 deletions

View File

@@ -4,6 +4,7 @@ import { stream } from '@/stream';
import { i18n } from '@/i18n';
import { defaultStore } from '@/store';
import { DriveFile } from 'misskey-js/built/entities';
import { uploadFile } from '@/scripts/upload';
function select(src: any, label: string | null, multiple: boolean): Promise<DriveFile | DriveFile[]> {
return new Promise((res, rej) => {
@@ -14,7 +15,7 @@ function select(src: any, label: string | null, multiple: boolean): Promise<Driv
input.type = 'file';
input.multiple = multiple;
input.onchange = () => {
const promises = Array.from(input.files).map(file => os.upload(file, defaultStore.state.uploadFolder, undefined, keepOriginal.value));
const promises = Array.from(input.files).map(file => uploadFile(file, defaultStore.state.uploadFolder, undefined, keepOriginal.value));
Promise.all(promises).then(driveFiles => {
res(multiple ? driveFiles : driveFiles[0]);

View File

@@ -0,0 +1,114 @@
import { reactive, ref } from 'vue';
import { defaultStore } from '@/store';
import { apiUrl } from '@/config';
import * as Misskey from 'misskey-js';
import { $i } from '@/account';
import { readAndCompressImage } from 'browser-image-resizer';
import { alert } from '@/os';
type Uploading = {
id: string;
name: string;
progressMax: number | undefined;
progressValue: number | undefined;
img: string;
};
export const uploads = ref<Uploading[]>([]);
const compressTypeMap = {
'image/jpeg': { quality: 0.85, mimeType: 'image/jpeg' },
'image/webp': { quality: 0.85, mimeType: 'image/jpeg' },
'image/svg+xml': { quality: 1, mimeType: 'image/png' },
} as const;
const mimeTypeMap = {
'image/webp': 'webp',
'image/jpeg': 'jpg',
'image/png': 'png',
} as const;
export function uploadFile(
file: File,
folder?: any,
name?: string,
keepOriginal: boolean = defaultStore.state.keepOriginalUploading
): Promise<Misskey.entities.DriveFile> {
if (folder && typeof folder == 'object') folder = folder.id;
return new Promise((resolve, reject) => {
const id = Math.random().toString();
const reader = new FileReader();
reader.onload = async (e) => {
const ctx = reactive<Uploading>({
id: id,
name: name || file.name || 'untitled',
progressMax: undefined,
progressValue: undefined,
img: window.URL.createObjectURL(file)
});
uploads.value.push(ctx);
let resizedImage: any;
if (!keepOriginal && file.type in compressTypeMap) {
const imgConfig = compressTypeMap[file.type];
const config = {
maxWidth: 2048,
maxHeight: 2048,
debug: true,
...imgConfig,
};
try {
resizedImage = await readAndCompressImage(file, config);
ctx.name = file.type !== imgConfig.mimeType ? `${ctx.name}.${mimeTypeMap[compressTypeMap[file.type].mimeType]}` : ctx.name;
} catch (e) {
console.error('Failed to resize image', e);
}
}
const data = new FormData();
data.append('i', $i.token);
data.append('force', 'true');
data.append('file', resizedImage || file);
data.append('name', ctx.name);
if (folder) data.append('folderId', folder);
const xhr = new XMLHttpRequest();
xhr.open('POST', apiUrl + '/drive/files/create', true);
xhr.onload = (ev) => {
if (xhr.status !== 200 || ev.target == null || ev.target.response == null) {
// TODO: 消すのではなくて再送できるようにしたい
uploads.value = uploads.value.filter(x => x.id != id);
alert({
type: 'error',
title: 'Failed to upload',
text: `${JSON.stringify(ev.target?.response)}, ${JSON.stringify(xhr.response)}`
});
reject();
return;
}
const driveFile = JSON.parse(ev.target.response);
resolve(driveFile);
uploads.value = uploads.value.filter(x => x.id != id);
};
xhr.upload.onprogress = e => {
if (e.lengthComputable) {
ctx.progressMax = e.total;
ctx.progressValue = e.loaded;
}
};
xhr.send(data);
};
reader.readAsArrayBuffer(file);
});
}