Skip to content

Commit 6dc5a80

Browse files
committed
legacy-data: Use legacy data to initialize this app's data
Fixes #1070.
1 parent e140bbb commit 6dc5a80

File tree

2 files changed

+94
-0
lines changed

2 files changed

+94
-0
lines changed

lib/model/database.dart

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import 'package:drift/remote.dart';
44
import 'package:sqlite3/common.dart';
55

66
import '../log.dart';
7+
import 'legacy_app_data.dart';
78
import 'schema_versions.g.dart';
89
import 'settings.dart';
910

@@ -195,6 +196,7 @@ class AppDatabase extends _$AppDatabase {
195196
await m.createAll();
196197
// Corresponds to `from4to5` above.
197198
await into(globalSettings).insert(GlobalSettingsCompanion());
199+
await migrateLegacyAppData(this);
198200
}
199201

200202
@override

lib/model/legacy_app_data.dart

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,105 @@ library;
99
import 'dart:convert';
1010
import 'dart:io';
1111

12+
import 'package:drift/drift.dart' as drift;
1213
import 'package:flutter/foundation.dart';
1314
import 'package:json_annotation/json_annotation.dart';
1415
import 'package:path_provider/path_provider.dart';
1516
import 'package:sqlite3/sqlite3.dart';
1617

18+
import '../log.dart';
19+
import 'database.dart';
20+
import 'settings.dart';
21+
1722
part 'legacy_app_data.g.dart';
1823

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+
19111
Future<LegacyAppData?> readLegacyAppData() async {
20112
final LegacyAppDatabase db;
21113
try {

0 commit comments

Comments
 (0)