Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(web): Add Partner Sharing Avatars to Timeline and Info Cards #12413

Open
wants to merge 13 commits into
base: main
Choose a base branch
from
3 changes: 3 additions & 0 deletions i18n/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -843,6 +843,7 @@
"main_branch_warning": "You’re using a development version; we strongly recommend using a release version!",
"make": "Make",
"manage_shared_links": "Manage shared links",
"manage_sharing": "Manage sharing settings",
"manage_sharing_with_partners": "Manage sharing with partners",
"manage_the_app_settings": "Manage the app settings",
"manage_your_account": "Manage your account",
Expand Down Expand Up @@ -1182,6 +1183,8 @@
"show_slideshow_transition": "Show slideshow transition",
"show_supporter_badge": "Supporter badge",
"show_supporter_badge_description": "Show a supporter badge",
"show_user_thumbnails": "Show user thumbnails",
"show_user_thumbnails_description": "Show user avatars on timeline for shared albums and partners",
"shuffle": "Shuffle",
"sidebar": "Sidebar",
"sidebar_display_description": "Display a link to the view in the sidebar",
Expand Down
139 changes: 93 additions & 46 deletions mobile/pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.0.3"
chewie:
dependency: "direct main"
description:
name: chewie
sha256: "2243e41e79e865d426d9dd9c1a9624aa33c4ad11de2d0cd680f826e2cd30e879"
url: "https://pub.dev"
source: hosted
version: "1.8.3"
ci:
dependency: transitive
description:
Expand Down Expand Up @@ -310,6 +318,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.0.0"
cupertino_icons:
dependency: transitive
description:
name: cupertino_icons
sha256: ba631d1c7f7bef6b729a622b7b752645a2d076dba9976925b8f25725a30e1ee6
url: "https://pub.dev"
source: hosted
version: "1.0.8"
custom_lint:
dependency: "direct dev"
description:
Expand Down Expand Up @@ -362,10 +378,10 @@ packages:
dependency: "direct main"
description:
name: device_info_plus
sha256: f545ffbadee826f26f2e1a0f0cbd667ae9a6011cc0f77c0f8f00a969655e6e95
sha256: db03b2d2a3fa466a4627709e1db58692c3f7f658e36a5942d342d86efedc4091
url: "https://pub.dev"
source: hosted
version: "11.1.1"
version: "11.0.0"
device_info_plus_platform_interface:
dependency: transitive
description:
Expand Down Expand Up @@ -434,10 +450,10 @@ packages:
dependency: "direct main"
description:
name: file_picker
sha256: aac85f20436608e01a6ffd1fdd4e746a7f33c93a2c83752e626bdfaea139b877
sha256: "167bb619cdddaa10ef2907609feb8a79c16dfa479d3afaf960f8e223f754bf12"
url: "https://pub.dev"
source: hosted
version: "8.1.3"
version: "8.1.2"
file_selector_linux:
dependency: transitive
description:
Expand Down Expand Up @@ -606,10 +622,10 @@ packages:
dependency: "direct main"
description:
name: flutter_web_auth
sha256: "95e4856e24fb6ac1678f5ff334743b63f782d839ab324543d29ccbd295176209"
sha256: a69fa8f43b9e4d86ac72176bf747b735e7b977dd7cf215076d95b87cb05affdd
url: "https://pub.dev"
source: hosted
version: "0.6.0"
version: "0.5.0"
flutter_web_plugins:
dependency: transitive
description: flutter
Expand Down Expand Up @@ -860,26 +876,26 @@ packages:
dependency: "direct main"
description:
name: isar
sha256: e17a9555bc7f22ff26568b8c64d019b4ffa2dc6bd4cb1c8d9b269aefd32e53ad
url: "https://pub.isar-community.dev"
sha256: "99165dadb2cf2329d3140198363a7e7bff9bbd441871898a87e26914d25cf1ea"
url: "https://pub.dev"
source: hosted
version: "3.1.8"
version: "3.1.0+1"
isar_flutter_libs:
dependency: "direct main"
description:
name: isar_flutter_libs
sha256: "78710781e658ce4bff59b3f38c5b2735e899e627f4e926e1221934e77b95231a"
url: "https://pub.isar-community.dev"
sha256: bc6768cc4b9c61aabff77152e7f33b4b17d2fc93134f7af1c3dd51500fe8d5e8
url: "https://pub.dev"
source: hosted
version: "3.1.8"
version: "3.1.0+1"
isar_generator:
dependency: "direct dev"
description:
name: isar_generator
sha256: "484e73d3b7e81dbd816852fe0b9497333118a9aeb646fd2d349a62cc8980ffe1"
url: "https://pub.isar-community.dev"
sha256: "76c121e1295a30423604f2f819bc255bc79f852f3bc8743a24017df6068ad133"
url: "https://pub.dev"
source: hosted
version: "3.1.8"
version: "3.1.0+1"
js:
dependency: transitive
description:
Expand Down Expand Up @@ -1008,31 +1024,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.0.4"
native_video_player:
dependency: "direct main"
description:
path: "."
ref: ac78487
resolved-ref: ac78487b9a87c9e72cd15b428270a905ac551f29
url: "https://github.com/immich-app/native_video_player"
source: git
version: "1.3.1"
network_info_plus:
dependency: "direct main"
description:
name: network_info_plus
sha256: bf9e39e523e9951d741868dc33ac386b0bc24301e9b7c8a7d60dbc34879150a8
url: "https://pub.dev"
source: hosted
version: "6.1.1"
network_info_plus_platform_interface:
nested:
dependency: transitive
description:
name: network_info_plus_platform_interface
sha256: b7f35f4a7baef511159e524499f3c15464a49faa5ec10e92ee0bce265e664906
name: nested
sha256: "03bac4c528c64c95c722ec99280375a6f2fc708eec17c7b3f07253b626cd2a20"
url: "https://pub.dev"
source: hosted
version: "2.0.1"
version: "1.0.0"
nm:
dependency: transitive
description:
Expand Down Expand Up @@ -1068,10 +1067,10 @@ packages:
dependency: "direct main"
description:
name: package_info_plus
sha256: da8d9ac8c4b1df253d1a328b7bf01ae77ef132833479ab40763334db13b91cce
sha256: "894f37107424311bdae3e476552229476777b8752c5a2a2369c0cb9a2d5442ef"
url: "https://pub.dev"
source: hosted
version: "8.1.1"
version: "8.0.3"
package_info_plus_platform_interface:
dependency: transitive
description:
Expand Down Expand Up @@ -1212,18 +1211,18 @@ packages:
dependency: "direct main"
description:
name: photo_manager
sha256: f5ef2618870e9a50d8bfeb81a02c242d580ae8614bd5ea9e1b80dbb7e49d4260
sha256: "32a1ce1095aeaaa792a29f28c1f74613aa75109f21c2d4ab85be3ad9964230a4"
url: "https://pub.dev"
source: hosted
version: "3.6.1"
version: "3.5.0"
photo_manager_image_provider:
dependency: "direct main"
description:
name: photo_manager_image_provider
sha256: b6015b67b32f345f57cf32c126f871bced2501236c405aafaefa885f7c821e4f
sha256: "38ef1023dc11de3a8669f16e7c981673b3c5cfee715d17120f4b87daa2cdd0af"
url: "https://pub.dev"
source: hosted
version: "2.2.0"
version: "2.1.1"
platform:
dependency: transitive
description:
Expand Down Expand Up @@ -1256,6 +1255,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "5.0.2"
provider:
dependency: transitive
description:
name: provider
sha256: c8a055ee5ce3fd98d6fc872478b03823ffdb448699c6ebdbbc71d59b596fd48c
url: "https://pub.dev"
source: hosted
version: "6.1.2"
pub_semver:
dependency: transitive
description:
Expand Down Expand Up @@ -1332,10 +1339,10 @@ packages:
dependency: "direct main"
description:
name: share_plus
sha256: "9c9bafd4060728d7cdb2464c341743adbd79d327cb067ec7afb64583540b47c8"
sha256: fec12c3c39f01e4df1ec6ad92b6e85503c5ca64ffd6e28d18c9ffe53fcc4cb11
url: "https://pub.dev"
source: hosted
version: "10.1.2"
version: "10.0.3"
share_plus_platform_interface:
dependency: transitive
description:
Expand Down Expand Up @@ -1701,6 +1708,46 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.1.4"
video_player:
dependency: "direct main"
description:
name: video_player
sha256: e30df0d226c4ef82e2c150ebf6834b3522cf3f654d8e2f9419d376cdc071425d
url: "https://pub.dev"
source: hosted
version: "2.9.1"
video_player_android:
dependency: transitive
description:
name: video_player_android
sha256: "4de50df9ee786f5891d3281e1e633d7b142ef1acf47392592eb91cba5d355849"
url: "https://pub.dev"
source: hosted
version: "2.6.0"
video_player_avfoundation:
dependency: transitive
description:
name: video_player_avfoundation
sha256: d1e9a824f2b324000dc8fb2dcb2a3285b6c1c7c487521c63306cc5b394f68a7c
url: "https://pub.dev"
source: hosted
version: "2.6.1"
video_player_platform_interface:
dependency: transitive
description:
name: video_player_platform_interface
sha256: "236454725fafcacf98f0f39af0d7c7ab2ce84762e3b63f2cbb3ef9a7e0550bc6"
url: "https://pub.dev"
source: hosted
version: "6.2.2"
video_player_web:
dependency: transitive
description:
name: video_player_web
sha256: "6dcdd298136523eaf7dfc31abaf0dfba9aa8a8dbc96670e87e9d42b6f2caf774"
url: "https://pub.dev"
source: hosted
version: "2.3.2"
vm_service:
dependency: transitive
description:
Expand Down Expand Up @@ -1814,5 +1861,5 @@ packages:
source: hosted
version: "3.1.2"
sdks:
dart: ">=3.5.3 <4.0.0"
flutter: ">=3.24.5"
dart: ">=3.5.0 <4.0.0"
flutter: ">=3.24.3"
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
import { canCopyImageToClipboard } from '$lib/utils/asset-utils';
import { t } from 'svelte-i18n';
import type { Snippet } from 'svelte';
import UserAvatar from '$lib/components/shared-components/user-avatar.svelte';

interface Props {
asset: AssetResponseDto;
Expand Down Expand Up @@ -104,6 +105,11 @@
class="flex w-[calc(100%-3rem)] justify-end gap-2 overflow-hidden text-white"
data-testid="asset-viewer-navbar-actions"
>
{#if asset.owner && asset.owner.id !== $user.id}
<div class="p-3 margin:auto">
<UserAvatar user={asset.owner} size="xs"></UserAvatar>
</div>
{/if}
{#if !asset.isTrashed && $user}
<ShareAction {asset} />
{/if}
Expand Down Expand Up @@ -146,7 +152,6 @@
title={$t('editor')}
/>
{/if} -->

{#if isOwner}
<DeleteAction {asset} {onAction} />

Expand Down
8 changes: 6 additions & 2 deletions web/src/lib/components/asset-viewer/detail-panel.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -470,9 +470,13 @@
</div>
{/if}

{#if currentAlbum && currentAlbum.albumUsers.length > 0 && asset.owner}
{#if asset.owner && (asset.ownerId != $user?.id || $user === undefined)}
<section class="px-6 dark:text-immich-dark-fg mt-4">
<p class="text-sm">{$t('shared_by').toUpperCase()}</p>
{#if currentAlbum}
<p class="text-sm">{$t('shared_by').toUpperCase()}</p>
{:else}
<p class="text-sm">{$t('partner_sharing').toUpperCase()}</p>
{/if}
<div class="flex gap-4 pt-4">
<div>
<UserAvatar user={asset.owner} size="md" />
Expand Down
27 changes: 26 additions & 1 deletion web/src/lib/components/assets/thumbnail/thumbnail.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,13 @@
import Icon from '$lib/components/elements/icon.svelte';
import { ProjectionType } from '$lib/constants';
import { getAssetThumbnailUrl, isSharedLink } from '$lib/utils';
import { handleError } from '$lib/utils/handle-error';
import { getAltText } from '$lib/utils/thumbnail-util';
import { timeToSeconds } from '$lib/utils/date-time';
import { user } from '$lib/stores/user.store';
import { AssetMediaSize, AssetTypeEnum, type AssetResponseDto } from '@immich/sdk';
import { locale, playVideoThumbnailOnHover } from '$lib/stores/preferences.store';
import { locale, playVideoThumbnailOnHover, showUserThumbnails } from '$lib/stores/preferences.store';
import { getUserAndCacheResult } from '$lib/utils/users';
import { getAssetPlaybackUrl } from '$lib/utils';
import {
mdiArchiveArrowDownOutline,
Expand All @@ -19,6 +22,7 @@
} from '@mdi/js';

import { fade } from 'svelte/transition';
import { t } from 'svelte-i18n';
import ImageThumbnail from './image-thumbnail.svelte';
import VideoThumbnail from './video-thumbnail.svelte';
import { currentUrlReplaceAssetId } from '$lib/utils/navigation';
Expand All @@ -30,6 +34,7 @@
import { onDestroy } from 'svelte';
import { TUNABLES } from '$lib/utils/tunables';
import { thumbhash } from '$lib/actions/thumbhash';
import UserAvatar from '$lib/components/shared-components/user-avatar.svelte';

interface Props {
asset: AssetResponseDto;
Expand Down Expand Up @@ -61,6 +66,7 @@
onSelect?: ((asset: AssetResponseDto) => void) | undefined;
onMouseEvent?: ((event: { isMouseOver: boolean; selectedGroupIndex: number }) => void) | undefined;
class?: string;
showOwnerAvatar?: boolean;
}

let {
Expand All @@ -86,6 +92,7 @@
onSelect = undefined,
onMouseEvent = undefined,
class: className = '',
showOwnerAvatar = false,
}: Props = $props();

let {
Expand Down Expand Up @@ -187,6 +194,14 @@
}
};

const getShareUser = async () => {
try {
return await getUserAndCacheResult(asset.ownerId);
} catch (error) {
handleError(error, $t('errors.failed_to_load_people'));
}
};

onDestroy(() => {
assetStore?.taskManager.removeAllTasksForComponent(componentId);
});
Expand Down Expand Up @@ -297,6 +312,16 @@
</div>
{/if}

{#if showOwnerAvatar && $showUserThumbnails && (isSharedLink() || asset.ownerId != $user.id)}
{#await getShareUser() then shareUser}
{#if shareUser}
<div class="absolute bottom-2 left-2 z-10">
<UserAvatar user={shareUser} size="sm" />
</div>
{/if}
{/await}
{/if}

{#if !isSharedLink() && showArchiveIcon && asset.isArchived}
<div class="absolute {asset.isFavorite ? 'bottom-10' : 'bottom-2'} left-2 z-10">
<Icon path={mdiArchiveArrowDownOutline} size="24" class="text-white" />
Expand Down
Loading
Loading