Skip to content

Add and handle live-updates to saved snippets data #1511

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

Open
wants to merge 4 commits into
base: main
Choose a base branch
from

Conversation

PIG208
Copy link
Member

@PIG208 PIG208 commented May 13, 2025

This prepares the data model and API bindings for #1391 towards #863.

@PIG208 PIG208 added the maintainer review PR ready for review by Zulip maintainers label May 13, 2025
@PIG208 PIG208 requested a review from chrisbobbe May 13, 2025 18:50
@PIG208 PIG208 force-pushed the pr-saved-prep branch 2 times, most recently from c27690a to c5cc482 Compare May 16, 2025 23:17
@PIG208 PIG208 mentioned this pull request May 16, 2025
3 tasks
Copy link
Collaborator

@chrisbobbe chrisbobbe left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!! Small comments below.

@@ -37,6 +37,13 @@ sealed class Event {
case 'update': return RealmUserUpdateEvent.fromJson(json);
default: return UnexpectedEvent.fromJson(json);
}
case 'saved_snippets':
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

api: Add save_snippets events and handle live-updates

Commit-message nit: saved_snippets

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also this is labeled as an "api:" commit, but it also adds to model code; how about separate api: and model: commits?

(Or perhaps just one model: commit with the API-binding additions lumped into that same commit—but if doing that, it would be logical to lump all the new API-binding code into that commit, including the initial-snapshot code.)

Map<int, SavedSnippet> get savedSnippets;
}

class SavedSnippetStoreImpl with SavedSnippetStore {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Normally a substore would extend PerAccountStoreBase…it seems we don't depend on that here though 🙂 but maybe it's helpful to do it anyway, in case it's needed in the future, and also as an example for future substore implementations?

diff --git lib/model/saved_snippet.dart lib/model/saved_snippet.dart
index 66b50781d..92cb253ef 100644
--- lib/model/saved_snippet.dart
+++ lib/model/saved_snippet.dart
@@ -2,14 +2,18 @@ import 'package:collection/collection.dart';
 
 import '../api/model/events.dart';
 import '../api/model/model.dart';
+import 'store.dart';
 
 mixin SavedSnippetStore {
   Map<int, SavedSnippet> get savedSnippets;
 }
 
-class SavedSnippetStoreImpl with SavedSnippetStore {
-  SavedSnippetStoreImpl({required Iterable<SavedSnippet> savedSnippets})
-    : _savedSnippets = {
+class SavedSnippetStoreImpl extends PerAccountStoreBase with SavedSnippetStore {
+  SavedSnippetStoreImpl({
+    required super.core,
+    required Iterable<SavedSnippet> savedSnippets,
+  }) :
+      _savedSnippets = {
         for (final savedSnippet in savedSnippets)
           savedSnippet.id: savedSnippet,
       };

savedSnippets: [eg.savedSnippet(id: 101)]));
check(store).savedSnippets.values.single.id.equals(101);

await store.handleEvent(SavedSnippetsAddEvent(id: 1,savedSnippet:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: space after comma; actually maybe put savedSnippet: on the next line, with eg.savedSnippet(?

@PIG208
Copy link
Member Author

PIG208 commented May 20, 2025

Thanks! Updated the PR.

Copy link
Collaborator

@chrisbobbe chrisbobbe left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! Small comments below.

part 'saved_snippets.g.dart';

/// https://zulip.com/api/create-saved-snippet
Future<CreateSavedSnippetResult> createSavedSnippet(ApiConnection connection, {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

api: Add createSavedSnippet route

This needs a simple smoke test in test/api/route/.

Comment on lines +880 to +883
case SavedSnippetsEvent():
assert(debugLog('server event: saved_snippets/${event.op}'));
_savedSnippets.handleSavedSnippetsEvent(event);
notifyListeners();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah I guess this case needs to be handled (as a no-op) in the earlier commit—

api: Add saved_snippets events

—to satisfy the analyzer there.

Map<int, SavedSnippet> get savedSnippets;
}

class SavedSnippetStoreImpl extends PerAccountStoreBase with SavedSnippetStore {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

model: Handle live-updates to savedSnippets

Commit-message nit: this commit does more than just handle live-updates to savedSnippets—it's what adds savedSnippets into the codebase in the first place :)

Could be:

model: Add PerAccountStore.savedSnippets, updating with events

or similar.

@PIG208
Copy link
Member Author

PIG208 commented May 20, 2025

Thanks! Pushed an update.

Copy link
Collaborator

@chrisbobbe chrisbobbe left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! One nit below, and I'll mark for Greg's review.

Comment on lines 18 to 22
check(connection.takeRequests()).single.isA<http.Request>()
.bodyFields.deepEquals({
'title': 'test saved snippet',
'content': 'content',
});
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
check(connection.takeRequests()).single.isA<http.Request>()
.bodyFields.deepEquals({
'title': 'test saved snippet',
'content': 'content',
});
check(connection.takeRequests()).single.isA<http.Request>()
.bodyFields.deepEquals({
'title': 'test saved snippet',
'content': 'content',
});

(I think)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh right. Oops 😬

@chrisbobbe chrisbobbe requested a review from gnprice May 20, 2025 23:15
@chrisbobbe chrisbobbe assigned gnprice and unassigned chrisbobbe May 20, 2025
@chrisbobbe chrisbobbe added integration review Added by maintainers when PR may be ready for integration and removed maintainer review PR ready for review by Zulip maintainers labels May 20, 2025
Copy link
Member

@gnprice gnprice left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks to you both! I've done a quick skim, and this structure looks good. I like the organization with the separate API and model/store commits (as per #1511 (comment)), with this to decouple the API event commit from the store changes:

      case SavedSnippetsEvent():
        // TODO handle
        break;

I'll aim to do a full review tomorrow.

Comment on lines +348 to +350
/// The corresponding API docs are in several places for
/// different values of `op`; see subclasses.
sealed class SavedSnippetsEvent extends Event {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: It looks like these docs are actually next to each other, so this class can usefully link to the one that comes first. (The subclasses can still link to the individual sections.)

This wording was originally for realm_user, which is actually scattered across two widely-separated places in https://zulip.com/api/get-events . (And I see I wrote it at the same time for stream but it's not true of stream now; not sure if that was an oversight or that one got fixed since then.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
integration review Added by maintainers when PR may be ready for integration
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants