diff --git a/packages/frontend/src/os.ts b/packages/frontend/src/os.ts index bb10cd7895..c4c545be1b 100644 --- a/packages/frontend/src/os.ts +++ b/packages/frontend/src/os.ts @@ -27,72 +27,67 @@ import { showMovedDialog } from '@/scripts/show-moved-dialog.js'; 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 = (( endpoint: E, data: P = {} as any, token?: string | null | undefined, + customErrors?: Record, ) => { const promise = misskeyApi(endpoint, data, token); - promiseDialog(promise, null, (err) => { - apiErrorAlert(err); + promiseDialog(promise, null, async (err) => { + 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') { + 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; + // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition + } else if (customErrors && customErrors[err.code] != null) { + title = customErrors[err.code].title; + text = customErrors[err.code].text; + } 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; -}) as typeof misskeyApi; +}); type Unpromise = T extends Promise ? U : never; diff --git a/packages/frontend/src/pages/settings/profile.vue b/packages/frontend/src/pages/settings/profile.vue index 398cb7fd58..5ca8d0949d 100644 --- a/packages/frontend/src/pages/settings/profile.vue +++ b/packages/frontend/src/pages/settings/profile.vue @@ -240,26 +240,18 @@ function changeAvatar(ev) { }); } - const updatePromise = misskeyApi('i/update', { + await os.apiWithDialog('i/update', { avatarId: originalOrCropped.id, - }); - - os.promiseDialog(updatePromise, (updatedUser) => { - os.success(); - $i.avatarId = updatedUser.avatarId; - $i.avatarUrl = updatedUser.avatarUrl; + }, undefined, { + 'AVATAR_IS_SENSITIVE': { + title: i18n.ts.cannotSelectSensitiveMedia, + text: i18n.ts.cannotSelectSensitiveMediaDescription, + }, + }).then(() => { + $i.avatarId = originalOrCropped.id; + $i.avatarUrl = originalOrCropped.url; 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'); - } }); }); } @@ -300,25 +292,17 @@ function changeBanner(ev) { }); } - const updatePromise = misskeyApi('i/update', { + await os.apiWithDialog('i/update', { bannerId: originalOrCropped.id, - }); - - os.promiseDialog(updatePromise, (updatedUser) => { - os.success(); - $i.bannerId = updatedUser.bannerId; - $i.bannerUrl = updatedUser.bannerUrl; + }, undefined, { + 'BANNER_IS_SENSITIVE': { + title: i18n.ts.cannotSelectSensitiveMedia, + text: i18n.ts.cannotSelectSensitiveMediaDescription, + }, + }).then(() => { + $i.bannerId = originalOrCropped.id; + $i.bannerUrl = originalOrCropped.url; 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'); - } }); }); }