mirror of
https://github.com/immich-app/immich.git
synced 2026-05-22 15:42:32 -04:00
refactor: yeet old timeline (#27666)
* refactor: yank old timeline # Conflicts: # mobile/lib/presentation/pages/editing/drift_edit.page.dart # mobile/lib/providers/websocket.provider.dart # mobile/lib/routing/router.dart * more cleanup * remove native code * chore: bump sqlite-data version * remove old background tasks from BGTaskSchedulerPermittedIdentifiers * rebase --------- Co-authored-by: shenlong-tanwen <139912620+shalong-tanwen@users.noreply.github.com>
This commit is contained in:
@@ -1,85 +0,0 @@
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:immich_mobile/extensions/build_context_extensions.dart';
|
||||
import 'package:immich_mobile/providers/activity.provider.dart';
|
||||
import 'package:immich_mobile/providers/album/current_album.provider.dart';
|
||||
import 'package:immich_mobile/providers/asset_viewer/current_asset.provider.dart';
|
||||
import 'package:immich_mobile/providers/user.provider.dart';
|
||||
import 'package:immich_mobile/widgets/common/user_circle_avatar.dart';
|
||||
|
||||
class ActivityTextField extends HookConsumerWidget {
|
||||
final bool isEnabled;
|
||||
final String? likeId;
|
||||
final Function(String) onSubmit;
|
||||
|
||||
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 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);
|
||||
inputController.clear();
|
||||
inputFocusNode.unfocus();
|
||||
}
|
||||
|
||||
Future<void> addLike() async {
|
||||
await activityNotifier.addLike();
|
||||
}
|
||||
|
||||
Future<void> removeLike() async {
|
||||
if (liked) {
|
||||
await activityNotifier.removeActivity(likeId!);
|
||||
}
|
||||
}
|
||||
|
||||
return Padding(
|
||||
padding: const EdgeInsets.only(bottom: 10),
|
||||
child: TextField(
|
||||
controller: inputController,
|
||||
enabled: isEnabled,
|
||||
focusNode: inputFocusNode,
|
||||
textInputAction: TextInputAction.send,
|
||||
autofocus: false,
|
||||
decoration: InputDecoration(
|
||||
border: InputBorder.none,
|
||||
focusedBorder: InputBorder.none,
|
||||
prefixIcon: user != null
|
||||
? Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 15),
|
||||
child: UserCircleAvatar(user: user, size: 30),
|
||||
)
|
||||
: null,
|
||||
suffixIcon: Padding(
|
||||
padding: const EdgeInsets.only(right: 10),
|
||||
child: IconButton(
|
||||
icon: Icon(liked ? Icons.thumb_up : Icons.thumb_up_off_alt),
|
||||
onPressed: liked ? removeLike : addLike,
|
||||
),
|
||||
),
|
||||
suffixIconColor: liked ? context.primaryColor : null,
|
||||
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,113 +0,0 @@
|
||||
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/presentation/widgets/images/remote_image_provider.dart';
|
||||
import 'package:immich_mobile/providers/activity_service.provider.dart';
|
||||
import 'package:immich_mobile/providers/asset_viewer/current_asset.provider.dart';
|
||||
import 'package:immich_mobile/widgets/common/user_circle_avatar.dart';
|
||||
|
||||
class ActivityTile extends HookConsumerWidget {
|
||||
final Activity activity;
|
||||
final bool isBottomSheet;
|
||||
|
||||
const ActivityTile(this.activity, {super.key, this.isBottomSheet = false});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final asset = ref.watch(currentAssetProvider);
|
||||
final isLike = activity.type == ActivityType.like;
|
||||
// Asset thumbnail is displayed when we are accessing activities from the album page
|
||||
// currentAssetProvider will not be set until we open the gallery viewer
|
||||
final showAssetThumbnail = asset == null && activity.assetId != null && !isBottomSheet;
|
||||
|
||||
onTap() async {
|
||||
final activityService = ref.read(activityServiceProvider);
|
||||
final route = await activityService.buildAssetViewerRoute(activity.assetId!, ref);
|
||||
if (route != null) {
|
||||
await context.pushRoute(route);
|
||||
}
|
||||
}
|
||||
|
||||
return ListTile(
|
||||
minVerticalPadding: 15,
|
||||
leading: isLike
|
||||
? Container(
|
||||
width: isBottomSheet ? 30 : 44,
|
||||
alignment: Alignment.center,
|
||||
child: Icon(Icons.thumb_up, color: context.primaryColor),
|
||||
)
|
||||
: isBottomSheet
|
||||
? UserCircleAvatar(user: activity.user, size: 30)
|
||||
: UserCircleAvatar(user: activity.user),
|
||||
title: _ActivityTitle(
|
||||
userName: activity.user.name,
|
||||
createdAt: activity.createdAt.timeAgo(),
|
||||
leftAlign: isBottomSheet ? false : (isLike || showAssetThumbnail),
|
||||
),
|
||||
// No subtitle for like, so center title
|
||||
titleAlignment: !isLike ? ListTileTitleAlignment.top : ListTileTitleAlignment.center,
|
||||
trailing: showAssetThumbnail ? _ActivityAssetThumbnail(activity.assetId!, onTap) : null,
|
||||
subtitle: !isLike ? Text(activity.comment!) : null,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _ActivityTitle extends StatelessWidget {
|
||||
final String userName;
|
||||
final String createdAt;
|
||||
final bool 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));
|
||||
|
||||
return Row(
|
||||
mainAxisAlignment: leftAlign ? MainAxisAlignment.start : MainAxisAlignment.spaceBetween,
|
||||
mainAxisSize: leftAlign ? MainAxisSize.min : MainAxisSize.max,
|
||||
children: [
|
||||
Text(userName, style: textStyle, overflow: TextOverflow.ellipsis),
|
||||
if (leftAlign) Text(" • ", style: textStyle),
|
||||
Expanded(
|
||||
child: Text(
|
||||
createdAt,
|
||||
style: textStyle,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
textAlign: leftAlign ? TextAlign.left : TextAlign.right,
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _ActivityAssetThumbnail extends StatelessWidget {
|
||||
final String assetId;
|
||||
final GestureTapCallback? onTap;
|
||||
|
||||
const _ActivityAssetThumbnail(this.assetId, this.onTap);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return GestureDetector(
|
||||
onTap: onTap,
|
||||
child: Container(
|
||||
width: 40,
|
||||
height: 30,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: const BorderRadius.all(Radius.circular(4)),
|
||||
image: DecorationImage(
|
||||
image: RemoteImageProvider.thumbnail(assetId: assetId, thumbhash: ""),
|
||||
fit: BoxFit.cover,
|
||||
),
|
||||
),
|
||||
child: const SizedBox.shrink(),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,6 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:immich_mobile/widgets/activities/activity_tile.dart';
|
||||
import 'package:immich_mobile/widgets/common/confirm_dialog.dart';
|
||||
|
||||
/// Wraps an [ActivityTile] and makes it dismissible
|
||||
class DismissibleActivity extends StatelessWidget {
|
||||
final String activityId;
|
||||
final Widget body;
|
||||
|
||||
Reference in New Issue
Block a user