2022-11-19 05:00:17 +00:00
|
|
|
import 'package:flutter/material.dart';
|
2022-11-30 00:56:14 +00:00
|
|
|
import 'package:go_router/go_router.dart';
|
2023-03-11 18:40:36 +00:00
|
|
|
import 'package:logging/logging.dart';
|
2022-11-22 04:46:34 +00:00
|
|
|
import 'package:provider/provider.dart';
|
2023-04-20 20:26:11 +00:00
|
|
|
import 'package:result_monad/result_monad.dart';
|
2022-11-19 05:00:17 +00:00
|
|
|
|
2022-11-30 00:56:14 +00:00
|
|
|
import '../globals.dart';
|
2023-04-20 20:26:11 +00:00
|
|
|
import '../models/exec_error.dart';
|
2022-11-19 05:00:17 +00:00
|
|
|
import '../models/user_notification.dart';
|
2022-11-30 00:56:14 +00:00
|
|
|
import '../routes.dart';
|
2022-12-27 16:08:16 +00:00
|
|
|
import '../services/connections_manager.dart';
|
2022-11-22 04:46:34 +00:00
|
|
|
import '../services/notifications_manager.dart';
|
2022-11-30 00:56:14 +00:00
|
|
|
import '../services/timeline_manager.dart';
|
2023-03-14 03:47:40 +00:00
|
|
|
import '../utils/active_profile_selector.dart';
|
2022-11-19 05:00:17 +00:00
|
|
|
import '../utils/dateutils.dart';
|
2022-11-22 04:46:34 +00:00
|
|
|
import '../utils/snackbar_builder.dart';
|
2023-04-27 19:19:51 +00:00
|
|
|
import 'html_text_viewer_control.dart';
|
2022-12-30 15:55:05 +00:00
|
|
|
import 'image_control.dart';
|
2022-11-19 05:00:17 +00:00
|
|
|
|
|
|
|
class NotificationControl extends StatelessWidget {
|
2023-03-11 18:40:36 +00:00
|
|
|
static final _logger = Logger('$NotificationControl');
|
2022-11-19 05:00:17 +00:00
|
|
|
final UserNotification notification;
|
|
|
|
|
|
|
|
const NotificationControl({
|
|
|
|
super.key,
|
|
|
|
required this.notification,
|
|
|
|
});
|
|
|
|
|
2022-11-30 19:32:40 +00:00
|
|
|
Future<void> _goToStatus(BuildContext context) async {
|
2023-03-14 03:47:40 +00:00
|
|
|
final manager =
|
|
|
|
getIt<ActiveProfileSelector<TimelineManager>>().activeEntry.value;
|
2022-11-30 19:32:40 +00:00
|
|
|
final existingPostData = manager.getPostTreeEntryBy(notification.iid);
|
|
|
|
if (existingPostData.isSuccess) {
|
2023-01-15 15:39:05 +00:00
|
|
|
context
|
|
|
|
.push('/post/view/${existingPostData.value.id}/${notification.iid}');
|
2022-11-30 19:32:40 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
final loadedPost = await manager.refreshStatusChain(notification.iid);
|
|
|
|
if (loadedPost.isSuccess) {
|
2023-01-15 15:39:05 +00:00
|
|
|
context.push('/post/view/${loadedPost.value.id}/${notification.iid}');
|
2022-11-30 19:32:40 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
buildSnackbar(
|
|
|
|
context, 'Error getting data for notification: ${loadedPost.error}');
|
|
|
|
}
|
|
|
|
|
2022-11-19 05:00:17 +00:00
|
|
|
@override
|
|
|
|
Widget build(BuildContext context) {
|
2022-12-27 16:08:16 +00:00
|
|
|
const iconSize = 50.0;
|
2023-03-11 18:40:36 +00:00
|
|
|
final manager = context
|
|
|
|
.watch<ActiveProfileSelector<NotificationsManager>>()
|
|
|
|
.activeEntry
|
|
|
|
.fold(
|
|
|
|
onSuccess: (manager) => manager,
|
|
|
|
onError: (error) {
|
|
|
|
_logger.severe('Error getting notification manager: $error');
|
|
|
|
return null;
|
|
|
|
},
|
|
|
|
);
|
|
|
|
|
2023-03-12 01:50:31 +00:00
|
|
|
final fromIcon = getIt<ActiveProfileSelector<ConnectionsManager>>()
|
|
|
|
.activeEntry
|
|
|
|
.andThen((manager) => manager.getById(notification.fromId))
|
|
|
|
.fold(
|
|
|
|
onSuccess: (connection) => ImageControl(
|
|
|
|
imageUrl: connection.avatarUrl.toString(),
|
|
|
|
iconOverride: const Icon(Icons.person),
|
|
|
|
width: iconSize,
|
|
|
|
height: iconSize,
|
|
|
|
onTap: () async {
|
|
|
|
context.pushNamed(ScreenPaths.userProfile,
|
|
|
|
params: {'id': notification.fromId});
|
|
|
|
},
|
|
|
|
),
|
|
|
|
onError: (error) => GestureDetector(
|
|
|
|
onTap: () async {
|
|
|
|
context.pushNamed(ScreenPaths.userProfile,
|
|
|
|
params: {'id': notification.fromId});
|
|
|
|
},
|
|
|
|
child: const SizedBox(
|
|
|
|
width: iconSize,
|
|
|
|
height: iconSize,
|
|
|
|
child: Icon(Icons.person),
|
|
|
|
),
|
|
|
|
),
|
|
|
|
);
|
2022-12-29 14:33:22 +00:00
|
|
|
|
2023-01-23 21:25:14 +00:00
|
|
|
Function()? onTap;
|
|
|
|
switch (notification.type) {
|
|
|
|
case NotificationType.follow:
|
|
|
|
onTap = () {
|
|
|
|
context.pushNamed(ScreenPaths.userProfile,
|
|
|
|
params: {'id': notification.fromId});
|
|
|
|
};
|
|
|
|
break;
|
|
|
|
case NotificationType.follow_request:
|
|
|
|
onTap = () {
|
|
|
|
context.push('/connect/${notification.fromId}');
|
|
|
|
};
|
|
|
|
break;
|
|
|
|
case NotificationType.unknown:
|
|
|
|
buildSnackbar(context, 'Unknown message type, nothing to do');
|
|
|
|
break;
|
|
|
|
case NotificationType.favourite:
|
|
|
|
case NotificationType.mention:
|
|
|
|
case NotificationType.reshare:
|
|
|
|
case NotificationType.reblog:
|
|
|
|
case NotificationType.status:
|
|
|
|
onTap = () {
|
|
|
|
_goToStatus(context);
|
|
|
|
};
|
|
|
|
break;
|
2023-02-08 15:41:29 +00:00
|
|
|
case NotificationType.direct_message:
|
|
|
|
onTap = () => context.pushNamed(
|
|
|
|
ScreenPaths.thread,
|
|
|
|
queryParams: {'uri': notification.iid},
|
|
|
|
);
|
|
|
|
break;
|
2023-01-23 21:25:14 +00:00
|
|
|
}
|
|
|
|
|
2022-11-19 05:00:17 +00:00
|
|
|
return ListTile(
|
2022-11-30 00:56:14 +00:00
|
|
|
tileColor: notification.dismissed ? null : Colors.black12,
|
2022-12-30 15:55:05 +00:00
|
|
|
leading: fromIcon,
|
2022-11-30 00:56:14 +00:00
|
|
|
title: GestureDetector(
|
2023-01-23 21:25:14 +00:00
|
|
|
onTap: onTap == null ? null : () async => onTap!(),
|
2023-04-27 19:19:51 +00:00
|
|
|
child: HtmlTextViewerControl(
|
|
|
|
content: notification.content,
|
2023-01-23 21:25:14 +00:00
|
|
|
onTapUrl: onTap == null ? null : (_) async => onTap!(),
|
|
|
|
),
|
|
|
|
),
|
|
|
|
subtitle: GestureDetector(
|
|
|
|
onTap: onTap == null ? null : () async => onTap!(),
|
|
|
|
child: Text(
|
|
|
|
ElapsedDateUtils.epochSecondsToString(notification.timestamp),
|
|
|
|
),
|
2022-11-30 00:56:14 +00:00
|
|
|
),
|
2023-02-08 15:41:29 +00:00
|
|
|
trailing: notification.dismissed ||
|
|
|
|
notification.type == NotificationType.direct_message
|
2022-11-19 05:00:17 +00:00
|
|
|
? null
|
2022-11-22 04:46:34 +00:00
|
|
|
: IconButton(
|
2023-03-11 18:40:36 +00:00
|
|
|
onPressed: manager == null
|
|
|
|
? null
|
|
|
|
: () async {
|
2023-04-20 20:26:11 +00:00
|
|
|
await manager.markSeen(notification).withError((error) {
|
|
|
|
buildSnackbar(
|
|
|
|
context, 'Error marking notification: $error');
|
|
|
|
logError(error, _logger);
|
|
|
|
});
|
2023-03-11 18:40:36 +00:00
|
|
|
},
|
2022-11-22 04:46:34 +00:00
|
|
|
icon: Icon(Icons.close_rounded)),
|
2022-11-19 05:00:17 +00:00
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|