working jumps from notif page
Doesn't work from notif page pushed from notif controller
This commit is contained in:
parent
9f070fcdba
commit
c90a1c41b0
6 changed files with 136 additions and 57 deletions
|
|
@ -37,6 +37,7 @@ class NotificationController
|
|||
MaterialPageRoute(
|
||||
builder: (_) => NotificationsPage(
|
||||
highlightedEventId: eventId,
|
||||
jumpToEvent: (eventId) {},
|
||||
defaultToAllNotifications: true,
|
||||
),
|
||||
),
|
||||
|
|
@ -62,6 +63,7 @@ class NotificationController
|
|||
MaterialPageRoute(
|
||||
builder: (_) => NotificationsPage(
|
||||
highlightedEventId: eventId,
|
||||
jumpToEvent: (eventId) {},
|
||||
defaultToAllNotifications: true,
|
||||
),
|
||||
),
|
||||
|
|
|
|||
|
|
@ -68,6 +68,14 @@ final class ChatScroll({
|
|||
if (found || controllerData is AsyncError) {
|
||||
if (found) {
|
||||
anchorId.value = target;
|
||||
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
final context = keyFor(target).currentContext;
|
||||
if (context != null && context.mounted) {
|
||||
anchorMountedCompleter.value?.complete(context);
|
||||
anchorMountedCompleter.value = null;
|
||||
}
|
||||
});
|
||||
} else {
|
||||
anchorMountedCompleter.value?.completeError(
|
||||
StateError("Failed to load context for $target"),
|
||||
|
|
@ -80,21 +88,6 @@ final class ChatScroll({
|
|||
return null;
|
||||
}, [controllerData, pendingAnchorTarget.value]);
|
||||
|
||||
useEffect(() {
|
||||
final completer = anchorMountedCompleter.value;
|
||||
if (completer == null) return null;
|
||||
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
final context = keyFor(anchorId.value!).currentContext;
|
||||
if (context != null && context.mounted) {
|
||||
anchorMountedCompleter.value?.complete(context);
|
||||
anchorMountedCompleter.value = null;
|
||||
}
|
||||
});
|
||||
|
||||
return null;
|
||||
}, [anchorId.value]);
|
||||
|
||||
final ({IList<Event> history, IList<Event> live}) split = useMemoized(() {
|
||||
final items = controllerData.value?.timeline;
|
||||
final anchor = anchorId.value;
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
import "package:flutter_hooks/flutter_hooks.dart";
|
||||
import "package:material_ui/material_ui.dart";
|
||||
import "package:hooks_riverpod/hooks_riverpod.dart";
|
||||
import "package:nexus/controllers/init_complete.dart";
|
||||
|
|
@ -7,9 +8,12 @@ import "package:nexus/widgets/sidebar.dart";
|
|||
import "package:nexus/widgets/room_chat/room_chat.dart";
|
||||
import "package:nexus/widgets/loading.dart";
|
||||
|
||||
class const ChatPage({super.key}) extends ConsumerWidget {
|
||||
class const ChatPage({super.key}) extends HookConsumerWidget {
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) => LayoutBuilder(
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final initialHighlightedEvent = useState<String?>(null);
|
||||
|
||||
return LayoutBuilder(
|
||||
builder: (context, constraints) {
|
||||
final isDesktop = constraints.maxWidth > 650;
|
||||
final showMembersByDefault = constraints.maxWidth > 1000;
|
||||
|
|
@ -24,13 +28,23 @@ class const ChatPage({super.key}) extends ConsumerWidget {
|
|||
body: initComplete
|
||||
? Row(
|
||||
children: [
|
||||
if (isDesktop) Sidebar(isDesktop: isDesktop),
|
||||
if (isDesktop)
|
||||
Sidebar(
|
||||
isDesktop: isDesktop,
|
||||
jumpToEvent: (eventId) =>
|
||||
initialHighlightedEvent.value = eventId,
|
||||
),
|
||||
Expanded(
|
||||
child: RoomChat(
|
||||
key: ValueKey(roomId),
|
||||
key: ValueKey((
|
||||
roomId,
|
||||
initialHighlightedEvent.value,
|
||||
)),
|
||||
roomId: roomId,
|
||||
isDesktop: isDesktop,
|
||||
showMembersByDefault: showMembersByDefault,
|
||||
initialHighlightedEvent:
|
||||
initialHighlightedEvent.value,
|
||||
),
|
||||
),
|
||||
],
|
||||
|
|
@ -43,9 +57,14 @@ class const ChatPage({super.key}) extends ConsumerWidget {
|
|||
),
|
||||
drawer: isDesktop || !initComplete
|
||||
? null
|
||||
: Sidebar(isDesktop: isDesktop),
|
||||
: Sidebar(
|
||||
isDesktop: isDesktop,
|
||||
jumpToEvent: (eventId) =>
|
||||
initialHighlightedEvent.value = eventId,
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,10 +1,13 @@
|
|||
import "dart:async";
|
||||
|
||||
import "package:collection/collection.dart";
|
||||
import "package:m3e_buttons/m3e_buttons.dart";
|
||||
import "package:material_ui/material_ui.dart";
|
||||
import "package:flutter_hooks/flutter_hooks.dart";
|
||||
import "package:hooks_riverpod/hooks_riverpod.dart";
|
||||
import "package:nexus/controllers/key.dart";
|
||||
import "package:nexus/controllers/notifications.dart";
|
||||
import "package:nexus/controllers/spaces.dart";
|
||||
import "package:nexus/models/event.dart";
|
||||
import "package:nexus/widgets/appbar.dart";
|
||||
import "package:nexus/widgets/error_dialog.dart";
|
||||
|
|
@ -16,6 +19,7 @@ import "package:super_sliver_list/super_sliver_list.dart";
|
|||
class const NotificationsPage({
|
||||
final String? highlightedEventId,
|
||||
final bool defaultToAllNotifications = false,
|
||||
required final void Function(String eventId) jumpToEvent,
|
||||
super.key,
|
||||
}) extends HookConsumerWidget {
|
||||
@override
|
||||
|
|
@ -127,10 +131,49 @@ class const NotificationsPage({
|
|||
child: HighlightWrapper(
|
||||
InkWell(
|
||||
onTap: () {
|
||||
// TODO: Jump to event
|
||||
final spaces = ref.read(
|
||||
SpacesController.provider,
|
||||
);
|
||||
final space = spaces.firstWhereOrNull(
|
||||
(space) =>
|
||||
space.children.any(
|
||||
(room) =>
|
||||
room.metadata?.id ==
|
||||
event.roomId,
|
||||
) ||
|
||||
space.subSpaces.any(
|
||||
(subSpace) =>
|
||||
subSpace.children.any(
|
||||
(room) =>
|
||||
room.metadata?.id ==
|
||||
event.roomId,
|
||||
),
|
||||
),
|
||||
);
|
||||
if (space == null) return;
|
||||
|
||||
ref
|
||||
.read(
|
||||
KeyController.provider(
|
||||
KeyController.spaceKey,
|
||||
).notifier,
|
||||
)
|
||||
.set(space.id);
|
||||
ref
|
||||
.read(
|
||||
KeyController.provider(
|
||||
KeyController.roomKey,
|
||||
).notifier,
|
||||
)
|
||||
.set(event.roomId);
|
||||
jumpToEvent(event.eventId);
|
||||
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
child: IgnorePointer(
|
||||
child: EventRenderer(event),
|
||||
),
|
||||
),
|
||||
isHighlighted: isHighlighted,
|
||||
),
|
||||
);
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ final class const RoomChat({
|
|||
final relatedEvent = useState<Event?>(null);
|
||||
final relationType = useState(RelationType.reply);
|
||||
final contextualEvent = useState<String?>(initialHighlightedEvent);
|
||||
final highlightedEvent = useState<String?>(initialHighlightedEvent);
|
||||
final highlightedEvent = useState<String?>(null);
|
||||
|
||||
final composerSize = useState<double>(64);
|
||||
|
||||
|
|
@ -106,6 +106,24 @@ final class const RoomChat({
|
|||
});
|
||||
}
|
||||
|
||||
useEffect(() {
|
||||
if (initialHighlightedEvent == null) return null;
|
||||
|
||||
void check() {
|
||||
if (!context.mounted) return;
|
||||
|
||||
if (scroll.scrollController.hasClients) {
|
||||
jumpToId(initialHighlightedEvent!);
|
||||
} else {
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) => check());
|
||||
}
|
||||
}
|
||||
|
||||
check();
|
||||
|
||||
return null;
|
||||
}, [initialHighlightedEvent]);
|
||||
|
||||
IList<PopupMenuEntry> getEventOptions(Event event) =>
|
||||
event.buildEventOptions(
|
||||
context: context,
|
||||
|
|
|
|||
|
|
@ -16,8 +16,11 @@ import "package:nexus/widgets/room_menu.dart";
|
|||
// Needed for navigation_rail_m3e (#65).
|
||||
import "package:flutter/material.dart" as old_mat;
|
||||
|
||||
class const Sidebar({required final bool isDesktop, super.key})
|
||||
extends HookConsumerWidget {
|
||||
class const Sidebar({
|
||||
required final bool isDesktop,
|
||||
required final void Function(String eventId) jumpToEvent,
|
||||
super.key,
|
||||
}) extends HookConsumerWidget {
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final selectedSpaceProvider = KeyController.provider(
|
||||
|
|
@ -194,7 +197,8 @@ class const Sidebar({required final bool isDesktop, super.key})
|
|||
tooltip: "Open notifications",
|
||||
onPressed: () => Navigator.of(context).push(
|
||||
MaterialPageRoute(
|
||||
builder: (_) => NotificationsPage(),
|
||||
builder: (_) =>
|
||||
NotificationsPage(jumpToEvent: jumpToEvent),
|
||||
),
|
||||
),
|
||||
icon: Icon(Icons.notifications),
|
||||
|
|
|
|||
Loading…
Reference in a new issue