feat: replace heart icons to thumbs-up across activity

This commit is contained in:
idubnori
2025-12-16 00:06:57 +09:00
parent 35eda735c8
commit 4568e55f3f
8 changed files with 19 additions and 19 deletions

View File

@@ -47,7 +47,7 @@ class LikeActivityActionButton extends ConsumerWidget {
return BaseActionButton( return BaseActionButton(
maxWidth: 60, maxWidth: 60,
iconData: liked != null ? Icons.favorite : Icons.favorite_border, iconData: liked != null ? Icons.thumb_up : Icons.thumb_up_off_alt,
label: "like".t(context: context), label: "like".t(context: context),
onPressed: () => onTap(liked), onPressed: () => onTap(liked),
iconOnly: iconOnly, iconOnly: iconOnly,
@@ -57,7 +57,7 @@ class LikeActivityActionButton extends ConsumerWidget {
// default to empty heart during loading // default to empty heart during loading
loading: () => BaseActionButton( loading: () => BaseActionButton(
iconData: Icons.favorite_border, iconData: Icons.thumb_up_off_alt,
label: "like".t(context: context), label: "like".t(context: context),
iconOnly: iconOnly, iconOnly: iconOnly,
menuItem: menuItem, menuItem: menuItem,

View File

@@ -68,11 +68,11 @@ class ActivityTextField extends HookConsumerWidget {
suffixIcon: Padding( suffixIcon: Padding(
padding: const EdgeInsets.only(right: 10), padding: const EdgeInsets.only(right: 10),
child: IconButton( child: IconButton(
icon: Icon(liked ? Icons.favorite_rounded : Icons.favorite_border_rounded), icon: Icon(liked ? Icons.thumb_up : Icons.thumb_up_off_alt),
onPressed: liked ? removeLike : addLike, onPressed: liked ? removeLike : addLike,
), ),
), ),
suffixIconColor: liked ? Colors.red[700] : null, suffixIconColor: liked ? Colors.blue[700] : null,
hintText: !isEnabled ? 'shared_album_activities_input_disable'.tr() : 'say_something'.tr(), hintText: !isEnabled ? 'shared_album_activities_input_disable'.tr() : 'say_something'.tr(),
hintStyle: TextStyle(fontWeight: FontWeight.normal, fontSize: 14, color: Colors.grey[600]), hintStyle: TextStyle(fontWeight: FontWeight.normal, fontSize: 14, color: Colors.grey[600]),
), ),

View File

@@ -37,7 +37,7 @@ class ActivityTile extends HookConsumerWidget {
? Container( ? Container(
width: isBottomSheet ? 30 : 44, width: isBottomSheet ? 30 : 44,
alignment: Alignment.center, alignment: Alignment.center,
child: Icon(Icons.favorite_rounded, color: Colors.red[700]), child: Icon(Icons.thumb_up, color: Colors.blue[700]),
) )
: isBottomSheet : isBottomSheet
? UserCircleAvatar(user: activity.user, size: 30, radius: 15) ? UserCircleAvatar(user: activity.user, size: 30, radius: 15)

View File

@@ -68,7 +68,7 @@ class CommentBubble extends ConsumerWidget {
child: Container( child: Container(
padding: const EdgeInsets.all(4), padding: const EdgeInsets.all(4),
decoration: BoxDecoration(color: Colors.white.withValues(alpha: 0.7), shape: BoxShape.circle), decoration: BoxDecoration(color: Colors.white.withValues(alpha: 0.7), shape: BoxShape.circle),
child: Icon(Icons.favorite, color: Colors.red[600], size: 18), child: Icon(Icons.thumb_up, color: Colors.blue[600], size: 18),
), ),
), ),
], ],
@@ -82,7 +82,7 @@ class CommentBubble extends ConsumerWidget {
likes = Container( likes = Container(
padding: const EdgeInsets.all(8), padding: const EdgeInsets.all(8),
decoration: BoxDecoration(color: Colors.white.withValues(alpha: 0.7), shape: BoxShape.circle), decoration: BoxDecoration(color: Colors.white.withValues(alpha: 0.7), shape: BoxShape.circle),
child: Icon(Icons.favorite, color: Colors.red[600], size: 18), child: Icon(Icons.thumb_up, color: Colors.blue[600], size: 18),
); );
} }

View File

@@ -77,15 +77,15 @@ void main() {
overrides: overrides, overrides: overrides,
); );
expect(find.widgetWithIcon(IconButton, Icons.favorite_rounded), findsOneWidget); expect(find.widgetWithIcon(IconButton, Icons.thumb_up), findsOneWidget);
expect(find.widgetWithIcon(IconButton, Icons.favorite_border_rounded), findsNothing); expect(find.widgetWithIcon(IconButton, Icons.thumb_up_off_alt), findsNothing);
}); });
testWidgets('Bordered icon if likedId == null', (tester) async { testWidgets('Bordered icon if likedId == null', (tester) async {
await tester.pumpConsumerWidget(ActivityTextField(onSubmit: (_) {}), overrides: overrides); await tester.pumpConsumerWidget(ActivityTextField(onSubmit: (_) {}), overrides: overrides);
expect(find.widgetWithIcon(IconButton, Icons.favorite_border_rounded), findsOneWidget); expect(find.widgetWithIcon(IconButton, Icons.thumb_up_off_alt), findsOneWidget);
expect(find.widgetWithIcon(IconButton, Icons.favorite_rounded), findsNothing); expect(find.widgetWithIcon(IconButton, Icons.thumb_up), findsNothing);
}); });
testWidgets('Adds new like', (tester) async { testWidgets('Adds new like', (tester) async {

View File

@@ -91,17 +91,17 @@ void main() {
group('Like Activity', () { group('Like Activity', () {
final activity = Activity(id: '1', createdAt: DateTime(100), type: ActivityType.like, user: UserStub.admin); final activity = Activity(id: '1', createdAt: DateTime(100), type: ActivityType.like, user: UserStub.admin);
testWidgets('Like contains filled heart as leading', (tester) async { testWidgets('Like contains filled thumbs-up as leading', (tester) async {
await tester.pumpConsumerWidget(ActivityTile(activity), overrides: overrides); await tester.pumpConsumerWidget(ActivityTile(activity), overrides: overrides);
// Leading widget should not be null // Leading widget should not be null
final listTile = tester.widget<ListTile>(find.byType(ListTile)); final listTile = tester.widget<ListTile>(find.byType(ListTile));
expect(listTile.leading, isNotNull); expect(listTile.leading, isNotNull);
// And should have a favorite icon // And should have a thumb_up icon
final favoIconFinder = find.widgetWithIcon(listTile.leading!.runtimeType, Icons.favorite_rounded); final thumbUpIconFinder = find.widgetWithIcon(listTile.leading!.runtimeType, Icons.thumb_up);
expect(favoIconFinder, findsOneWidget); expect(thumbUpIconFinder, findsOneWidget);
}); });
testWidgets('Like title is center aligned', (tester) async { testWidgets('Like title is center aligned', (tester) async {

View File

@@ -2,7 +2,7 @@
import { locale } from '$lib/stores/preferences.store'; import { locale } from '$lib/stores/preferences.store';
import type { ActivityResponseDto } from '@immich/sdk'; import type { ActivityResponseDto } from '@immich/sdk';
import { Icon } from '@immich/ui'; import { Icon } from '@immich/ui';
import { mdiCommentOutline, mdiHeart, mdiHeartOutline } from '@mdi/js'; import { mdiCommentOutline, mdiThumbUp, mdiThumbUpOutline } from '@mdi/js';
interface Props { interface Props {
isLiked: ActivityResponseDto | null; isLiked: ActivityResponseDto | null;
@@ -19,7 +19,7 @@
<div class="w-full flex p-4 items-center justify-center rounded-full gap-5 bg-subtle border bg-opacity-60"> <div class="w-full flex p-4 items-center justify-center rounded-full gap-5 bg-subtle border bg-opacity-60">
<button type="button" class={disabled ? 'cursor-not-allowed' : ''} onclick={onFavorite} {disabled}> <button type="button" class={disabled ? 'cursor-not-allowed' : ''} onclick={onFavorite} {disabled}>
<div class="flex gap-2 items-center justify-center"> <div class="flex gap-2 items-center justify-center">
<Icon icon={isLiked ? mdiHeart : mdiHeartOutline} size="24" class={isLiked ? 'text-red-400' : 'text-fg'} /> <Icon icon={isLiked ? mdiThumbUp : mdiThumbUpOutline} size="24" class={isLiked ? 'text-blue-400' : 'text-fg'} />
{#if numberOfLikes} {#if numberOfLikes}
<div class="text-l">{numberOfLikes.toLocaleString($locale)}</div> <div class="text-l">{numberOfLikes.toLocaleString($locale)}</div>
{/if} {/if}

View File

@@ -13,7 +13,7 @@
import { isTenMinutesApart } from '$lib/utils/timesince'; import { isTenMinutesApart } from '$lib/utils/timesince';
import { ReactionType, type ActivityResponseDto, type AssetTypeEnum, type UserResponseDto } from '@immich/sdk'; import { ReactionType, type ActivityResponseDto, type AssetTypeEnum, type UserResponseDto } from '@immich/sdk';
import { Icon, IconButton, LoadingSpinner, toastManager } from '@immich/ui'; import { Icon, IconButton, LoadingSpinner, toastManager } from '@immich/ui';
import { mdiClose, mdiDeleteOutline, mdiDotsVertical, mdiHeart, mdiSend } from '@mdi/js'; import { mdiClose, mdiDeleteOutline, mdiDotsVertical, mdiSend, mdiThumbUp } from '@mdi/js';
import * as luxon from 'luxon'; import * as luxon from 'luxon';
import { t } from 'svelte-i18n'; import { t } from 'svelte-i18n';
import UserAvatar from '../shared-components/user-avatar.svelte'; import UserAvatar from '../shared-components/user-avatar.svelte';
@@ -181,7 +181,7 @@
{:else if reaction.type === ReactionType.Like} {:else if reaction.type === ReactionType.Like}
<div class="relative"> <div class="relative">
<div class="flex py-3 ps-3 mt-3 gap-4 items-center text-sm"> <div class="flex py-3 ps-3 mt-3 gap-4 items-center text-sm">
<div class="text-red-600"><Icon icon={mdiHeart} size="20" /></div> <div class="text-blue-600"><Icon icon={mdiThumbUp} size="20" /></div>
<div class="w-full" title={`${reaction.user.name} (${reaction.user.email})`}> <div class="w-full" title={`${reaction.user.name} (${reaction.user.email})`}>
{$t('user_liked', { {$t('user_liked', {