@@ -8,13 +8,103 @@ library;
88import 'dart:convert' ;
99import 'dart:io' ;
1010
11+ import 'package:drift/drift.dart' as drift;
1112import 'package:flutter/foundation.dart' ;
1213import 'package:json_annotation/json_annotation.dart' ;
1314import 'package:path_provider/path_provider.dart' ;
1415import 'package:sqlite3/sqlite3.dart' ;
1516
17+ import '../log.dart' ;
18+ import 'database.dart' ;
19+ import 'settings.dart' ;
20+
1621part 'legacy_app_data.g.dart' ;
1722
23+ Future <void > migrateLegacyAppData (AppDatabase db) async {
24+ assert (debugLog ("Migrating legacy app data..." ));
25+ final legacyData = await readLegacyAppData ();
26+ if (legacyData == null ) {
27+ assert (debugLog ("... no legacy app data found." ));
28+ return ;
29+ }
30+
31+ assert (debugLog ("Found settings: ${legacyData .settings ?.toJson ()}" ));
32+ final settings = legacyData.settings;
33+ if (settings != null ) {
34+ await db.update (db.globalSettings).write (GlobalSettingsCompanion (
35+ // TODO(#1139) apply settings.language
36+ themeSetting: switch (settings.theme) {
37+ // The legacy app has just two values for this setting: light and dark,
38+ // where light is the default. Map that default to the new default,
39+ // which is to follow the system-wide setting.
40+ // We planned the same change for the legacy app (but were
41+ // foiled by React Native):
42+ // https://github.com/zulip/zulip-mobile/issues/5533
43+ // More-recent discussion:
44+ // https://github.com/zulip/zulip-flutter/pull/1588#discussion_r2147418577
45+ LegacyAppThemeSetting .default_ => drift.Value .absent (),
46+ LegacyAppThemeSetting .night => drift.Value (ThemeSetting .dark),
47+ },
48+ browserPreference: switch (settings.browser) {
49+ LegacyAppBrowserPreference .embedded => drift.Value (BrowserPreference .inApp),
50+ LegacyAppBrowserPreference .external => drift.Value (BrowserPreference .external ),
51+ LegacyAppBrowserPreference .default_ => drift.Value .absent (),
52+ },
53+ markReadOnScroll: switch (settings.markMessagesReadOnScroll) {
54+ // The legacy app's default was "always".
55+ // In this app, that would mix poorly with the VisitFirstUnreadSetting
56+ // default of "conversations"; so translate the old default
57+ // to the new default of "conversations".
58+ LegacyAppMarkMessagesReadOnScroll .always =>
59+ drift.Value (MarkReadOnScrollSetting .conversations),
60+ LegacyAppMarkMessagesReadOnScroll .never =>
61+ drift.Value (MarkReadOnScrollSetting .never),
62+ LegacyAppMarkMessagesReadOnScroll .conversationViewsOnly =>
63+ drift.Value (MarkReadOnScrollSetting .conversations),
64+ },
65+ ));
66+ }
67+
68+ assert (debugLog ("Found ${legacyData .accounts ?.length } accounts:" ));
69+ for (final account in legacyData.accounts ?? < LegacyAppAccount > []) {
70+ assert (debugLog (" account: ${account .toJson ()..['apiKey' ] = 'redacted' }" ));
71+ if (account.apiKey.isEmpty) {
72+ // This represents the user having logged out of this account.
73+ // (See `Auth.apiKey` in src/api/transportTypes.js .)
74+ // In this app, when a user logs out of an account,
75+ // the account is removed from the accounts list. So remove this account.
76+ assert (debugLog (" (account ignored because had been logged out)" ));
77+ continue ;
78+ }
79+ if (account.userId == null
80+ || account.zulipVersion == null
81+ || account.zulipFeatureLevel == null ) {
82+ // The legacy app either never loaded server data for this account,
83+ // or last did so on an ancient version of the app.
84+ // (See docs and comments on these properties in src/types.js .)
85+ // Drop the account.
86+ assert (debugLog (" (account ignored because missing metadata)" ));
87+ continue ;
88+ }
89+ await db.createAccount (AccountsCompanion .insert (
90+ realmUrl: account.realm,
91+ userId: account.userId! ,
92+ email: account.email,
93+ apiKey: account.apiKey,
94+ zulipVersion: account.zulipVersion! ,
95+ // no zulipMergeBase; legacy app didn't record it
96+ zulipFeatureLevel: account.zulipFeatureLevel! ,
97+ // This app doesn't yet maintain ackedPushToken (#322), so avoid recording
98+ // a value that would then be allowed to get stale. See discussion:
99+ // https://github.com/zulip/zulip-flutter/pull/1588#discussion_r2148817025
100+ // TODO(#322): apply ackedPushToken
101+ // ackedPushToken: drift.Value(account.ackedPushToken),
102+ ));
103+ }
104+
105+ assert (debugLog ("Done migrating legacy app data." ));
106+ }
107+
18108Future <LegacyAppData ?> readLegacyAppData () async {
19109 final LegacyAppDatabase db;
20110 try {
0 commit comments