Skip to content

On launch, go to the last visited account #1784

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions lib/model/actions.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import 'package:flutter/foundation.dart';

import '../notifications/display.dart';
import '../notifications/receive.dart';
import 'settings.dart';
import 'store.dart';

// TODO: Make this a part of GlobalStore
Expand All @@ -21,6 +22,18 @@ Future<void> logOutAccount(GlobalStore globalStore, int accountId) async {
await globalStore.removeAccount(accountId);
}

Future<void> removeLastVisitedAccountIfNecessary(GlobalStore store, int loggedOutAccountId) async {
// If account is not logged out yet, do nothing.
if (store.getAccount(loggedOutAccountId) != null) return;

// If the logged-out account is different than the last visited one, do nothing.
if (loggedOutAccountId != store.settings.getInt(IntGlobalSetting.lastVisitedAccountId)) {
return;
}

await store.settings.setInt(IntGlobalSetting.lastVisitedAccountId, null);
}

Future<void> unregisterToken(GlobalStore globalStore, int accountId) async {
final account = globalStore.getAccount(accountId);
if (account == null) return; // TODO(log)
Expand Down
54 changes: 50 additions & 4 deletions lib/model/database.dart
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@ class GlobalSettings extends Table {
.nullable()();

// If adding a new column to this table, consider whether [BoolGlobalSettings]
// can do the job instead (by adding a value to the [BoolGlobalSetting] enum).
// or [IntGlobalSettings] can do the job instead (by adding a value to the
// [BoolGlobalSetting] or [IntGlobalSetting] enum).
// That way is more convenient, when it works, because
// it avoids a migration and therefore several added copies of our schema
// in the Drift generated files.
Expand All @@ -50,6 +51,9 @@ class GlobalSettings extends Table {
/// referring to a possible setting from [BoolGlobalSetting].
/// For settings in [BoolGlobalSetting] without a row in this table,
/// the setting's value is that of [BoolGlobalSetting.default_].
///
/// See also:
/// - [IntGlobalSettings], the int-valued counterpart of this table.
@DataClassName('BoolGlobalSettingRow')
class BoolGlobalSettings extends Table {
/// The setting's name, a possible name from [BoolGlobalSetting].
Expand All @@ -73,6 +77,37 @@ class BoolGlobalSettings extends Table {
Set<Column<Object>>? get primaryKey => {name};
}

/// The table of the user's int-valued, account-independent settings.
///
/// These apply across all the user's accounts on this client
/// (i.e. on this install of the app on this device).
///
/// Each row is a [IntGlobalSettingRow],
/// referring to a possible setting from [IntGlobalSetting].
/// For settings in [IntGlobalSetting] without a row in this table,
/// the setting's value is `null`.
///
/// See also:
/// - [BoolGlobalSettings], the bool-valued counterpart of this table.
@DataClassName('IntGlobalSettingRow')
class IntGlobalSettings extends Table {
Copy link
Collaborator

@chrisbobbe chrisbobbe Aug 8, 2025

Choose a reason for hiding this comment

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

The commit 5cfd4ae, which added BoolGlobalSettings, included a lot of useful material that I think should be easy to propagate to this new thing:

(EDIT: and I see some of these have actually been addressed in the latest revision; I'll strike out those parts. 🙂)

  • The commit message points to why the new thing is helpful, in fact as soon as the summary line
  • An implementation comment in GlobalSettings saying "consider whether [etc.] can do the job instead", which helps us get the most usefulness from the thing. Let's change that comment so that it also mentions the int global settings
  • Dartdocs on BoolGlobalSettings and its fields. (Let's also add bidirectional "See also:" notes in that class's dartdoc and in IntGlobalSettings's.)
  • Ditto the BoolGlobalSetting enum, and it also got this helpful-looking implementation comment:
      // Former settings which might exist in the database,
      // whose names should therefore not be reused:
      // (this list is empty so far)
    (No need to add a placeholderIgnore member, though; the pseudo-setting we're adding here isn't an "experimental feature" setting and we don't plan to remove it.)
  • Tests

/// The setting's name, a possible name from [IntGlobalSetting].
///
/// The table may have rows where [name] is not the name of any
/// enum value in [IntGlobalSetting].
/// This happens if the app has previously run at a future or modified
/// version which had additional values in that enum,
/// and the user set one of those additional settings.
/// The app ignores any such unknown rows.
TextColumn get name => text()();

/// The user's chosen value for the setting.
IntColumn get value => integer()();

@override
Set<Column<Object>>? get primaryKey => {name};
}

/// The table of [Account] records in the app's database.
class Accounts extends Table {
/// The ID of this account in the app's local database.
Expand Down Expand Up @@ -116,7 +151,7 @@ class UriConverter extends TypeConverter<Uri, String> {
@override Uri fromSql(String fromDb) => Uri.parse(fromDb);
}

@DriftDatabase(tables: [GlobalSettings, BoolGlobalSettings, Accounts])
@DriftDatabase(tables: [GlobalSettings, BoolGlobalSettings, IntGlobalSettings, Accounts])
class AppDatabase extends _$AppDatabase {
AppDatabase(super.e);

Expand All @@ -129,7 +164,7 @@ class AppDatabase extends _$AppDatabase {
// information on using the build_runner.
// * Write a migration in `_migrationSteps` below.
// * Write tests.
static const int latestSchemaVersion = 9; // See note.
static const int latestSchemaVersion = 10; // See note.

@override
int get schemaVersion => latestSchemaVersion;
Expand Down Expand Up @@ -200,7 +235,10 @@ class AppDatabase extends _$AppDatabase {
// assume there wasn't also the legacy app before that.
await m.database.update(schema.globalSettings).write(
RawValuesInsertable({'legacy_upgrade_state': Constant('noLegacy')}));
}
},
from9To10: (m, schema) async {
await m.createTable(schema.intGlobalSettings);
},
);

Future<void> _createLatestSchema(Migrator m) async {
Expand Down Expand Up @@ -256,6 +294,14 @@ class AppDatabase extends _$AppDatabase {
return result;
}

Future<Map<IntGlobalSetting, int>> getIntGlobalSettings() async {
return {
for (final row in await select(intGlobalSettings).get())
if (IntGlobalSetting.byName(row.name) case final setting?)
setting: row.value
};
}

Future<int> createAccount(AccountsCompanion values) async {
try {
return await into(accounts).insert(values);
Expand Down
Loading