mirror of
https://github.com/immich-app/immich.git
synced 2026-06-12 19:11:52 -07:00
feat(web): video player i18n (#28192)
This commit is contained in:
+32
-1
@@ -1524,6 +1524,38 @@
|
||||
"marked_all_as_read": "Marked all as read",
|
||||
"matches": "Matches",
|
||||
"matching_assets": "Matching Assets",
|
||||
"media_chrome": {
|
||||
"auto": "Auto",
|
||||
"captions": "Captions",
|
||||
"captions_off": "Off",
|
||||
"closed_captions": "closed captions",
|
||||
"decode_error": "Decode error",
|
||||
"disable_captions": "Disable captions",
|
||||
"enable_captions": "Enable captions",
|
||||
"enter_fullscreen_mode": "Enter fullscreen mode",
|
||||
"exit_fullscreen_mode": "Exit fullscreen mode",
|
||||
"loop": "Loop",
|
||||
"media_error_description": "A media error caused playback to be aborted. The media could be corrupt or your browser does not support this format.",
|
||||
"media_loading": "media loading",
|
||||
"mute": "Mute",
|
||||
"network_error": "Network error",
|
||||
"network_error_description": "A network error caused the media download to fail.",
|
||||
"not_supported_error": "Source Not Supported",
|
||||
"playback_rate": "Playback rate",
|
||||
"playback_rate_current": "current playback rate",
|
||||
"playback_rate_value": "Playback rate {playbackRate}",
|
||||
"playback_time": "playback time",
|
||||
"quality": "Quality",
|
||||
"second": "second",
|
||||
"seconds": "seconds",
|
||||
"time_value_of_total_time": "{currentTime} of {totalTime}",
|
||||
"time_value_remaining": "{time} remaining",
|
||||
"unmute": "Unmute",
|
||||
"unsupported_error_description": "An unsupported error occurred. The server or network failed, or your browser does not support this format.",
|
||||
"video_not_loaded_unknown_time": "video not loaded, unknown time.",
|
||||
"video_player": "video player",
|
||||
"volume": "volume"
|
||||
},
|
||||
"media_type": "Media type",
|
||||
"memories": "Memories",
|
||||
"memories_all_caught_up": "All caught up",
|
||||
@@ -1762,7 +1794,6 @@
|
||||
"play_original_video": "Play original video",
|
||||
"play_original_video_setting_description": "Prefer playback of original videos rather than transcoded videos. If original asset is not compatible it may not playback correctly.",
|
||||
"play_transcoded_video": "Play transcoded video",
|
||||
"playback_speed": "Playback speed",
|
||||
"please_auth_to_access": "Please authenticate to access",
|
||||
"port": "Port",
|
||||
"preferences_settings_subtitle": "Manage the app's preferences",
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
import { assetViewerFadeDuration } from '$lib/constants';
|
||||
import { assetViewerManager } from '$lib/managers/asset-viewer-manager.svelte';
|
||||
import { castManager } from '$lib/managers/cast-manager.svelte';
|
||||
import { autoPlayVideo, loopVideo as loopVideoPreference } from '$lib/stores/preferences.store';
|
||||
import { autoPlayVideo, lang, loopVideo as loopVideoPreference } from '$lib/stores/preferences.store';
|
||||
import { getAssetMediaUrl, getAssetPlaybackUrl } from '$lib/utils';
|
||||
import { AssetMediaSize, type AssetResponseDto } from '@immich/sdk';
|
||||
import { Icon, LoadingSpinner } from '@immich/ui';
|
||||
@@ -166,6 +166,7 @@
|
||||
<!-- dir=ltr based on https://github.com/videojs/video.js/issues/949 -->
|
||||
<media-controller
|
||||
dir="ltr"
|
||||
lang={$lang}
|
||||
nohotkeys
|
||||
class="dark h-full max-w-full"
|
||||
style:aspect-ratio={aspectRatio}
|
||||
@@ -194,14 +195,14 @@
|
||||
></video>
|
||||
|
||||
{#if extendedControls}
|
||||
<media-settings-menu hidden anchor="auto" class="w-3xs rounded-xl border border-light-300 shadow-sm">
|
||||
<media-settings-menu hidden anchor="auto" class="min-w-3xs rounded-xl border border-light-300 shadow-sm">
|
||||
<Icon slot="checked-indicator" icon={mdiCheck} class="m-2" />
|
||||
<media-settings-menu-item class="mx-1 rounded-lg p-1 ps-2">
|
||||
{$t('playback_speed')}
|
||||
{$t('media_chrome.playback_rate')}
|
||||
<Icon slot="suffix" icon={mdiChevronRight} class="m-2" />
|
||||
<media-playback-rate-menu slot="submenu" hidden rates="0.5 1 1.5 2">
|
||||
<Icon slot="back-icon" icon={mdiChevronLeft} class="m-2" />
|
||||
<span slot="title">{$t('playback_speed')}</span>
|
||||
<span slot="title">{$t('media_chrome.playback_rate')}</span>
|
||||
</media-playback-rate-menu>
|
||||
</media-settings-menu-item>
|
||||
</media-settings-menu>
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
import { serverConfigManager } from '$lib/managers/server-config-manager.svelte';
|
||||
import ServerRestartingModal from '$lib/modals/ServerRestartingModal.svelte';
|
||||
import { Route } from '$lib/route';
|
||||
import { locale } from '$lib/stores/preferences.store';
|
||||
import { lang, locale } from '$lib/stores/preferences.store';
|
||||
import { sidebarStore } from '$lib/stores/sidebar.svelte';
|
||||
import { closeWebsocketConnection, openWebsocketConnection, websocketStore } from '$lib/stores/websocket';
|
||||
import { maintenanceShouldRedirect } from '$lib/utils/maintenance';
|
||||
@@ -35,6 +35,8 @@
|
||||
toastManager,
|
||||
TooltipProvider,
|
||||
} from '@immich/ui';
|
||||
import { En } from 'media-chrome/lang/en';
|
||||
import { addTranslation } from 'media-chrome/utils/i18n';
|
||||
import { onMount, type Snippet } from 'svelte';
|
||||
import { t } from 'svelte-i18n';
|
||||
import { get } from 'svelte/store';
|
||||
@@ -44,6 +46,38 @@
|
||||
children?: Snippet;
|
||||
}
|
||||
|
||||
const MediaChromeDefaultKeys = [
|
||||
'Start airplay',
|
||||
'Stop airplay',
|
||||
'Audio',
|
||||
'Start casting',
|
||||
'Stop casting',
|
||||
'Enter picture in picture mode',
|
||||
'Exit picture in picture mode',
|
||||
'Seek backward',
|
||||
'Seek forward',
|
||||
'audio player',
|
||||
'seek',
|
||||
'audio tracks',
|
||||
'chapter: {chapterName}',
|
||||
'live',
|
||||
'start airplay',
|
||||
'stop airplay',
|
||||
'start casting',
|
||||
'stop casting',
|
||||
'enter picture in picture mode',
|
||||
'exit picture in picture mode',
|
||||
'seek to live',
|
||||
'playing live',
|
||||
'seek back {seekOffset} seconds',
|
||||
'seek forward {seekOffset} seconds',
|
||||
'Encryption Error',
|
||||
'The media is encrypted and there are no keys to decrypt it.',
|
||||
] as const satisfies Array<keyof typeof En>;
|
||||
const MediaChromeDefaults = Object.fromEntries(MediaChromeDefaultKeys.map((key) => [key, key])) as {
|
||||
[K in (typeof MediaChromeDefaultKeys)[number]]: K;
|
||||
};
|
||||
|
||||
$effect(() => {
|
||||
setTranslations({
|
||||
cancel: $t('cancel'),
|
||||
@@ -73,6 +107,58 @@
|
||||
save: $t('save'),
|
||||
supporter: $t('supporter'),
|
||||
});
|
||||
|
||||
addTranslation($lang, {
|
||||
...MediaChromeDefaults,
|
||||
Captions: $t('media_chrome.captions'),
|
||||
'Enable captions': $t('media_chrome.enable_captions'),
|
||||
'Disable captions': $t('media_chrome.disable_captions'),
|
||||
'Enter fullscreen mode': $t('media_chrome.enter_fullscreen_mode'),
|
||||
'Exit fullscreen mode': $t('media_chrome.exit_fullscreen_mode'),
|
||||
Mute: $t('media_chrome.mute'),
|
||||
Unmute: $t('media_chrome.unmute'),
|
||||
Loop: $t('media_chrome.loop'),
|
||||
Play: $t('play'),
|
||||
Pause: $t('pause'),
|
||||
'Playback rate': $t('media_chrome.playback_rate'),
|
||||
'Playback rate {playbackRate}': $t('media_chrome.playback_rate_value'),
|
||||
Quality: $t('media_chrome.quality'),
|
||||
Settings: $t('settings'),
|
||||
Auto: $t('media_chrome.auto'),
|
||||
'video player': $t('media_chrome.video_player'),
|
||||
volume: $t('media_chrome.volume'),
|
||||
'closed captions': $t('media_chrome.closed_captions'),
|
||||
'current playback rate': $t('media_chrome.playback_rate_current'),
|
||||
'playback time': $t('media_chrome.playback_time'),
|
||||
'media loading': $t('media_chrome.media_loading'),
|
||||
settings: $t('settings'),
|
||||
quality: $t('media_chrome.quality'),
|
||||
play: $t('play'),
|
||||
pause: $t('pause'),
|
||||
mute: $t('media_chrome.mute'),
|
||||
unmute: $t('media_chrome.unmute'),
|
||||
Off: $t('media_chrome.captions_off'),
|
||||
'enter fullscreen mode': $t('media_chrome.enter_fullscreen_mode'),
|
||||
'exit fullscreen mode': $t('media_chrome.exit_fullscreen_mode'),
|
||||
'Network Error': $t('media_chrome.network_error'),
|
||||
'Decode Error': $t('media_chrome.decode_error'),
|
||||
'Source Not Supported': $t('media_chrome.not_supported_error'),
|
||||
'A network error caused the media download to fail.': $t('media_chrome.network_error_description'),
|
||||
'A media error caused playback to be aborted. The media could be corrupt or your browser does not support this format.':
|
||||
$t('media_chrome.media_error_description'),
|
||||
'An unsupported error occurred. The server or network failed, or your browser does not support this format.': $t(
|
||||
'media_chrome.unsupported_error_description',
|
||||
),
|
||||
hour: $t('hour'),
|
||||
hours: $t('hours'),
|
||||
minute: $t('minute'),
|
||||
minutes: $t('minutes'),
|
||||
second: $t('media_chrome.second'),
|
||||
seconds: $t('media_chrome.seconds'),
|
||||
'{time} remaining': $t('media_chrome.time_value_remaining'),
|
||||
'{currentTime} of {totalTime}': $t('media_chrome.time_value_of_total_time'),
|
||||
'video not loaded, unknown time.': $t('media_chrome.video_not_loaded_unknown_time'),
|
||||
});
|
||||
});
|
||||
|
||||
$effect(() => setLocale($locale));
|
||||
|
||||
Reference in New Issue
Block a user