feat: toasts (#23298)

This commit is contained in:
Jason Rasmussen
2025-10-28 15:09:11 -04:00
committed by GitHub
parent 106effca2e
commit 52596255c8
80 changed files with 341 additions and 1069 deletions

View File

@@ -1,12 +1,8 @@
<script lang="ts">
import {
notificationController,
NotificationType,
} from '$lib/components/shared-components/notification/notification';
import PinCodeInput from '$lib/components/user-settings-page/PinCodeInput.svelte';
import { handleError } from '$lib/utils/handle-error';
import { changePinCode } from '@immich/sdk';
import { Button, Heading, Text } from '@immich/ui';
import { Button, Heading, Text, toastManager } from '@immich/ui';
import { t } from 'svelte-i18n';
import { fade } from 'svelte/transition';
@@ -31,13 +27,8 @@
isLoading = true;
try {
await changePinCode({ pinCodeChangeDto: { pinCode: currentPinCode, newPinCode } });
resetForm();
notificationController.show({
message: $t('pin_code_changed_successfully'),
type: NotificationType.Info,
});
toastManager.success($t('pin_code_changed_successfully'));
} catch (error) {
handleError(error, $t('unable_to_change_pin_code'));
} finally {

View File

@@ -1,12 +1,8 @@
<script lang="ts">
import {
notificationController,
NotificationType,
} from '$lib/components/shared-components/notification/notification';
import PinCodeInput from '$lib/components/user-settings-page/PinCodeInput.svelte';
import { handleError } from '$lib/utils/handle-error';
import { setupPinCode } from '@immich/sdk';
import { Button, Heading } from '@immich/ui';
import { Button, Heading, toastManager } from '@immich/ui';
import { t } from 'svelte-i18n';
interface Props {
@@ -30,12 +26,7 @@
isLoading = true;
try {
await setupPinCode({ pinCodeSetupDto: { pinCode: newPinCode } });
notificationController.show({
message: $t('pin_code_setup_successfully'),
type: NotificationType.Info,
});
toastManager.success($t('pin_code_setup_successfully'));
onCreated?.(newPinCode);
resetForm();
} catch (error) {

View File

@@ -1,14 +1,10 @@
<script lang="ts">
import {
notificationController,
NotificationType,
} from '$lib/components/shared-components/notification/notification';
import SettingInputField from '$lib/components/shared-components/settings/setting-input-field.svelte';
import SettingSwitch from '$lib/components/shared-components/settings/setting-switch.svelte';
import { SettingInputFieldType } from '$lib/constants';
import { handleError } from '$lib/utils/handle-error';
import { changePassword } from '@immich/sdk';
import { Button } from '@immich/ui';
import type { HttpError } from '@sveltejs/kit';
import { Button, toastManager } from '@immich/ui';
import { t } from 'svelte-i18n';
import { fade } from 'svelte/transition';
@@ -21,20 +17,14 @@
try {
await changePassword({ changePasswordDto: { password, newPassword, invalidateSessions } });
notificationController.show({
message: $t('updated_password'),
type: NotificationType.Info,
});
toastManager.success($t('updated_password'));
password = '';
newPassword = '';
confirmPassword = '';
} catch (error) {
console.error('Error [user-profile] [changePassword]', error);
notificationController.show({
message: (error as HttpError)?.body?.message || $t('errors.unable_to_change_password'),
type: NotificationType.Error,
});
handleError(error, $t('errors.unable_to_change_password'));
}
};

View File

@@ -1,9 +1,8 @@
<script lang="ts">
import { handleError } from '$lib/utils/handle-error';
import { deleteAllSessions, deleteSession, getSessions, type SessionResponseDto } from '@immich/sdk';
import { Button, modalManager } from '@immich/ui';
import { Button, modalManager, toastManager } from '@immich/ui';
import { t } from 'svelte-i18n';
import { handleError } from '../../utils/handle-error';
import { notificationController, NotificationType } from '../shared-components/notification/notification';
import DeviceCard from './device-card.svelte';
interface Props {
@@ -25,7 +24,7 @@
try {
await deleteSession({ id: device.id });
notificationController.show({ message: $t('logged_out_device'), type: NotificationType.Info });
toastManager.success($t('logged_out_device'));
} catch (error) {
handleError(error, $t('errors.unable_to_log_out_device'));
} finally {
@@ -41,10 +40,7 @@
try {
await deleteAllSessions();
notificationController.show({
message: $t('logged_out_all_devices'),
type: NotificationType.Info,
});
toastManager.success($t('logged_out_all_devices'));
} catch (error) {
handleError(error, $t('errors.unable_to_log_out_all_devices'));
} finally {

View File

@@ -1,18 +1,14 @@
<script lang="ts">
import {
notificationController,
NotificationType,
} from '$lib/components/shared-components/notification/notification';
import SettingInputField from '$lib/components/shared-components/settings/setting-input-field.svelte';
import SettingSwitch from '$lib/components/shared-components/settings/setting-switch.svelte';
import { SettingInputFieldType } from '$lib/constants';
import { preferences } from '$lib/stores/user.store';
import { ByteUnit, convertFromBytes, convertToBytes } from '$lib/utils/byte-units';
import { handleError } from '$lib/utils/handle-error';
import { updateMyPreferences } from '@immich/sdk';
import { Button } from '@immich/ui';
import { Button, toastManager } from '@immich/ui';
import { t } from 'svelte-i18n';
import { fade } from 'svelte/transition';
import { handleError } from '../../utils/handle-error';
let archiveSize = $state(convertFromBytes($preferences?.download?.archiveSize || 4, ByteUnit.GiB));
let includeEmbeddedVideos = $state($preferences?.download?.includeEmbeddedVideos || false);
@@ -29,7 +25,7 @@
});
$preferences = newPreferences;
notificationController.show({ message: $t('saved_settings'), type: NotificationType.Info });
toastManager.success($t('saved_settings'));
} catch (error) {
handleError(error, $t('errors.unable_to_update_settings'));
}

View File

@@ -1,17 +1,13 @@
<script lang="ts">
import {
notificationController,
NotificationType,
} from '$lib/components/shared-components/notification/notification';
import SettingAccordion from '$lib/components/shared-components/settings/setting-accordion.svelte';
import SettingSelect from '$lib/components/shared-components/settings/setting-select.svelte';
import SettingSwitch from '$lib/components/shared-components/settings/setting-switch.svelte';
import { preferences } from '$lib/stores/user.store';
import { handleError } from '$lib/utils/handle-error';
import { AssetOrder, updateMyPreferences } from '@immich/sdk';
import { Button } from '@immich/ui';
import { Button, toastManager } from '@immich/ui';
import { t } from 'svelte-i18n';
import { fade } from 'svelte/transition';
import { handleError } from '../../utils/handle-error';
// Albums
let defaultAssetOrder = $state($preferences?.albums?.defaultAssetOrder ?? AssetOrder.Desc);
@@ -58,7 +54,7 @@
$preferences = { ...data };
notificationController.show({ message: $t('saved_settings'), type: NotificationType.Info });
toastManager.success($t('saved_settings'));
} catch (error) {
handleError(error, $t('errors.unable_to_update_settings'));
}

View File

@@ -1,16 +1,11 @@
<script lang="ts">
import {
notificationController,
NotificationType,
} from '$lib/components/shared-components/notification/notification';
import { updateMyPreferences } from '@immich/sdk';
import { fade } from 'svelte/transition';
import { handleError } from '../../utils/handle-error';
import SettingSwitch from '$lib/components/shared-components/settings/setting-switch.svelte';
import { preferences } from '$lib/stores/user.store';
import { handleError } from '$lib/utils/handle-error';
import { updateMyPreferences } from '@immich/sdk';
import { Button, toastManager } from '@immich/ui';
import { t } from 'svelte-i18n';
import { Button } from '@immich/ui';
import { fade } from 'svelte/transition';
let emailNotificationsEnabled = $state($preferences?.emailNotifications?.enabled ?? true);
let albumInviteNotificationEnabled = $state($preferences?.emailNotifications?.albumInvite ?? true);
@@ -32,7 +27,7 @@
$preferences.emailNotifications.albumInvite = data.emailNotifications.albumInvite;
$preferences.emailNotifications.albumUpdate = data.emailNotifications.albumUpdate;
notificationController.show({ message: $t('saved_settings'), type: NotificationType.Info });
toastManager.success($t('saved_settings'));
} catch (error) {
handleError(error, $t('errors.unable_to_update_settings'));
}

View File

@@ -2,13 +2,12 @@
import { goto } from '$app/navigation';
import { featureFlags } from '$lib/stores/server-config.store';
import { oauth } from '$lib/utils';
import { handleError } from '$lib/utils/handle-error';
import { type UserAdminResponseDto } from '@immich/sdk';
import { Button, LoadingSpinner } from '@immich/ui';
import { Button, LoadingSpinner, toastManager } from '@immich/ui';
import { onMount } from 'svelte';
import { t } from 'svelte-i18n';
import { fade } from 'svelte/transition';
import { handleError } from '../../utils/handle-error';
import { notificationController, NotificationType } from '../shared-components/notification/notification';
interface Props {
user: UserAdminResponseDto;
@@ -22,13 +21,8 @@
if (oauth.isCallback(globalThis.location)) {
try {
loading = true;
user = await oauth.link(globalThis.location);
notificationController.show({
message: $t('linked_oauth_account'),
type: NotificationType.Info,
});
toastManager.success($t('linked_oauth_account'));
} catch (error) {
handleError(error, $t('errors.unable_to_link_oauth_account'));
} finally {
@@ -42,10 +36,7 @@
const handleUnlink = async () => {
try {
user = await oauth.unlink();
notificationController.show({
message: $t('unlinked_oauth_account'),
type: NotificationType.Info,
});
toastManager.success($t('unlinked_oauth_account'));
} catch (error) {
handleError(error, $t('errors.unable_to_unlink_account'));
}

View File

@@ -2,6 +2,7 @@
import SettingSwitch from '$lib/components/shared-components/settings/setting-switch.svelte';
import UserAvatar from '$lib/components/shared-components/user-avatar.svelte';
import PartnerSelectionModal from '$lib/modals/PartnerSelectionModal.svelte';
import { handleError } from '$lib/utils/handle-error';
import {
createPartner,
getPartners,
@@ -15,7 +16,6 @@
import { mdiCheck, mdiClose } from '@mdi/js';
import { onMount } from 'svelte';
import { t } from 'svelte-i18n';
import { handleError } from '../../utils/handle-error';
interface PartnerSharing {
user: UserResponseDto;

View File

@@ -3,13 +3,12 @@
import ApiKeyModal from '$lib/modals/ApiKeyModal.svelte';
import ApiKeySecretModal from '$lib/modals/ApiKeySecretModal.svelte';
import { locale } from '$lib/stores/preferences.store';
import { handleError } from '$lib/utils/handle-error';
import { createApiKey, deleteApiKey, getApiKeys, updateApiKey, type ApiKeyResponseDto } from '@immich/sdk';
import { Button, IconButton, modalManager } from '@immich/ui';
import { Button, IconButton, modalManager, toastManager } from '@immich/ui';
import { mdiPencilOutline, mdiTrashCanOutline } from '@mdi/js';
import { t } from 'svelte-i18n';
import { fade } from 'svelte/transition';
import { handleError } from '../../utils/handle-error';
import { notificationController, NotificationType } from '../shared-components/notification/notification';
interface Props {
keys: ApiKeyResponseDto[];
@@ -61,10 +60,7 @@
try {
await updateApiKey({ id: key.id, apiKeyUpdateDto: { name: result.name, permissions: result.permissions } });
notificationController.show({
message: $t('saved_api_key'),
type: NotificationType.Info,
});
toastManager.success($t('saved_api_key'));
} catch (error) {
handleError(error, $t('errors.unable_to_save_api_key'));
} finally {
@@ -80,10 +76,7 @@
try {
await deleteApiKey({ id: key.id });
notificationController.show({
message: $t('removed_api_key', { values: { name: key.name } }),
type: NotificationType.Info,
});
toastManager.success($t('removed_api_key', { values: { name: key.name } }));
} catch (error) {
handleError(error, $t('errors.unable_to_remove_api_key'));
} finally {

View File

@@ -1,18 +1,14 @@
<script lang="ts">
import {
notificationController,
NotificationType,
} from '$lib/components/shared-components/notification/notification';
import SettingInputField from '$lib/components/shared-components/settings/setting-input-field.svelte';
import { SettingInputFieldType } from '$lib/constants';
import { user } from '$lib/stores/user.store';
import { handleError } from '$lib/utils/handle-error';
import { updateMyUser } from '@immich/sdk';
import { Button } from '@immich/ui';
import { Button, toastManager } from '@immich/ui';
import { cloneDeep } from 'lodash-es';
import { t } from 'svelte-i18n';
import { createBubbler, preventDefault } from 'svelte/legacy';
import { fade } from 'svelte/transition';
import { handleError } from '../../utils/handle-error';
let editedUser = $state(cloneDeep($user));
const bubble = createBubbler();
@@ -29,10 +25,7 @@
Object.assign(editedUser, data);
$user = data;
notificationController.show({
message: $t('saved_profile'),
type: NotificationType.Info,
});
toastManager.success($t('saved_profile'));
} catch (error) {
handleError(error, $t('errors.unable_to_save_profile'));
}