いろいろ変えた

This commit is contained in:
kakkokari-gtyih 2024-04-09 14:35:51 +09:00
parent 466835a614
commit db27623f2d
3 changed files with 110 additions and 79 deletions

View File

@ -27,66 +27,78 @@ import { showMovedDialog } from '@/scripts/show-moved-dialog.js';
export const openingWindowsCount = ref(0); export const openingWindowsCount = ref(0);
export async function apiErrorAlert(err: Misskey.api.APIError, endpoint?: string) {
let title: string | undefined;
let text = err.message + '\n' + err.id;
if (err.code === 'INTERNAL_ERROR') {
title = i18n.ts.internalServerError;
text = i18n.ts.internalServerErrorDescription;
const date = new Date().toISOString();
const { result } = await actions({
type: 'error',
title,
text,
actions: [{
value: 'ok',
text: i18n.ts.gotIt,
primary: true,
}, {
value: 'copy',
text: i18n.ts.copyErrorInfo,
}],
});
if (result === 'copy') {
const errorReportText = [
`Info: ${JSON.stringify(err.info)}`,
`Date: ${date}`,
];
if (endpoint) errorReportText.unshift(`Endpoint: ${endpoint}`);
copyToClipboard(errorReportText.join('\n'));
success();
}
return;
} else if (err.code === 'RATE_LIMIT_EXCEEDED') {
title = i18n.ts.cannotPerformTemporary;
text = i18n.ts.cannotPerformTemporaryDescription;
} else if (err.code === 'INVALID_PARAM') {
title = i18n.ts.invalidParamError;
text = i18n.ts.invalidParamErrorDescription;
} else if (err.code === 'ROLE_PERMISSION_DENIED') {
title = i18n.ts.permissionDeniedError;
text = i18n.ts.permissionDeniedErrorDescription;
} else if (err.code.startsWith('TOO_MANY')) {
title = i18n.ts.youCannotCreateAnymore;
text = `${i18n.ts.error}: ${err.id}`;
} else if (err.message.startsWith('Unexpected token')) {
title = i18n.ts.gotInvalidResponseError;
text = i18n.ts.gotInvalidResponseErrorDescription;
}
alert({
type: 'error',
title,
text,
});
}
export const apiWithDialog = (<E extends keyof Misskey.Endpoints = keyof Misskey.Endpoints, P extends Misskey.Endpoints[E]['req'] = Misskey.Endpoints[E]['req']>( export const apiWithDialog = (<E extends keyof Misskey.Endpoints = keyof Misskey.Endpoints, P extends Misskey.Endpoints[E]['req'] = Misskey.Endpoints[E]['req']>(
endpoint: E, endpoint: E,
data: P = {} as any, data: P = {} as any,
token?: string | null | undefined, token?: string | null | undefined,
) => { ) => {
const promise = misskeyApi(endpoint, data, token); const promise = misskeyApi(endpoint, data, token);
promiseDialog(promise, null, async (err) => { promiseDialog(promise, null, (err) => {
let title: string | undefined; apiErrorAlert(err);
let text = err.message + '\n' + err.id;
if (err.code === 'INTERNAL_ERROR') {
title = i18n.ts.internalServerError;
text = i18n.ts.internalServerErrorDescription;
const date = new Date().toISOString();
const { result } = await actions({
type: 'error',
title,
text,
actions: [{
value: 'ok',
text: i18n.ts.gotIt,
primary: true,
}, {
value: 'copy',
text: i18n.ts.copyErrorInfo,
}],
});
if (result === 'copy') {
copyToClipboard(`Endpoint: ${endpoint}\nInfo: ${JSON.stringify(err.info)}\nDate: ${date}`);
success();
}
return;
} else if (err.code === 'RATE_LIMIT_EXCEEDED') {
title = i18n.ts.cannotPerformTemporary;
text = i18n.ts.cannotPerformTemporaryDescription;
} else if (err.code === 'INVALID_PARAM') {
title = i18n.ts.invalidParamError;
text = i18n.ts.invalidParamErrorDescription;
} else if (err.code === 'ROLE_PERMISSION_DENIED') {
title = i18n.ts.permissionDeniedError;
text = i18n.ts.permissionDeniedErrorDescription;
} else if (err.code.startsWith('TOO_MANY')) {
title = i18n.ts.youCannotCreateAnymore;
text = `${i18n.ts.error}: ${err.id}`;
} else if (err.message.startsWith('Unexpected token')) {
title = i18n.ts.gotInvalidResponseError;
text = i18n.ts.gotInvalidResponseErrorDescription;
}
alert({
type: 'error',
title,
text,
});
}); });
return promise; return promise;
}) as typeof misskeyApi; }) as typeof misskeyApi;
type Unpromise<T> = T extends Promise<infer U> ? U : never;
export function promiseDialog<T extends Promise<any>>( export function promiseDialog<T extends Promise<any>>(
promise: T, promise: T,
onSuccess?: ((res: any) => void) | null, onSuccess?: ((res: Unpromise<T>) => void) | null,
onFailure?: ((err: Misskey.api.APIError) => void) | null, onFailure?: ((err: Misskey.api.APIError) => void) | null,
text?: string, text?: string,
): T { ): T {

View File

@ -128,6 +128,7 @@ import { defaultStore } from '@/store.js';
import { globalEvents } from '@/events.js'; import { globalEvents } from '@/events.js';
import MkInfo from '@/components/MkInfo.vue'; import MkInfo from '@/components/MkInfo.vue';
import MkTextarea from '@/components/MkTextarea.vue'; import MkTextarea from '@/components/MkTextarea.vue';
import { misskeyApi } from '@/scripts/misskey-api.js';
const $i = signinRequired(); const $i = signinRequired();
@ -239,13 +240,27 @@ function changeAvatar(ev) {
}); });
} }
const i = await os.apiWithDialog('i/update', { const updatePromise = misskeyApi('i/update', {
avatarId: originalOrCropped.id, avatarId: originalOrCropped.id,
}); });
$i.avatarId = i.avatarId;
$i.avatarUrl = i.avatarUrl; os.promiseDialog(updatePromise, (updatedUser) => {
globalEvents.emit('requestClearPageCache'); os.success();
claimAchievement('profileFilled'); $i.avatarId = updatedUser.avatarId;
$i.avatarUrl = updatedUser.avatarUrl;
globalEvents.emit('requestClearPageCache');
claimAchievement('profileFilled');
}, (err) => {
if (err.code === 'AVATAR_IS_SENSITIVE') {
os.alert({
type: 'error',
title: i18n.ts.cannotSelectSensitiveMedia,
text: i18n.ts.cannotSelectSensitiveMediaDescription,
});
} else {
os.apiErrorAlert(err, 'i/update');
}
});
}); });
} }
@ -285,12 +300,26 @@ function changeBanner(ev) {
}); });
} }
const i = await os.apiWithDialog('i/update', { const updatePromise = misskeyApi('i/update', {
bannerId: originalOrCropped.id, bannerId: originalOrCropped.id,
}); });
$i.bannerId = i.bannerId;
$i.bannerUrl = i.bannerUrl; os.promiseDialog(updatePromise, (updatedUser) => {
globalEvents.emit('requestClearPageCache'); os.success();
$i.bannerId = updatedUser.bannerId;
$i.bannerUrl = updatedUser.bannerUrl;
globalEvents.emit('requestClearPageCache');
}, (err) => {
if (err.code === 'BANNER_IS_SENSITIVE') {
os.alert({
type: 'error',
title: i18n.ts.cannotSelectSensitiveMedia,
text: i18n.ts.cannotSelectSensitiveMediaDescription,
});
} else {
os.apiErrorAlert(err, 'i/update');
}
});
}); });
} }

View File

@ -12,6 +12,7 @@ import { useStream } from '@/stream.js';
import { i18n } from '@/i18n.js'; import { i18n } from '@/i18n.js';
import { defaultStore } from '@/store.js'; import { defaultStore } from '@/store.js';
import { uploadFile } from '@/scripts/upload.js'; import { uploadFile } from '@/scripts/upload.js';
import { deepMerge } from '@/scripts/merge.js';
type SelectFileOptions = { type SelectFileOptions = {
multiple?: boolean; multiple?: boolean;
@ -88,29 +89,18 @@ export function chooseFileFromUrl(): Promise<Misskey.entities.DriveFile> {
} }
function select(src: any, label: string | null, options?: SelectFileOptions): Promise<Misskey.entities.DriveFile[]> { function select(src: any, label: string | null, options?: SelectFileOptions): Promise<Misskey.entities.DriveFile[]> {
const _options = { const _options = deepMerge(options ?? {}, {
multiple: false, multiple: false,
/** ドライブファイル選択時のみに適用 */
excludeSensitive: false, excludeSensitive: false,
additionalMenu: [],
...options, additionalMenu: [] as MenuItem[],
}; });
return new Promise((res, rej) => { return new Promise((res, rej) => {
const keepOriginal = ref(defaultStore.state.keepOriginalUploading); const keepOriginal = ref(defaultStore.state.keepOriginalUploading);
function _resolve(files: Misskey.entities.DriveFile[]) {
if (_options.excludeSensitive && files.some(file => file.isSensitive)) {
os.alert({
title: i18n.ts.cannotSelectSensitiveMedia,
text: i18n.ts.cannotSelectSensitiveMediaDescription,
});
rej(new Error('Sensitive media is selected'));
return;
}
res(files);
}
os.popupMenu([label ? { os.popupMenu([label ? {
text: label, text: label,
type: 'label', type: 'label',
@ -121,23 +111,23 @@ function select(src: any, label: string | null, options?: SelectFileOptions): Pr
}, { }, {
text: i18n.ts.upload, text: i18n.ts.upload,
icon: 'ti ti-upload', icon: 'ti ti-upload',
action: () => chooseFileFromPc(_options.multiple, keepOriginal.value).then(files => _resolve(files)), action: () => chooseFileFromPc(_options.multiple, keepOriginal.value).then(files => res(files)),
}, { }, {
text: i18n.ts.fromDrive, text: i18n.ts.fromDrive,
icon: 'ti ti-cloud', icon: 'ti ti-cloud',
action: () => chooseFileFromDrive(_options.multiple, _options.excludeSensitive).then(files => _resolve(files)), action: () => chooseFileFromDrive(_options.multiple, _options.excludeSensitive).then(files => res(files)),
}, { }, {
text: i18n.ts.fromUrl, text: i18n.ts.fromUrl,
icon: 'ti ti-link', icon: 'ti ti-link',
action: () => chooseFileFromUrl().then(file => _resolve([file])), action: () => chooseFileFromUrl().then(file => res([file])),
}, ..._options.additionalMenu], src); }, ...(_options.additionalMenu)], src);
}); });
} }
export function selectFile(src: any, label: string | null = null, options?: { excludeSensitive?: boolean; additionalMenu?: MenuItem[]; }): Promise<Misskey.entities.DriveFile> { export function selectFile(src: any, label: string | null = null, options?: { excludeSensitive?: boolean; additionalMenu?: MenuItem[]; }): Promise<Misskey.entities.DriveFile> {
return select(src, label, { ...options, multiple: false }).then(files => files[0]); return select(src, label, { ...(options ? options : {}), multiple: false }).then(files => files[0]);
} }
export function selectFiles(src: any, label: string | null = null, options?: { excludeSensitive?: boolean; additionalMenu?: MenuItem[]; }): Promise<Misskey.entities.DriveFile[]> { export function selectFiles(src: any, label: string | null = null, options?: { excludeSensitive?: boolean; additionalMenu?: MenuItem[]; }): Promise<Misskey.entities.DriveFile[]> {
return select(src, label, { ...options, multiple: true }); return select(src, label, { ...(options ? options : {}), multiple: true });
} }