change how cross-room jumping works
This commit is contained in:
parent
b92aaed610
commit
da7f2dcf4e
5 changed files with 45 additions and 48 deletions
|
|
@ -1,16 +0,0 @@
|
|||
import "package:flutter_riverpod/flutter_riverpod.dart";
|
||||
|
||||
class ContextualEventController(String? _) extends Notifier<int?> {
|
||||
@override
|
||||
int? build() => null;
|
||||
|
||||
void set(int? event) => state = event;
|
||||
|
||||
@override
|
||||
bool updateShouldNotify(_, _) => true;
|
||||
|
||||
static final provider =
|
||||
NotifierProvider.family<ContextualEventController, int?, String?>(
|
||||
ContextualEventController.new,
|
||||
);
|
||||
}
|
||||
17
lib/controllers/jump_request.dart
Normal file
17
lib/controllers/jump_request.dart
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
import "package:flutter_riverpod/flutter_riverpod.dart";
|
||||
|
||||
typedef JumpRequest = ({String roomId, int rowId});
|
||||
|
||||
class JumpRequestController extends Notifier<JumpRequest?> {
|
||||
@override
|
||||
JumpRequest? build() => null;
|
||||
|
||||
void request(String roomId, int rowId) =>
|
||||
state = (roomId: roomId, rowId: rowId);
|
||||
|
||||
void consume() => state = null;
|
||||
|
||||
static final provider = NotifierProvider<JumpRequestController, JumpRequest?>(
|
||||
JumpRequestController.new,
|
||||
);
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
import "package:collection/collection.dart";
|
||||
import "package:flutter_riverpod/experimental/mutation.dart";
|
||||
import "package:nexus/controllers/contextual_event.dart";
|
||||
import "package:nexus/controllers/jump_request.dart";
|
||||
import "package:nexus/controllers/key.dart";
|
||||
import "package:nexus/controllers/spaces.dart";
|
||||
import "package:nexus/models/space.dart";
|
||||
|
|
@ -31,16 +31,16 @@ extension FocusRoom on MutationTarget {
|
|||
.read(KeyController.provider(KeyController.spaceKey).notifier)
|
||||
.set(parent.id);
|
||||
|
||||
if (eventRowId != null) {
|
||||
container
|
||||
.read(JumpRequestController.provider.notifier)
|
||||
.request(roomId, eventRowId);
|
||||
}
|
||||
|
||||
await container
|
||||
.read(KeyController.provider(KeyController.roomKey).notifier)
|
||||
.set(roomId);
|
||||
|
||||
if (eventRowId != null) {
|
||||
container
|
||||
.read(ContextualEventController.provider(roomId).notifier)
|
||||
.set(eventRowId);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
import "package:material_ui/material_ui.dart";
|
||||
import "package:hooks_riverpod/hooks_riverpod.dart";
|
||||
import "package:nexus/controllers/init_complete.dart";
|
||||
import "package:nexus/controllers/contextual_event.dart";
|
||||
import "package:nexus/controllers/key.dart";
|
||||
import "package:nexus/widgets/appbar.dart";
|
||||
import "package:nexus/widgets/sidebar.dart";
|
||||
|
|
@ -27,19 +26,11 @@ class const ChatPage({super.key}) extends HookConsumerWidget {
|
|||
children: [
|
||||
if (isDesktop) Sidebar(),
|
||||
Expanded(
|
||||
child: Consumer(
|
||||
builder: (context, ref, _) {
|
||||
final initialHighlight = ref.watch(
|
||||
ContextualEventController.provider(roomId),
|
||||
);
|
||||
return RoomChat(
|
||||
key: ValueKey((roomId, initialHighlight)),
|
||||
child: RoomChat(
|
||||
key: ValueKey(roomId),
|
||||
roomId: roomId,
|
||||
isDesktop: isDesktop,
|
||||
initialHighlight: initialHighlight,
|
||||
showMembersByDefault: showMembersByDefault,
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
|
|
|
|||
|
|
@ -21,19 +21,24 @@ import "package:nexus/widgets/room_appbar.dart";
|
|||
import "package:nexus/main.dart";
|
||||
import "package:nexus/widgets/room_chat/chat_timeline.dart";
|
||||
import "package:nexus/helpers/extensions/build_event_options.dart";
|
||||
import "package:nexus/controllers/jump_request.dart";
|
||||
|
||||
final class const RoomChat({
|
||||
required final String? roomId,
|
||||
required final bool isDesktop,
|
||||
required final bool showMembersByDefault,
|
||||
final int? initialHighlight,
|
||||
super.key,
|
||||
}) extends HookConsumerWidget {
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final relatedEvent = useState<int?>(null);
|
||||
final relationType = useState(RelationType.reply);
|
||||
final contextualEvent = useState<int?>(initialHighlight);
|
||||
final pendingJump = ref.read(JumpRequestController.provider);
|
||||
final contextualEvent = useState<int?>(
|
||||
pendingJump != null && pendingJump.roomId == this.roomId
|
||||
? pendingJump.rowId
|
||||
: null,
|
||||
);
|
||||
final highlightedEvent = useState<int?>(null);
|
||||
|
||||
final composerSize = useState<double>(64);
|
||||
|
|
@ -110,23 +115,23 @@ final class const RoomChat({
|
|||
});
|
||||
}
|
||||
|
||||
useEffect(() {
|
||||
if (initialHighlight == null) return null;
|
||||
ref.listen(JumpRequestController.provider, (_, request) {
|
||||
if (request == null || request.roomId != roomId) return;
|
||||
|
||||
void check() {
|
||||
void tryJump() {
|
||||
if (!context.mounted) return;
|
||||
if (ref.read(JumpRequestController.provider) != request) return;
|
||||
|
||||
if (scroll.scrollController.hasClients) {
|
||||
jumpToEvent(initialHighlight!);
|
||||
ref.read(JumpRequestController.provider.notifier).consume();
|
||||
jumpToEvent(request.rowId);
|
||||
} else {
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) => check());
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) => tryJump());
|
||||
}
|
||||
}
|
||||
|
||||
check();
|
||||
|
||||
return null;
|
||||
}, [initialHighlight]);
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) => tryJump());
|
||||
});
|
||||
|
||||
IList<PopupMenuEntry> getEventOptions(Event event) =>
|
||||
event.buildEventOptions(
|
||||
|
|
|
|||
Loading…
Reference in a new issue