chore(web): another missing translations (#10274)

* chore(web): another missing translations

* unused removed

* more keys

* lint fix

* test fixed

* dynamic translation fix

* fixes

* people search translation

* params fixed

* keep filter setting fix

* lint fix

* $t fixes

* Update web/src/lib/i18n/en.json

Co-authored-by: Michel Heusschen <59014050+michelheusschen@users.noreply.github.com>

* another missing

* activity translation

* link sharing translations

* expiration dropdown fix - didn't work localized

* notification title

* device logout

* search results

* reset to default

* unsaved change

* select from computer

* selected

* select-2

* select-3

* unmerge

* pluralize, force icu message

* Update web/src/lib/components/asset-viewer/asset-viewer.svelte

Co-authored-by: Michel Heusschen <59014050+michelheusschen@users.noreply.github.com>

* review fixes

* remove user

* plural fixes

* ffmpeg settings

* fixes

* error title

* plural fixes

* onboarding

* change password

* more more

* console log fix

* another

* api key desc

* map marker

* format fix

* key fix

* asset-utils

* utils

* misc

---------

Co-authored-by: Michel Heusschen <59014050+michelheusschen@users.noreply.github.com>
This commit is contained in:
waclaw66
2024-06-24 15:50:01 +02:00
committed by GitHub
parent df9e074304
commit dd2c7400a6
90 changed files with 635 additions and 322 deletions

View File

@@ -37,10 +37,9 @@
import { createAssetInteractionStore } from '$lib/stores/asset-interaction.store';
import { assetViewingStore } from '$lib/stores/asset-viewing.store';
import { AssetStore } from '$lib/stores/assets.store';
import { locale } from '$lib/stores/preferences.store';
import { SlideshowNavigation, SlideshowState, slideshowStore } from '$lib/stores/slideshow.store';
import { user } from '$lib/stores/user.store';
import { handlePromiseError, s } from '$lib/utils';
import { handlePromiseError } from '$lib/utils';
import { downloadAlbum } from '$lib/utils/asset-utils';
import { openFileUploadDialog } from '$lib/utils/file-uploader';
import { handleError } from '$lib/utils/handle-error';
@@ -168,10 +167,10 @@
});
notificationController.show({
type: NotificationType.Info,
message: `Activity is ${album.isActivityEnabled ? 'enabled' : 'disabled'}`,
message: $t('activity_changed', { values: { enabled: album.isActivityEnabled } }),
});
} catch (error) {
handleError(error, `Can't ${album.isActivityEnabled ? 'disable' : 'enable'} activity`);
handleError(error, $t('errors.cant_change_activity', { values: { enabled: album.isActivityEnabled } }));
}
};
@@ -189,7 +188,7 @@
reactions = [...reactions, isLiked];
}
} catch (error) {
handleError(error, "Can't change favorite for asset");
handleError(error, $t('errors.cant_change_asset_favorite'));
}
};
@@ -216,7 +215,7 @@
const { comments } = await getActivityStatistics({ albumId: album.id });
setNumberOfComments(comments);
} catch (error) {
handleError(error, "Can't get number of comments");
handleError(error, $t('errors.cant_get_number_of_comments'));
}
};
@@ -283,7 +282,7 @@
const count = results.filter(({ success }) => success).length;
notificationController.show({
type: NotificationType.Info,
message: `Added ${count} asset${s(count)}`,
message: $t('assets_added_count', { values: { count: count } }),
});
await refreshAlbum();
@@ -291,7 +290,7 @@
timelineInteractionStore.clearMultiselect();
viewMode = ViewMode.VIEW;
} catch (error) {
handleError(error, 'Error adding assets to album');
handleError(error, $t('errors.error_adding_assets_to_album'));
}
};
@@ -317,7 +316,7 @@
viewMode = ViewMode.VIEW;
} catch (error) {
handleError(error, 'Error adding users to album');
handleError(error, $t('errors.error_adding_users_to_album'));
}
};
@@ -331,7 +330,7 @@
await refreshAlbum();
viewMode = album.albumUsers.length > 0 ? ViewMode.VIEW_USERS : ViewMode.VIEW;
} catch (error) {
handleError(error, $t('errors.unable_to_load_album'));
handleError(error, $t('errors.error_deleting_shared_user'));
}
};
@@ -342,7 +341,7 @@
const handleRemoveAlbum = async () => {
const isConfirmed = await dialogController.show({
id: 'remove-album',
prompt: `Are you sure you want to delete the album ${album.albumName}?\nIf this album is shared, other users will not be able to access it anymore.`,
prompt: $t('album_delete_confirmation', { values: { album: album.albumName } }),
});
if (!isConfirmed) {
@@ -393,7 +392,7 @@
},
});
} catch (error) {
handleError(error, 'Unable to update album cover');
handleError(error, $t('errors.unable_to_update_album_cover'));
}
};
@@ -495,9 +494,9 @@
<svelte:fragment slot="leading">
<p class="text-lg dark:text-immich-dark-fg">
{#if $timelineSelected.size === 0}
Add to album
{$t('add_to_album')}
{:else}
{$timelineSelected.size.toLocaleString($locale)} selected
{$t('selected_count', { values: { count: $timelineSelected.size } })}
{/if}
</p>
</svelte:fragment>
@@ -508,7 +507,7 @@
on:click={handleSelectFromComputer}
class="rounded-lg px-6 py-2 text-sm font-medium text-immich-primary transition-all hover:bg-immich-primary/10 dark:text-immich-dark-primary dark:hover:bg-immich-dark-primary/25"
>
Select from computer
{$t('select_from_computer')}
</button>
<Button size="sm" rounded="lg" disabled={$timelineSelected.size === 0} on:click={handleAddAssets}
>{$t('done')}</Button

View File

@@ -161,21 +161,16 @@
if (results.length - count > 0) {
notificationController.show({
type: NotificationType.Error,
message: `Unable to change the visibility for ${results.length - count} ${
results.length - count <= 1 ? 'person' : 'people'
}`,
message: $t('errors.unable_to_change_visibility', { values: { count: results.length - count } }),
});
}
notificationController.show({
type: NotificationType.Info,
message: `Visibility changed for ${count} ${count <= 1 ? 'person' : 'people'}`,
message: $t('visibility_changed', { values: { count: count } }),
});
}
} catch (error) {
handleError(
error,
`Unable to change the visibility for ${changed.length} ${changed.length <= 1 ? 'person' : 'people'}`,
);
handleError(error, $t('errors.unable_to_change_visibility', { values: { count: changed.length } }));
}
// Reset variables used on the "Show & hide people" modal
showLoadingSpinner = false;
@@ -346,7 +341,7 @@
return person;
});
notificationController.show({
message: 'Date of birth saved successfully',
message: $t('birthdate_saved'),
type: NotificationType.Info,
});
} catch (error) {
@@ -447,7 +442,7 @@
<div class="flex flex-col content-center items-center text-center">
<Icon path={mdiAccountOff} size="3.5em" />
<p class="mt-5 text-3xl font-medium max-w-lg line-clamp-2 overflow-hidden">
{`No people${searchName ? ` named "${searchName}"` : ''}`}
{$t(searchName ? 'search_no_people_named' : 'search_no_people', { values: { name: searchName } })}
</p>
</div>
</div>

View File

@@ -30,7 +30,7 @@
import { assetViewingStore } from '$lib/stores/asset-viewing.store';
import { AssetStore } from '$lib/stores/assets.store';
import { websocketEvents } from '$lib/stores/websocket';
import { getPeopleThumbnailUrl, handlePromiseError, s } from '$lib/utils';
import { getPeopleThumbnailUrl, handlePromiseError } from '$lib/utils';
import { clickOutside } from '$lib/actions/click-outside';
import { handleError } from '$lib/utils/handle-error';
import { isExternalUrl } from '$lib/utils/navigation';
@@ -488,7 +488,7 @@
{#if data.person.name}
<p class="w-40 sm:w-72 font-medium truncate">{data.person.name}</p>
<p class="absolute w-fit text-sm text-gray-500 dark:text-immich-gray bottom-0">
{`${numberOfAssets} asset${s(numberOfAssets)}`}
{$t('assets_count', { values: { count: numberOfAssets } })}
</p>
{:else}
<p class="font-medium">{$t('add_a_name')}</p>

View File

@@ -279,7 +279,9 @@
<div class="ml-6 text-4xl font-medium text-black/70 dark:text-white/80">{$t('albums').toUpperCase()}</div>
<AlbumCardGroup albums={searchResultAlbums} showDateRange showItemCount />
<div class="m-6 text-4xl font-medium text-black/70 dark:text-white/80">PHOTOS & VIDEOS</div>
<div class="m-6 text-4xl font-medium text-black/70 dark:text-white/80">
{$t('photos_and_videos').toUpperCase()}
</div>
</section>
{/if}
<section id="search-content" class="relative bg-immich-bg dark:bg-immich-dark-bg">
@@ -296,7 +298,7 @@
<div class="flex flex-col content-center items-center text-center">
<Icon path={mdiImageOffOutline} size="3.5em" />
<p class="mt-5 text-3xl font-medium">{$t('no_results')}</p>
<p class="text-base font-normal">Try a synonym or more general keyword</p>
<p class="text-base font-normal">{$t('no_results_description')}</p>
</div>
</div>
{/if}

View File

@@ -37,8 +37,7 @@
const handleEmptyTrash = async () => {
const isConfirmed = await dialogController.show({
id: 'empty-trash',
prompt:
'Are you sure you want to empty the trash? This will remove all the assets in trash permanently from Immich.\nYou cannot undo this action!',
prompt: $t('empty_trash_confirmation'),
});
if (!isConfirmed) {
@@ -53,7 +52,7 @@
assetStore.removeAssets(deletedAssetIds);
notificationController.show({
message: `Permanently deleted ${numberOfAssets} ${numberOfAssets == 1 ? 'asset' : 'assets'}`,
message: $t('assets_permanently_deleted_count', { values: { count: numberOfAssets } }),
type: NotificationType.Info,
});
} catch (error) {
@@ -64,7 +63,7 @@
const handleRestoreTrash = async () => {
const isConfirmed = await dialogController.show({
id: 'restore-trash',
prompt: 'Are you sure you want to restore all your trashed assets? You cannot undo this action!',
prompt: $t('assets_restore_confirmation'),
});
if (!isConfirmed) {
@@ -78,7 +77,7 @@
assetStore.removeAssets(restoredAssetIds);
notificationController.show({
message: `Restored ${numberOfAssets} ${numberOfAssets == 1 ? 'asset' : 'assets'}`,
message: $t('assets_restored_count', { values: { count: numberOfAssets } }),
type: NotificationType.Info,
});
} catch (error) {

View File

@@ -42,8 +42,8 @@
notificationController.show({
message: $featureFlags.trash
? $t('assets_moved_to_trash', { values: { count: trashedCount } })
: $t('permanently_deleted_assets', { values: { count: trashedCount } }),
? $t('assets_moved_to_trash_count', { values: { count: trashedCount } })
: $t('permanently_deleted_assets_count', { values: { count: trashedCount } }),
type: NotificationType.Info,
});
};

View File

@@ -35,7 +35,7 @@
<div>
<div class="flex items-center justify-between gap-4 px-4 py-4">
<h1 class="font-medium text-immich-primary dark:text-immich-dark-primary">
🚨 Error - Something went wrong
🚨 {$t('error_title')}
</h1>
<div class="flex justify-end">
<CircleIconButton

View File

@@ -6,6 +6,7 @@
import { resetSavedUser, user } from '$lib/stores/user.store';
import { logout } from '@immich/sdk';
import type { PageData } from './$types';
import { t } from 'svelte-i18n';
export let data: PageData;
@@ -18,11 +19,10 @@
<FullscreenContainer title={data.meta.title}>
<p slot="message">
Hi {$user.name} ({$user.email}),
{$t('hi_user', { values: { name: $user.name, email: $user.email } })}
<br />
<br />
This is either the first time you are signing into the system or a request has been made to change your password. Please
enter the new password below.
{$t('change_password_description')}
</p>
<ChangePasswordForm on:success={onSuccess} />

View File

@@ -2,6 +2,7 @@ import { AppRoute } from '$lib/constants';
import { user } from '$lib/stores/user.store';
import { authenticate } from '$lib/utils/auth';
import { redirect } from '@sveltejs/kit';
import { t } from 'svelte-i18n';
import { get } from 'svelte/store';
import type { PageLoad } from './$types';
@@ -11,9 +12,11 @@ export const load = (async () => {
redirect(302, AppRoute.PHOTOS);
}
const $t = get(t);
return {
meta: {
title: 'Change Password',
title: $t('change_password'),
},
};
}) satisfies PageLoad;

View File

@@ -1,6 +1,8 @@
import { AppRoute } from '$lib/constants';
import { defaults, getServerConfig } from '@immich/sdk';
import { redirect } from '@sveltejs/kit';
import { t } from 'svelte-i18n';
import { get } from 'svelte/store';
import type { PageLoad } from './$types';
export const load = (async ({ fetch }) => {
@@ -11,9 +13,10 @@ export const load = (async ({ fetch }) => {
redirect(302, AppRoute.AUTH_REGISTER);
}
const $t = get(t);
return {
meta: {
title: 'Login',
title: $t('login'),
},
};
}) satisfies PageLoad;

View File

@@ -1,13 +1,18 @@
import { loadConfig } from '$lib/stores/server-config.store';
import { authenticate } from '$lib/utils/auth';
import { t } from 'svelte-i18n';
import { get } from 'svelte/store';
import type { PageLoad } from './$types';
export const load = (async () => {
await authenticate({ admin: true });
await loadConfig();
const $t = get(t);
return {
meta: {
title: 'Onboarding',
title: $t('onboarding'),
},
};
}) satisfies PageLoad;

View File

@@ -2,14 +2,14 @@
import AdminRegistrationForm from '$lib/components/forms/admin-registration-form.svelte';
import FullscreenContainer from '$lib/components/shared-components/fullscreen-container.svelte';
import type { PageData } from './$types';
import { t } from 'svelte-i18n';
export let data: PageData;
</script>
<FullscreenContainer title={data.meta.title}>
<p slot="message">
Since you are the first user on the system, you will be assigned as the Admin and are responsible for administrative
tasks, and additional users will be created by you.
{$t('admin.registration_description')}
</p>
<AdminRegistrationForm />

View File

@@ -1,6 +1,8 @@
import { AppRoute } from '$lib/constants';
import { getServerConfig } from '@immich/sdk';
import { redirect } from '@sveltejs/kit';
import { t } from 'svelte-i18n';
import { get } from 'svelte/store';
import type { PageLoad } from './$types';
export const load = (async () => {
@@ -10,9 +12,11 @@ export const load = (async () => {
redirect(302, AppRoute.AUTH_LOGIN);
}
const $t = get(t);
return {
meta: {
title: 'Admin Registration',
title: $t('admin.registration'),
},
};
}) satisfies PageLoad;