Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion e2e/src/web/specs/asset-viewer/navbar.e2e-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ test.describe('Asset Viewer Navbar', () => {
await page.goto(`/photos/${asset.id}`);
await page.waitForSelector('#immich-asset-viewer');
await page.keyboard.press('f');
await expect(page.locator('#notification-list').getByTestId('message')).toHaveText('Added to favorites');
await expect(page.getByText('Added to favorites')).toBeVisible();
});
});
});
2 changes: 1 addition & 1 deletion e2e/src/web/specs/asset-viewer/slideshow.e2e-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,6 @@ test.describe('Slideshow', () => {

await expect(page.getByRole('button', { name: 'Exit Slideshow' })).toBeVisible();
await page.keyboard.press('f');
await expect(page.locator('#notification-list')).not.toBeVisible();
await expect(page.getByText('Added to favorites')).not.toBeVisible();
});
});
2 changes: 1 addition & 1 deletion i18n/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -906,7 +906,6 @@
"edit_tag": "Edit tag",
"edit_title": "Edit Title",
"edit_user": "Edit user",
"edited": "Edited",
"editor": "Editor",
"editor_close_without_save_prompt": "The changes will not be saved",
"editor_close_without_save_title": "Close editor?",
Expand Down Expand Up @@ -1717,6 +1716,7 @@
"running": "Running",
"save": "Save",
"save_to_gallery": "Save to gallery",
"saved": "Saved",
"saved_api_key": "Saved API Key",
"saved_profile": "Saved profile",
"saved_settings": "Saved settings",
Expand Down
10 changes: 5 additions & 5 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
"@formatjs/icu-messageformat-parser": "^2.9.8",
"@immich/justified-layout-wasm": "^0.4.3",
"@immich/sdk": "file:../open-api/typescript-sdk",
"@immich/ui": "^0.37.1",
"@immich/ui": "^0.39.1",
"@mapbox/mapbox-gl-rtl-text": "0.2.3",
"@mdi/js": "^7.4.47",
"@photo-sphere-viewer/core": "^5.11.5",
Expand Down
33 changes: 33 additions & 0 deletions web/src/lib/components/ToastAction.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<script lang="ts">
import { Button, ToastContainer, ToastContent, type Color, type IconLike } from '@immich/ui';

type Props = {
onClose?: () => void;
color?: Color;
title: string;
icon?: IconLike | false;
description: string;
button?: {
text: string;
color?: Color;
onClick: () => void;
};
};

const { onClose, title, description, color, icon, button }: Props = $props();

const onClick = () => {
button?.onClick();
onClose?.();
};
</script>

<ToastContainer {color}>
<ToastContent {color} {title} {description} {onClose} {icon}>
{#if button}
<div class="flex justify-end gap-2 px-2 pb-2">
<Button color={button.color ?? 'secondary'} size="small" onclick={onClick}>{button.text}</Button>
</div>
{/if}
</ToastContent>
</ToastContainer>
21 changes: 6 additions & 15 deletions web/src/lib/components/admin-settings/AdminSettings.svelte
Original file line number Diff line number Diff line change
@@ -1,15 +1,12 @@
<script lang="ts">
import {
NotificationType,
notificationController,
} from '$lib/components/shared-components/notification/notification';
import { retrieveServerConfig } from '$lib/stores/server-config.store';
import { handleError } from '$lib/utils/handle-error';
import { getConfig, getConfigDefaults, updateConfig, type SystemConfigDto } from '@immich/sdk';
import { retrieveServerConfig } from '$lib/stores/server-config.store';
import { toastManager } from '@immich/ui';
import { cloneDeep, isEqual } from 'lodash-es';
import { onMount } from 'svelte';
import type { SettingsResetOptions } from './admin-settings';
import { t } from 'svelte-i18n';
import type { SettingsResetOptions } from './admin-settings';

interface Props {
config: SystemConfigDto;
Expand Down Expand Up @@ -41,7 +38,7 @@

config = cloneDeep(newConfig);
savedConfig = cloneDeep(newConfig);
notificationController.show({ message: $t('settings_saved'), type: NotificationType.Info });
toastManager.success($t('settings_saved'));

await retrieveServerConfig();
} catch (error) {
Expand All @@ -56,10 +53,7 @@
config = { ...config, [key]: resetConfig[key] };
}

notificationController.show({
message: $t('admin.reset_settings_to_recent_saved'),
type: NotificationType.Info,
});
toastManager.info($t('admin.reset_settings_to_recent_saved'));
};

const resetToDefault = (configKeys: Array<keyof SystemConfigDto>) => {
Expand All @@ -71,10 +65,7 @@
config = { ...config, [key]: defaultConfig[key] };
}

notificationController.show({
message: $t('admin.reset_settings_to_default'),
type: NotificationType.Info,
});
toastManager.info($t('admin.reset_settings_to_default'));
};

onMount(async () => {
Expand Down
8 changes: 2 additions & 6 deletions web/src/lib/components/admin-settings/AuthSettings.svelte
Original file line number Diff line number Diff line change
@@ -1,8 +1,4 @@
<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 SettingButtonsRow from '$lib/components/shared-components/settings/setting-buttons-row.svelte';
import SettingInputField from '$lib/components/shared-components/settings/setting-input-field.svelte';
Expand All @@ -13,7 +9,7 @@
import AuthDisableLoginConfirmModal from '$lib/modals/AuthDisableLoginConfirmModal.svelte';
import { handleError } from '$lib/utils/handle-error';
import { OAuthTokenEndpointAuthMethod, unlinkAllOAuthAccountsAdmin, type SystemConfigDto } from '@immich/sdk';
import { Button, modalManager, Text } from '@immich/ui';
import { Button, modalManager, Text, toastManager } from '@immich/ui';
import { mdiRestart } from '@mdi/js';
import { isEqual } from 'lodash-es';
import { t } from 'svelte-i18n';
Expand Down Expand Up @@ -65,7 +61,7 @@

try {
await unlinkAllOAuthAccountsAdmin({});
notificationController.show({ message: $t('success'), type: NotificationType.Info });
toastManager.success({});
} catch (error) {
handleError(error, $t('errors.something_went_wrong'));
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
<script lang="ts">
import TemplateSettings from '$lib/components/admin-settings/TemplateSettings.svelte';
import {
NotificationType,
notificationController,
} from '$lib/components/shared-components/notification/notification';
import SettingAccordion from '$lib/components/shared-components/settings/setting-accordion.svelte';
import SettingButtonsRow from '$lib/components/shared-components/settings/setting-buttons-row.svelte';
import SettingInputField from '$lib/components/shared-components/settings/setting-input-field.svelte';
Expand All @@ -12,7 +8,7 @@
import { user } from '$lib/stores/user.store';
import { handleError } from '$lib/utils/handle-error';
import { sendTestEmailAdmin, type SystemConfigDto } from '@immich/sdk';
import { Button, LoadingSpinner } from '@immich/ui';
import { Button, LoadingSpinner, toastManager } from '@immich/ui';
import { isEqual } from 'lodash-es';
import { t } from 'svelte-i18n';
import { fade } from 'svelte/transition';
Expand Down Expand Up @@ -55,10 +51,7 @@
},
});

notificationController.show({
type: NotificationType.Info,
message: $t('admin.notification_email_test_email_sent', { values: { email: $user.email } }),
});
toastManager.success($t('admin.notification_email_test_email_sent', { values: { email: $user.email } }));

if (!disabled) {
onSave({ notifications: config.notifications });
Expand Down
32 changes: 15 additions & 17 deletions web/src/lib/components/album-page/albums-list.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,7 @@
import AlbumsTable from '$lib/components/album-page/albums-table.svelte';
import MenuOption from '$lib/components/shared-components/context-menu/menu-option.svelte';
import RightClickContextMenu from '$lib/components/shared-components/context-menu/right-click-context-menu.svelte';
import {
NotificationType,
notificationController,
} from '$lib/components/shared-components/notification/notification';
import ToastAction from '$lib/components/ToastAction.svelte';
import { AppRoute } from '$lib/constants';
import AlbumEditModal from '$lib/modals/AlbumEditModal.svelte';
import AlbumShareModal from '$lib/modals/AlbumShareModal.svelte';
Expand Down Expand Up @@ -38,7 +35,7 @@
import { handleError } from '$lib/utils/handle-error';
import { normalizeSearchString } from '$lib/utils/string-utils';
import { addUsersToAlbum, deleteAlbum, isHttpError, type AlbumResponseDto, type AlbumUserAddDto } from '@immich/sdk';
import { modalManager } from '@immich/ui';
import { modalManager, toastManager } from '@immich/ui';
import { mdiDeleteOutline, mdiDownload, mdiRenameOutline, mdiShareVariantOutline } from '@mdi/js';
import { groupBy } from 'lodash-es';
import { onMount, type Snippet } from 'svelte';
Expand Down Expand Up @@ -280,11 +277,8 @@

try {
await handleDeleteAlbum(albumToDelete);
} catch {
notificationController.show({
message: $t('errors.unable_to_delete_album'),
type: NotificationType.Error,
});
} catch (error) {
handleError(error, $t('errors.unable_to_delete_album'));
} finally {
albumToDelete = null;
}
Expand All @@ -310,13 +304,17 @@
};

const successEditAlbumInfo = (album: AlbumResponseDto) => {
notificationController.show({
message: $t('album_info_updated'),
type: NotificationType.Info,
button: {
text: $t('view_album'),
onClick() {
return goto(resolve(`${AppRoute.ALBUMS}/${album.id}`));
toastManager.custom({
component: ToastAction,
props: {
color: 'primary',
title: $t('success'),
description: $t('album_info_updated'),
button: {
text: $t('view_album'),
onClick() {
return goto(resolve(`${AppRoute.ALBUMS}/${album.id}`));
},
},
},
});
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,14 @@
<script lang="ts">
import { shortcuts } from '$lib/actions/shortcut';
import DeleteAssetDialog from '$lib/components/photos-page/delete-asset-dialog.svelte';
import {
NotificationType,
notificationController,
} from '$lib/components/shared-components/notification/notification';
import { AssetAction } from '$lib/constants';
import Portal from '$lib/elements/Portal.svelte';
import { showDeleteModal } from '$lib/stores/preferences.store';
import { featureFlags } from '$lib/stores/server-config.store';
import { handleError } from '$lib/utils/handle-error';
import { toTimelineAsset } from '$lib/utils/timeline-util';
import { deleteAssets, type AssetResponseDto } from '@immich/sdk';
import { IconButton } from '@immich/ui';
import { IconButton, toastManager } from '@immich/ui';
import { mdiDeleteForeverOutline, mdiDeleteOutline } from '@mdi/js';
import { t } from 'svelte-i18n';
import type { OnAction, PreAction } from './action';
Expand Down Expand Up @@ -46,11 +42,7 @@
preAction({ type: AssetAction.TRASH, asset: toTimelineAsset(asset) });
await deleteAssets({ assetBulkDeleteDto: { ids: [asset.id] } });
onAction({ type: AssetAction.TRASH, asset: toTimelineAsset(asset) });

notificationController.show({
message: $t('moved_to_trash'),
type: NotificationType.Info,
});
toastManager.success($t('moved_to_trash'));
} catch (error) {
handleError(error, $t('errors.unable_to_trash_asset'));
}
Expand All @@ -61,11 +53,7 @@
preAction({ type: AssetAction.DELETE, asset: toTimelineAsset(asset) });
await deleteAssets({ assetBulkDeleteDto: { ids: [asset.id], force: true } });
onAction({ type: AssetAction.DELETE, asset: toTimelineAsset(asset) });

notificationController.show({
message: $t('permanently_deleted_asset'),
type: NotificationType.Info,
});
toastManager.success($t('permanently_deleted_asset'));
} catch (error) {
handleError(error, $t('errors.unable_to_delete_asset'));
} finally {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,13 @@
<script lang="ts">
import { shortcut } from '$lib/actions/shortcut';
import {
NotificationType,
notificationController,
} from '$lib/components/shared-components/notification/notification';
import { AssetAction } from '$lib/constants';
import { handleError } from '$lib/utils/handle-error';
import { toTimelineAsset } from '$lib/utils/timeline-util';
import { updateAsset, type AssetResponseDto } from '@immich/sdk';
import { IconButton, toastManager } from '@immich/ui';
import { mdiHeart, mdiHeartOutline } from '@mdi/js';
import { t } from 'svelte-i18n';
import type { OnAction } from './action';
import { IconButton } from '@immich/ui';

interface Props {
asset: AssetResponseDto;
Expand All @@ -36,10 +32,7 @@
asset: toTimelineAsset(asset),
});

notificationController.show({
type: NotificationType.Info,
message: asset.isFavorite ? $t('added_to_favorites') : $t('removed_from_favorites'),
});
toastManager.success(asset.isFavorite ? $t('added_to_favorites') : $t('removed_from_favorites'));
} catch (error) {
handleError(error, $t('errors.unable_to_add_remove_favorites', { values: { favorite: asset.isFavorite } }));
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,10 @@
<script lang="ts">
import MenuOption from '$lib/components/shared-components/context-menu/menu-option.svelte';
import {
notificationController,
NotificationType,
} from '$lib/components/shared-components/notification/notification';
import { AssetAction } from '$lib/constants';
import { handleError } from '$lib/utils/handle-error';
import { toTimelineAsset } from '$lib/utils/timeline-util';
import { restoreAssets, type AssetResponseDto } from '@immich/sdk';
import { toastManager } from '@immich/ui';
import { mdiHistory } from '@mdi/js';
import { t } from 'svelte-i18n';
import type { OnAction } from './action';
Expand All @@ -23,13 +20,8 @@
try {
await restoreAssets({ bulkIdsDto: { ids: [asset.id] } });
asset.isTrashed = false;

onAction({ type: AssetAction.RESTORE, asset: toTimelineAsset(asset) });

notificationController.show({
type: NotificationType.Info,
message: $t('restored_asset'),
});
toastManager.success($t('restored_asset'));
} catch (error) {
handleError(error, $t('errors.unable_to_restore_assets'));
}
Expand Down
Loading
Loading