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