Skip to content

Commit fe0f795

Browse files
committed
wip/link legacy-data: Use legacy data to initialize this app's data; TODO test
Fixes 1070.
1 parent bc928f7 commit fe0f795

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
@@ -8,13 +8,105 @@ library;
88
import 'dart:convert';
99
import 'dart:io';
1010

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

17+
import '../log.dart';
18+
import 'database.dart';
19+
import 'settings.dart';
20+
1621
part '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+
// Specifically, the latest added of these was userId, in commit 4fdefb09b
86+
// (#M4968), released in v27.170 in 2021-09.)
87+
// Drop the account.
88+
assert(debugLog(" (account ignored because missing metadata)"));
89+
continue;
90+
}
91+
await db.createAccount(AccountsCompanion.insert(
92+
realmUrl: account.realm,
93+
userId: account.userId!,
94+
email: account.email,
95+
apiKey: account.apiKey,
96+
zulipVersion: account.zulipVersion!,
97+
// no zulipMergeBase; legacy app didn't record it
98+
zulipFeatureLevel: account.zulipFeatureLevel!,
99+
// This app doesn't yet maintain ackedPushToken (#322), so avoid recording
100+
// a value that would then be allowed to get stale. See discussion:
101+
// https://github.com/zulip/zulip-flutter/pull/1588#discussion_r2148817025
102+
// TODO(#322): apply ackedPushToken
103+
// ackedPushToken: drift.Value(account.ackedPushToken),
104+
));
105+
}
106+
107+
assert(debugLog("Done migrating legacy app data."));
108+
}
109+
18110
Future<LegacyAppData?> readLegacyAppData() async {
19111
final LegacyAppDatabase db;
20112
try {

0 commit comments

Comments
 (0)