Skip to content

Conversation

rajveermalviya
Copy link
Member

@rajveermalviya rajveermalviya commented Sep 19, 2025

This doesn't yet handle RealmUpdateEvent, will send a follow-up PR for it.

Fixes-partly: #1036

@rajveermalviya rajveermalviya added the maintainer review PR ready for review by Zulip maintainers label Sep 19, 2025
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, this will be helpful! Comments below.

Also:

  • Does the 'basic happy case' test in test/widgets/login_test.dart need to be updated in order to catch a bug where the values aren't stored properly on login? (Or to be more explicit about testing that?)
  • Let's leave a TODO(#668) to remember to update the database on events


final bool realmEnableReadReceipts;

final Uri realmIconUrl;
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 realmName and realmIcon to InitialSnapshot

nit: realmIconUrl in commit message, right?

realmUrl: realmUrl ?? _realmUrl,
realmName: realmName ?? 'Example Zulip organization',
realmIcon: realmIcon ?? '$realmUrl/icon.png',
realmIcon: realmIcon ?? _realmIcon,
Copy link
Collaborator

Choose a reason for hiding this comment

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

_realmIcon is a relative URL, right? So this changes the behavior when realmIcon isn't passed to eg.serverSettings: before this change, it was an absolute URL (starting with realmUrl); now, it's a relative URL. Does the API specify what kind to expect? We should match that if so, otherwise probably just match the observed behavior. (Same with the initial snapshot.)

Copy link
Member Author

Choose a reason for hiding this comment

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

API docs don't specify that, but the example response there have "realm_icon": "https://secure.gravatar.com/…" URL, and on CZO the observed URL is /user_avatars/2/realm/icon.png?version=3. So, I guess it can be either ot those (absolute or relative).

Also GetServerSettingsResult.realmIcon was never read before so this change should be nfc, added a note for that in the commit message.

Copy link
Member Author

Choose a reason for hiding this comment

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

And separated this change to 6e0d9e4.

/// This corresponds to [GetServerSettingsResult.realmName].
Column<String> get realmName => text().nullable()();

/// The organization icon URL of the Zulip realm this account is on.
Copy link
Collaborator

Choose a reason for hiding this comment

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

nit: can remove "organization", it's redundant with "Zulip realm"

Comment on lines 127 to 132
/// The name of the Zulip realm this account is on.
///
/// This corresponds to [GetServerSettingsResult.realmName].
Column<String> get realmName => text().nullable()();
Copy link
Collaborator

Choose a reason for hiding this comment

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

Should we add a line like

  /// Nullable just because older versions of the app didn't store this.

here and on realmIcon?

Copy link
Collaborator

Choose a reason for hiding this comment

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

And in migrateLegacyAppData, maybe add lines like these:

--- lib/model/legacy_app_data.dart
+++ lib/model/legacy_app_data.dart
@@ -94,6 +94,8 @@ Future<void> migrateLegacyAppData(AppDatabase db) async {
     try {
       await db.createAccount(AccountsCompanion.insert(
         realmUrl: account.realm,
+        // no realmName; legacy app didn't record it
+        // no realmIcon; legacy app didn't record it
         userId: account.userId!,
         email: account.email,
         apiKey: account.apiKey,

import 'package:drift/remote.dart';
import 'package:sqlite3/common.dart';

import '../api/route/realm.dart';
Copy link
Collaborator

Choose a reason for hiding this comment

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

db: Store realmName and realmIcon in the Accounts table

And update account creation during login to populate
these fields from server settings.

Updates: #1036

Hmm I haven't seen an Updates: <issue> line before; what does that mean?

Copy link
Member Author

Choose a reason for hiding this comment

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

Hmm, I just meant to relate to the issue that this commit partly fixes. I guess Related: or the more direct Fixes-partly: fits better here.

Comment on lines 412 to 413
realmName: Value(widget.serverSettings.realmName),
realmIcon: Value(widget.serverSettings.realmIcon),
Copy link
Collaborator

Choose a reason for hiding this comment

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

db: Store realmName and realmIcon in the Accounts table

At this commit, the values are never updated when they change on the server, even when the user registers an event queue. So they can potentially be out-of-date by weeks, months, years; so let's add a TODO here to update them on /register, and remove the TODO in the next commit when that gets done.

required String realmName,
required Uri realmIcon,
}) async {
assert(_accounts.containsKey(accountId));
Copy link
Collaborator

Choose a reason for hiding this comment

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

There's an async gap before this caller, and normally we consider it possible that the account was logged out during an async gap. But I guess in this case, the async gap is for updating an account (await globalStore.updateZulipVersionData), and that can't successfully happen concurrently with deleting the account? Meaning this assert should actually always hold?

Copy link
Member Author

Choose a reason for hiding this comment

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

Added a check at the callsite of updateRealmData.

@rajveermalviya rajveermalviya force-pushed the pr-realm-name-icon branch 2 times, most recently from 3abe521 to 4403816 Compare September 23, 2025 15:20
@rajveermalviya
Copy link
Member Author

Thanks for the review @chrisbobbe! Pushed an update, PTAL.

@chrisbobbe
Copy link
Collaborator

Thanks! Looks good except it looks like these are still pending, from #1860 (review) :

Also:

  • Does the 'basic happy case' test in test/widgets/login_test.dart need to be updated in order to catch a bug where the values aren't stored properly on login? (Or to be more explicit about testing that?)
  • Let's leave a TODO(#668) to remember to update the database on events

@rajveermalviya
Copy link
Member Author

Thanks @chrisbobbe! Sorry for missing those. Pushed another update, PTAL.

@chrisbobbe
Copy link
Collaborator

Thanks, LGTM! Marking for Greg's review.

@chrisbobbe chrisbobbe requested review from gnprice and removed request for chrisbobbe September 25, 2025 21:06
@chrisbobbe chrisbobbe assigned gnprice and unassigned chrisbobbe Sep 25, 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 Sep 25, 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 @rajveermalviya for building this, and @chrisbobbe for the previous reviews! Apologies this review is a few days delayed.


final String realmName;
final String realmIcon;
final Uri realmIcon;
Copy link
Member

Choose a reason for hiding this comment

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

nit: do this before adding the corresponding field on InitialSnapshot; that way they agree from the beginning

Comment on lines -128 to +131
realmIcon: realmIcon ?? '$realmUrl/icon.png',
realmIcon: realmIcon ?? _realmIcon,
Copy link
Member

Choose a reason for hiding this comment

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

nit: similarly, reorder so this and eg.realmIcon agree from the beginning

Comment on lines +388 to +389
realmName: Value('Some organization'),
realmIcon: Value(Uri.parse('/some-image.png'))));
Copy link
Member

Choose a reason for hiding this comment

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

This seems like it distracts from the narrative of this test (which is about the web-auth flow, not about the realm name and icon). This is a classic example of data that should exist in order to make things realistic, but is boring.

Can we arrange for eg.selfAccount to already have these fields, with the same boring values that eg.serverSettings puts there? For example that's how this test already handles realmUrl, which is similarly boring.

Comment on lines +387 to +388
check(globalStore.getAccount(selfAccount.id)).identicalTo(updated);
check(updated).equals(selfAccount.copyWith(
Copy link
Member

Choose a reason for hiding this comment

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

nit: can make the relationships here more explicit:

Suggested change
check(globalStore.getAccount(selfAccount.id)).identicalTo(updated);
check(updated).equals(selfAccount.copyWith(
check(globalStore.getAccount(selfAccount.id))
..identicalTo(updated)
..equals(selfAccount.copyWith(

await globalStore.updateZulipVersionData(accountId, zulipVersionData);
connection.zulipFeatureLevel = zulipVersionData.zulipFeatureLevel;
}
if (globalStore.getAccount(accountId) != null) {
Copy link
Member

Choose a reason for hiding this comment

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

Can this condition ever fail? /cc @chrisbobbe since you had a related question above.

Before this change, the next step here was to call PerAccountStore.fromInitialSnapshot, which already assumes (and asserts) that the account exists. So if there's a reason that can be untrue, then that's an existing bug.

But I don't think it can be. The step before this was either the previous conditional — which has a ! that throws if the account doesn't exist — or globalStore.updateZulipVersionData, which calls updateAccount, which returns the updated account and so guarantees that it exists.

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