diff --git a/mobile/lib/widgets/activities/activity_text_field.dart b/mobile/lib/widgets/activities/activity_text_field.dart index e3958b6287..7644167a23 100644 --- a/mobile/lib/widgets/activities/activity_text_field.dart +++ b/mobile/lib/widgets/activities/activity_text_field.dart @@ -13,24 +13,25 @@ class ActivityTextField extends HookConsumerWidget { final String? likeId; final Function(String) onSubmit; - const ActivityTextField({required this.onSubmit, this.isEnabled = true, this.likeId, super.key}); + const ActivityTextField({ + required this.onSubmit, + this.isEnabled = true, + this.likeId, + super.key, + }); @override Widget build(BuildContext context, WidgetRef ref) { final album = ref.watch(currentAlbumProvider)!; final asset = ref.watch(currentAssetProvider); - final activityNotifier = ref.read(albumActivityProvider(album.remoteId!, asset?.remoteId).notifier); + final activityNotifier = ref.read( + albumActivityProvider(album.remoteId!, asset?.remoteId).notifier, + ); final user = ref.watch(currentUserProvider); final inputController = useTextEditingController(); final inputFocusNode = useFocusNode(); final liked = likeId != null; - // Show keyboard immediately on activities open - useEffect(() { - inputFocusNode.requestFocus(); - return null; - }, []); - // Pass text to callback and reset controller void onEditingComplete() { onSubmit(inputController.text); @@ -68,13 +69,21 @@ class ActivityTextField extends HookConsumerWidget { suffixIcon: Padding( padding: const EdgeInsets.only(right: 10), child: IconButton( - icon: Icon(liked ? Icons.favorite_rounded : Icons.favorite_border_rounded), + icon: Icon( + liked ? Icons.favorite_rounded : Icons.favorite_border_rounded, + ), onPressed: liked ? removeLike : addLike, ), ), suffixIconColor: liked ? Colors.red[700] : null, - hintText: !isEnabled ? 'shared_album_activities_input_disable'.tr() : 'say_something'.tr(), - hintStyle: TextStyle(fontWeight: FontWeight.normal, fontSize: 14, color: Colors.grey[600]), + hintText: !isEnabled + ? 'shared_album_activities_input_disable'.tr() + : 'say_something'.tr(), + hintStyle: TextStyle( + fontWeight: FontWeight.normal, + fontSize: 14, + color: Colors.grey[600], + ), ), onEditingComplete: onEditingComplete, onTapOutside: (_) => inputFocusNode.unfocus(), diff --git a/mobile/lib/widgets/activities/activity_tile.dart b/mobile/lib/widgets/activities/activity_tile.dart index 4b66bd5eaf..1c13ba9b17 100644 --- a/mobile/lib/widgets/activities/activity_tile.dart +++ b/mobile/lib/widgets/activities/activity_tile.dart @@ -1,10 +1,15 @@ +import 'package:auto_route/auto_route.dart'; import 'package:flutter/material.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:immich_mobile/extensions/build_context_extensions.dart'; import 'package:immich_mobile/extensions/datetime_extensions.dart'; import 'package:immich_mobile/models/activities/activity.model.dart'; -import 'package:immich_mobile/providers/image/immich_remote_thumbnail_provider.dart'; import 'package:immich_mobile/providers/asset_viewer/current_asset.provider.dart'; +import 'package:immich_mobile/providers/asset_viewer/show_controls.provider.dart'; +import 'package:immich_mobile/providers/image/immich_remote_thumbnail_provider.dart'; +import 'package:immich_mobile/repositories/asset.repository.dart'; +import 'package:immich_mobile/routing/router.dart'; +import 'package:immich_mobile/widgets/asset_grid/asset_grid_data_structure.dart'; import 'package:immich_mobile/widgets/common/user_circle_avatar.dart'; class ActivityTile extends HookConsumerWidget { @@ -14,6 +19,36 @@ class ActivityTile extends HookConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { + Future onTap() async { + if (activity.assetId == null) { + return; + } + + final asset = await ref + .read(assetRepositoryProvider) + .getByRemoteId(activity.assetId!); + if (asset == null) { + return; + } + + final renderList = await RenderList.fromAssets([ + asset, + ], GroupAssetsBy.none); + final assetNotifier = ref.read(currentAssetProvider.notifier); + assetNotifier.set(asset); + if (asset.isVideo) { + ref.read(showControlsProvider.notifier).show = false; + } + await context.pushRoute( + GalleryViewerRoute( + initialIndex: 0, + heroOffset: 0, + renderList: renderList, + ), + ); + assetNotifier.set(null); + } + final asset = ref.watch(currentAssetProvider); final isLike = activity.type == ActivityType.like; // Asset thumbnail is displayed when we are accessing activities from the album page @@ -35,8 +70,15 @@ class ActivityTile extends HookConsumerWidget { leftAlign: isLike || showAssetThumbnail, ), // No subtitle for like, so center title - titleAlignment: !isLike ? ListTileTitleAlignment.top : ListTileTitleAlignment.center, - trailing: showAssetThumbnail ? _ActivityAssetThumbnail(activity.assetId!) : null, + titleAlignment: !isLike + ? ListTileTitleAlignment.top + : ListTileTitleAlignment.center, + trailing: showAssetThumbnail + ? GestureDetector( + onTap: onTap, + child: _ActivityAssetThumbnail(activity.assetId!), + ) + : null, subtitle: !isLike ? Text(activity.comment!) : null, ); } @@ -47,15 +89,23 @@ class _ActivityTitle extends StatelessWidget { final String createdAt; final bool leftAlign; - const _ActivityTitle({required this.userName, required this.createdAt, required this.leftAlign}); + const _ActivityTitle({ + required this.userName, + required this.createdAt, + required this.leftAlign, + }); @override Widget build(BuildContext context) { final textColor = context.isDarkTheme ? Colors.white : Colors.black; - final textStyle = context.textTheme.bodyMedium?.copyWith(color: textColor.withValues(alpha: 0.6)); + final textStyle = context.textTheme.bodyMedium?.copyWith( + color: textColor.withValues(alpha: 0.6), + ); return Row( - mainAxisAlignment: leftAlign ? MainAxisAlignment.start : MainAxisAlignment.spaceBetween, + mainAxisAlignment: leftAlign + ? MainAxisAlignment.start + : MainAxisAlignment.spaceBetween, mainAxisSize: leftAlign ? MainAxisSize.min : MainAxisSize.max, children: [ Text(userName, style: textStyle, overflow: TextOverflow.ellipsis),