-
Notifications
You must be signed in to change notification settings - Fork 20
Show who else is editing a lineup group #243
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,76 @@ | ||
| import 'dart:convert'; | ||
|
|
||
| import 'package:flutter_riverpod/flutter_riverpod.dart'; | ||
| import 'package:icarus/collab/presence/presence_models.dart'; | ||
| import 'package:icarus/const/line_provider.dart'; | ||
| import 'package:icarus/providers/collab/active_page_live_sync_provider.dart'; | ||
| import 'package:icarus/providers/collab/strategy_presence_provider.dart'; | ||
| import 'package:icarus/providers/editor_operation_provider.dart'; | ||
| import 'package:icarus/providers/strategy_page_session_provider.dart'; | ||
|
|
||
| /// The lineups and spots each open lineup dialog shows, by the dialog that | ||
| /// opened them, so having one open counts as editing it. | ||
| final openLineUpItemsProvider = | ||
| NotifierProvider<OpenLineUpItemsNotifier, Map<Object, Set<String>>>( | ||
| OpenLineUpItemsNotifier.new, | ||
| ); | ||
|
|
||
| class OpenLineUpItemsNotifier extends Notifier<Map<Object, Set<String>>> { | ||
| @override | ||
| Map<Object, Set<String>> build() => const {}; | ||
|
|
||
| void open(Object owner, Set<String> itemIds) { | ||
| state = {...state, owner: itemIds}; | ||
| } | ||
|
|
||
| void close(Object owner) { | ||
| if (!state.containsKey(owner)) return; | ||
| state = {...state}..remove(owner); | ||
| } | ||
| } | ||
|
|
||
| /// The lineup groups this user is editing on the page on screen: those of | ||
| /// the lineup spots they hold, the spot a lineup is being placed from, and | ||
| /// the lineups an open dialog shows. Null for none. | ||
| final myLineupEditingProvider = Provider<PresenceEditing?>((ref) { | ||
| final pageId = | ||
| ref.watch(strategyPageSessionProvider.select((s) => s.activePageId)); | ||
| if (pageId == null) return null; | ||
| final held = ref.watch(editorHeldEntitiesProvider) ?? const <String>{}; | ||
| final placement = ref.watch(lineUpProvider.select((s) => s.placement)); | ||
| final open = ref.watch(openLineUpItemsProvider); | ||
| ref.watch(lineupGroupMemoryRevisionProvider); | ||
| final liveSync = ref.read(activePageLiveSyncProvider.notifier); | ||
| final groupIds = { | ||
| for (final id in { | ||
| ...held, | ||
| if (placement?.pinnedOriginId case final id?) id, | ||
| if (placement?.pinnedLandingId case final id?) id, | ||
| for (final ids in open.values) ...ids, | ||
| }) | ||
| if (liveSync.lineupGroupOf(pageId, id) case final group?) group, | ||
|
Comment on lines
+49
to
+51
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. An edit dialog can remain open after its page changes, but its registered lineup ID is looked up on the newly active page. If that page has a lineup with the same ID, collaborators see an editing notice for the new page’s group while the dialog still contains the old page’s draft. This misleading notice is a non-blocking concern; tie the registration to the page where the dialog opened. ArtifactsFlutter test for the lineup edit dialog across a page switch
Edit dialog state before switching pages
Edit dialog state after switching pages
Edit dialog initialization and save paths
Owner
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fixed in #244. Each open dialog records the page it opened on, and only dialogs from the page on screen count as editing. |
||
| }; | ||
| if (groupIds.isEmpty) return null; | ||
| return PresenceEditing(pageId: pageId, groupIds: groupIds); | ||
| }); | ||
|
|
||
| /// Teammates editing the lineup group [itemId] (a lineup, origin or landing | ||
| /// on the page on screen) is in, one entry per person. | ||
| final lineupGroupEditorsProvider = | ||
| Provider.autoDispose.family<List<PresencePeer>, String>((ref, itemId) { | ||
| final pageId = | ||
| ref.watch(strategyPageSessionProvider.select((s) => s.activePageId)); | ||
| if (pageId == null) return const []; | ||
| ref.watch(lineupGroupMemoryRevisionProvider); | ||
| final group = ref | ||
| .read(activePageLiveSyncProvider.notifier) | ||
| .lineupGroupOf(pageId, itemId); | ||
| if (group == null) return const []; | ||
| // Cursors move many times a second; rebuild only when who is editing | ||
| // changes, by watching a key of them rather than the list itself. | ||
| ref.watch(strategyPresenceProvider.select((s) => jsonEncode([ | ||
| for (final peer in s.editingLineupGroup(pageId, group)) | ||
| [peer.uid, peer.name], | ||
| ]))); | ||
| return ref.read(strategyPresenceProvider).editingLineupGroup(pageId, group); | ||
| }); | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When open dialogs or held items cover more than eight distinct lineup groups, this truncation silently omits the remaining groups from presence. Collaborators receive no editing notice for an omitted group, making the notice incomplete in this non-blocking edge case.
Artifacts
Flutter test source for open-dialog group presence
Eight-group control test output
Nine-group test output
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Intended. The room refuses more than 8 groups, so the client sends at most 8 rather than having the whole message dropped. In practice it's one or two: a held spot, a pinned placement, an open dialog. Editing nine lineup groups at once doesn't happen.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That’s fair. Since the room accepts at most eight groups, truncating the client payload to eight is the correct compatibility behavior, and the expected editing flows normally involve only one or two groups. I’m withdrawing this as a finding; no change is needed.