mirror of
https://github.com/immich-app/immich
synced 2025-10-17 18:19:27 +00:00
feat: open asset from activities page on list tile tap
feat: remove autofocus on activity page open feat: made only activity tile thumbnail image tappable
This commit is contained in:
parent
8fe54a4de1
commit
aa7027bb95
2 changed files with 76 additions and 17 deletions
|
|
@ -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(),
|
||||
|
|
|
|||
|
|
@ -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<void> 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),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue