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:collection/collection.dart";
|
||||||
import "package:flutter_riverpod/experimental/mutation.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/key.dart";
|
||||||
import "package:nexus/controllers/spaces.dart";
|
import "package:nexus/controllers/spaces.dart";
|
||||||
import "package:nexus/models/space.dart";
|
import "package:nexus/models/space.dart";
|
||||||
|
|
@ -31,16 +31,16 @@ extension FocusRoom on MutationTarget {
|
||||||
.read(KeyController.provider(KeyController.spaceKey).notifier)
|
.read(KeyController.provider(KeyController.spaceKey).notifier)
|
||||||
.set(parent.id);
|
.set(parent.id);
|
||||||
|
|
||||||
|
if (eventRowId != null) {
|
||||||
|
container
|
||||||
|
.read(JumpRequestController.provider.notifier)
|
||||||
|
.request(roomId, eventRowId);
|
||||||
|
}
|
||||||
|
|
||||||
await container
|
await container
|
||||||
.read(KeyController.provider(KeyController.roomKey).notifier)
|
.read(KeyController.provider(KeyController.roomKey).notifier)
|
||||||
.set(roomId);
|
.set(roomId);
|
||||||
|
|
||||||
if (eventRowId != null) {
|
|
||||||
container
|
|
||||||
.read(ContextualEventController.provider(roomId).notifier)
|
|
||||||
.set(eventRowId);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
import "package:material_ui/material_ui.dart";
|
import "package:material_ui/material_ui.dart";
|
||||||
import "package:hooks_riverpod/hooks_riverpod.dart";
|
import "package:hooks_riverpod/hooks_riverpod.dart";
|
||||||
import "package:nexus/controllers/init_complete.dart";
|
import "package:nexus/controllers/init_complete.dart";
|
||||||
import "package:nexus/controllers/contextual_event.dart";
|
|
||||||
import "package:nexus/controllers/key.dart";
|
import "package:nexus/controllers/key.dart";
|
||||||
import "package:nexus/widgets/appbar.dart";
|
import "package:nexus/widgets/appbar.dart";
|
||||||
import "package:nexus/widgets/sidebar.dart";
|
import "package:nexus/widgets/sidebar.dart";
|
||||||
|
|
@ -27,19 +26,11 @@ class const ChatPage({super.key}) extends HookConsumerWidget {
|
||||||
children: [
|
children: [
|
||||||
if (isDesktop) Sidebar(),
|
if (isDesktop) Sidebar(),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: Consumer(
|
child: RoomChat(
|
||||||
builder: (context, ref, _) {
|
key: ValueKey(roomId),
|
||||||
final initialHighlight = ref.watch(
|
roomId: roomId,
|
||||||
ContextualEventController.provider(roomId),
|
isDesktop: isDesktop,
|
||||||
);
|
showMembersByDefault: showMembersByDefault,
|
||||||
return RoomChat(
|
|
||||||
key: ValueKey((roomId, initialHighlight)),
|
|
||||||
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/main.dart";
|
||||||
import "package:nexus/widgets/room_chat/chat_timeline.dart";
|
import "package:nexus/widgets/room_chat/chat_timeline.dart";
|
||||||
import "package:nexus/helpers/extensions/build_event_options.dart";
|
import "package:nexus/helpers/extensions/build_event_options.dart";
|
||||||
|
import "package:nexus/controllers/jump_request.dart";
|
||||||
|
|
||||||
final class const RoomChat({
|
final class const RoomChat({
|
||||||
required final String? roomId,
|
required final String? roomId,
|
||||||
required final bool isDesktop,
|
required final bool isDesktop,
|
||||||
required final bool showMembersByDefault,
|
required final bool showMembersByDefault,
|
||||||
final int? initialHighlight,
|
|
||||||
super.key,
|
super.key,
|
||||||
}) extends HookConsumerWidget {
|
}) extends HookConsumerWidget {
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
final relatedEvent = useState<int?>(null);
|
final relatedEvent = useState<int?>(null);
|
||||||
final relationType = useState(RelationType.reply);
|
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 highlightedEvent = useState<int?>(null);
|
||||||
|
|
||||||
final composerSize = useState<double>(64);
|
final composerSize = useState<double>(64);
|
||||||
|
|
@ -110,23 +115,23 @@ final class const RoomChat({
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
useEffect(() {
|
ref.listen(JumpRequestController.provider, (_, request) {
|
||||||
if (initialHighlight == null) return null;
|
if (request == null || request.roomId != roomId) return;
|
||||||
|
|
||||||
void check() {
|
void tryJump() {
|
||||||
if (!context.mounted) return;
|
if (!context.mounted) return;
|
||||||
|
if (ref.read(JumpRequestController.provider) != request) return;
|
||||||
|
|
||||||
if (scroll.scrollController.hasClients) {
|
if (scroll.scrollController.hasClients) {
|
||||||
jumpToEvent(initialHighlight!);
|
ref.read(JumpRequestController.provider.notifier).consume();
|
||||||
|
jumpToEvent(request.rowId);
|
||||||
} else {
|
} else {
|
||||||
WidgetsBinding.instance.addPostFrameCallback((_) => check());
|
WidgetsBinding.instance.addPostFrameCallback((_) => tryJump());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
check();
|
WidgetsBinding.instance.addPostFrameCallback((_) => tryJump());
|
||||||
|
});
|
||||||
return null;
|
|
||||||
}, [initialHighlight]);
|
|
||||||
|
|
||||||
IList<PopupMenuEntry> getEventOptions(Event event) =>
|
IList<PopupMenuEntry> getEventOptions(Event event) =>
|
||||||
event.buildEventOptions(
|
event.buildEventOptions(
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue