[client] Support server-side logouts

This commit is contained in:
Abhishek Shroff
2024-09-18 13:16:25 +05:30
parent e913999aa7
commit 3f0ec0fd4c
7 changed files with 102 additions and 44 deletions

View File

@@ -6,7 +6,9 @@ import 'package:phylum/app_shortcuts.dart';
import 'package:phylum/integrations/download_manager.dart';
import 'package:phylum/libphylum/phylum_account.dart';
import 'package:phylum/ui/app/app_layout.dart';
import 'package:phylum/ui/app/app_logout.dart';
import 'package:phylum/ui/app/nav_forward.dart';
import 'package:phylum/util/logging.dart';
import 'package:provider/provider.dart';
class PhylumApp extends StatefulWidget {
@@ -22,57 +24,100 @@ class _PhylumAppState extends State<PhylumApp> {
final historyManager = NavForwardManager();
final navigatorKey = GlobalKey<NavigatorState>();
late final _appRouter = GoRouter(
navigatorKey: navigatorKey,
routes: [
GoRoute(
name: 'root',
path: '/',
redirect: (context, state) => '/home',
),
GoRoute(
name: 'home',
path: '/home',
pageBuilder: (context, state) {
final userHome = context.read<PhylumAccount>().userHome;
return NoTransitionPage(
name: state.name,
child: AppLayout(folderId: userHome),
arguments: userHome,
);
},
),
GoRoute(
name: 'folder',
path: '/folders/:id',
pageBuilder: (context, state) => NoTransitionPage(
name: state.name,
child: AppLayout(folderId: state.pathParameters['id']!),
arguments: state.pathParameters['id'],
),
),
],
observers: [
historyManager.navObserver,
],
);
@override
void initState() {
super.initState();
widget.account.api.addErrorResponseListener((e) {
if (e.code == "credentials_invalid") {
logger.i('Invalid Credentials - Logging out');
context.read<PhylumAccount>().logOut();
}
});
}
@override
Widget build(BuildContext context) {
return MultiProvider(
key: ValueKey(widget.account.id),
providers: [
Provider.value(value: widget.account),
StateNotifierProvider<PhylumAccount, AccountState>.value(value: widget.account),
StateNotifierProvider<ApiActionQueue, ApiActionQueueState>.value(value: widget.account.actionQueue),
StateNotifierProvider<NavForwardManager, NavForwardState>.value(value: historyManager),
StateNotifierProvider<DownloadManager, DownloadManagerState>(create: (context) => DownloadManager(widget.account))
],
child: MaterialApp.router(
builder: (context, child) {
final ready = context.select<AccountState, bool>((state) => state == AccountState.ready);
if (ready) {
return MaterialApp.router(
key: ValueKey(widget.account.id),
title: 'Phylum',
debugShowCheckedModeBanner: false,
theme: ThemeData(colorScheme: ColorScheme.fromSeed(seedColor: Colors.orange)),
darkTheme: ThemeData.dark(),
routerConfig: _appRouter,
shortcuts: getAppShortcuts(),
);
}
return MaterialApp.router(
key: ValueKey('${widget.account.id}-notready'),
title: 'Phylum',
debugShowCheckedModeBanner: false,
theme: ThemeData(colorScheme: ColorScheme.fromSeed(seedColor: Colors.orange)),
darkTheme: ThemeData.dark(),
routerConfig: createLogoutRouter(),
shortcuts: getAppShortcuts(),
);
},
);
}
RouterConfig<Object> createLogoutRouter() => GoRouter(
errorBuilder: (context, state) => const AppLogout(),
routes: [],
);
MaterialApp createRouter(RouterConfig<Object> router) => MaterialApp.router(
key: ValueKey(widget.account),
title: 'Phylum',
debugShowCheckedModeBanner: false,
theme: ThemeData(colorScheme: ColorScheme.fromSeed(seedColor: Colors.orange)),
darkTheme: ThemeData.dark(),
routerConfig: createRouter(widget.account),
routerConfig: router,
shortcuts: getAppShortcuts(),
),
);
}
GoRouter createRouter(PhylumAccount account) => GoRouter(
navigatorKey: navigatorKey,
routes: [
GoRoute(
name: 'root',
path: '/',
redirect: (context, state) => '/home',
),
GoRoute(
name: 'home',
path: '/home',
pageBuilder: (context, state) => NoTransitionPage(
name: state.name,
child: AppLayout(folderId: account.userHome),
arguments: account.userHome,
),
),
GoRoute(
name: 'folder',
path: '/folders/:id',
pageBuilder: (context, state) => NoTransitionPage(
name: state.name,
child: AppLayout(folderId: state.pathParameters['id']!),
arguments: state.pathParameters['id'],
),
),
],
observers: [
historyManager.navObserver,
],
);
}

View File

@@ -24,6 +24,6 @@ class AppDatabase extends _$AppDatabase {
});
static QueryExecutor _openConnection(String id) {
return openDatabase(storageDir: storageDir, tmpDir: tmpDir, name: 'phylum-$id.db');
return openDatabase(storageDir: storageDir, tmpDir: tmpDir, name: '$id-drift');
}
}

View File

@@ -77,6 +77,11 @@ class PhylumAccount extends Account<PhylumApiResponse, PhylumApiErrorResponse, P
await registerListener(actionQueue);
}
@override
Future<void> clearData() async {
return db.close();
}
Future<void> addAction(ApiAction<PhylumAccount> action) async {
return actionQueue.addAction(action);
}
@@ -87,7 +92,7 @@ class PhylumAccount extends Account<PhylumApiResponse, PhylumApiErrorResponse, P
account._accessToken = response['access_token'];
final userMap = response['user'];
account.userEmail = userMap['email'];
account.userEmail = userMap['username'];
account.userName = userMap['name'];
account.userHome = userMap['home'];

View File

@@ -1,5 +1,6 @@
import 'dart:io';
import 'package:drift/drift.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_state_notifier/flutter_state_notifier.dart';
@@ -15,6 +16,7 @@ import 'package:phylum/libphylum/actions/deserializers.dart';
import 'package:phylum/libphylum/db/db.dart';
import 'package:phylum/libphylum/phylum_account.dart';
import 'package:phylum/ui/login_page.dart';
import 'package:phylum/util/logging.dart';
import 'package:provider/provider.dart';
const storageDir = String.fromEnvironment("STORAGE_DIR");
@@ -23,8 +25,11 @@ void main() async {
WidgetsFlutterBinding.ensureInitialized();
PhylumDirectories.instance.initialize();
OTL.logger = Logger(level: Level.info);
logger = Logger(level: Level.info);
OTL.logger = logger;
GoRouter.optionURLReflectsImperativeAPIs = true;
// We use multiple distinct databases for different accounts, so this is expected behavior
driftRuntimeOptions.dontWarnAboutMultipleDatabases = true;
if (kIsWeb) {
Hive.init(null, backendPreference: HiveStorageBackendPreference.webWorker);

View File

@@ -0,0 +1,3 @@
import 'package:logger/logger.dart';
late final Logger logger;

View File

@@ -577,8 +577,8 @@ packages:
dependency: "direct main"
description:
path: "."
ref: e82fe8c91ab70a4517375ee6a64788c3f93f9448
resolved-ref: e82fe8c91ab70a4517375ee6a64788c3f93f9448
ref: d459579e4cf51cb1fe5f0d26617cfe839e39d0f8
resolved-ref: d459579e4cf51cb1fe5f0d26617cfe839e39d0f8
url: "https://codeberg.org/shroff/offtheline.git"
source: git
version: "0.13.0"

View File

@@ -21,7 +21,7 @@ dependencies:
offtheline:
git:
url: https://codeberg.org/shroff/offtheline.git
ref: e82fe8c91ab70a4517375ee6a64788c3f93f9448
ref: d459579e4cf51cb1fe5f0d26617cfe839e39d0f8
open_file:
path:
path_provider:
@@ -42,4 +42,4 @@ dev_dependencies:
build_runner: ^2.4.12
flutter:
uses-material-design: true
uses-material-design: true