better app initialization with bangs
This commit is contained in:
@@ -0,0 +1,54 @@
|
||||
import 'package:bang_navigator/features/about/data/repositories/package_info_repository.dart';
|
||||
import 'package:bang_navigator/features/bangs/domain/repositories/sync.dart';
|
||||
import 'package:bang_navigator/features/search_browser/domain/services/session.dart';
|
||||
import 'package:bang_navigator/features/settings/data/repositories/settings_repository.dart';
|
||||
import 'package:exceptions/exceptions.dart';
|
||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||
|
||||
part 'app_initialization.g.dart';
|
||||
|
||||
@Riverpod(keepAlive: true)
|
||||
class AppInitializationService extends _$AppInitializationService {
|
||||
/// Will de facto restart the app
|
||||
Future<void> reinitialize() async {
|
||||
ref.invalidateSelf();
|
||||
return initialize();
|
||||
}
|
||||
|
||||
Future<void> initialize() async {
|
||||
state = await Result.fromAsync(() async {
|
||||
final errors = <ErrorMessage>[];
|
||||
|
||||
//Ensure Package info is loaded
|
||||
await ref.read(packageInfoProvider.future);
|
||||
|
||||
final syncResults = await ref
|
||||
.read(bangSyncRepositoryProvider.notifier)
|
||||
.syncAllBangGroups(syncInterval: const Duration(days: 7));
|
||||
|
||||
for (final MapEntry(value: result) in syncResults.entries) {
|
||||
result.onFailure(errors.add);
|
||||
}
|
||||
|
||||
final settings = await ref.read(settingsRepositoryProvider.future);
|
||||
if (settings.incognitoMode) {
|
||||
await ref.read(sessionServiceProvider.notifier).clearAllData();
|
||||
}
|
||||
|
||||
if (settings.kagiSession case final String session) {
|
||||
if (session.isNotEmpty) {
|
||||
await ref
|
||||
.read(sessionServiceProvider.notifier)
|
||||
.setKagiSession(session);
|
||||
}
|
||||
}
|
||||
|
||||
return (initialized: true, errors: errors);
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
Result<({bool initialized, List<ErrorMessage> errors})> build() {
|
||||
return Result.success((initialized: false, errors: List.empty()));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'app_initialization.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// RiverpodGenerator
|
||||
// **************************************************************************
|
||||
|
||||
String _$appInitializationServiceHash() =>
|
||||
r'7b36828c2368c3b3a97b799dd8192854629c8379';
|
||||
|
||||
/// See also [AppInitializationService].
|
||||
@ProviderFor(AppInitializationService)
|
||||
final appInitializationServiceProvider = NotifierProvider<
|
||||
AppInitializationService,
|
||||
Result<({bool initialized, List<ErrorMessage> errors})>>.internal(
|
||||
AppInitializationService.new,
|
||||
name: r'appInitializationServiceProvider',
|
||||
debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product')
|
||||
? null
|
||||
: _$appInitializationServiceHash,
|
||||
dependencies: null,
|
||||
allTransitiveDependencies: null,
|
||||
);
|
||||
|
||||
typedef _$AppInitializationService
|
||||
= Notifier<Result<({bool initialized, List<ErrorMessage> errors})>>;
|
||||
// ignore_for_file: type=lint
|
||||
// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member
|
||||
@@ -44,10 +44,6 @@ class SessionService extends _$SessionService {
|
||||
await webViewLoaded.future.whenComplete(() => headlessWebView..dispose());
|
||||
}
|
||||
|
||||
void initializationDone() {
|
||||
state = true;
|
||||
}
|
||||
|
||||
@override
|
||||
bool build() => false;
|
||||
void build() {}
|
||||
}
|
||||
|
||||
@@ -6,12 +6,12 @@ part of 'session.dart';
|
||||
// RiverpodGenerator
|
||||
// **************************************************************************
|
||||
|
||||
String _$sessionServiceHash() => r'48126bad2cb8d5c38296307bede64bf549365acf';
|
||||
String _$sessionServiceHash() => r'fd2cd03bbf2dd254bb19e541c71a6fb249f5a7bb';
|
||||
|
||||
/// See also [SessionService].
|
||||
@ProviderFor(SessionService)
|
||||
final sessionServiceProvider =
|
||||
AutoDisposeNotifierProvider<SessionService, bool>.internal(
|
||||
AutoDisposeNotifierProvider<SessionService, void>.internal(
|
||||
SessionService.new,
|
||||
name: r'sessionServiceProvider',
|
||||
debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product')
|
||||
@@ -21,6 +21,6 @@ final sessionServiceProvider =
|
||||
allTransitiveDependencies: null,
|
||||
);
|
||||
|
||||
typedef _$SessionService = AutoDisposeNotifier<bool>;
|
||||
typedef _$SessionService = AutoDisposeNotifier<void>;
|
||||
// ignore_for_file: type=lint
|
||||
// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member
|
||||
|
||||
+46
-36
@@ -1,11 +1,10 @@
|
||||
import 'package:bang_navigator/core/logger.dart';
|
||||
import 'package:bang_navigator/core/providers.dart';
|
||||
import 'package:bang_navigator/features/about/data/repositories/package_info_repository.dart';
|
||||
import 'package:bang_navigator/features/bangs/domain/repositories/sync.dart';
|
||||
import 'package:bang_navigator/features/search_browser/domain/services/session.dart';
|
||||
import 'package:bang_navigator/features/settings/data/repositories/settings_repository.dart';
|
||||
import 'package:bang_navigator/domain/services/app_initialization.dart';
|
||||
import 'package:bang_navigator/presentation/hooks/on_initialization.dart';
|
||||
import 'package:bang_navigator/presentation/widgets/failure_widget.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||
import 'package:home_widget/home_widget.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
|
||||
@@ -39,28 +38,9 @@ void main() async {
|
||||
builder: (context, ref, child) {
|
||||
useOnInitialization(
|
||||
() async {
|
||||
await ref.read(packageInfoProvider.future);
|
||||
|
||||
await ref
|
||||
.read(bangSyncRepositoryProvider.notifier)
|
||||
.syncAllBangGroups(syncInterval: const Duration(days: 7));
|
||||
|
||||
final settings =
|
||||
await ref.read(settingsRepositoryProvider.future);
|
||||
|
||||
if (settings.incognitoMode) {
|
||||
await ref.read(sessionServiceProvider.notifier).clearAllData();
|
||||
}
|
||||
|
||||
if (settings.kagiSession case final String session) {
|
||||
if (session.isNotEmpty) {
|
||||
await ref
|
||||
.read(sessionServiceProvider.notifier)
|
||||
.setKagiSession(session);
|
||||
}
|
||||
}
|
||||
|
||||
ref.read(sessionServiceProvider.notifier).initializationDone();
|
||||
.read(appInitializationServiceProvider.notifier)
|
||||
.initialize();
|
||||
},
|
||||
);
|
||||
|
||||
@@ -76,18 +56,11 @@ class MainApp extends HookConsumerWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final isInitialized = ref.watch(sessionServiceProvider);
|
||||
final initializationResult = ref.watch(appInitializationServiceProvider);
|
||||
final router = ref.watch(routerProvider);
|
||||
|
||||
if (!isInitialized) {
|
||||
return const Center(
|
||||
child: CircularProgressIndicator(),
|
||||
);
|
||||
}
|
||||
|
||||
return MaterialApp.router(
|
||||
debugShowCheckedModeBanner: false,
|
||||
theme: ThemeData(
|
||||
final themeData = useMemoized(
|
||||
() => ThemeData(
|
||||
useMaterial3: true,
|
||||
brightness: Brightness.dark,
|
||||
// colorScheme: ColorScheme.fromSeed(
|
||||
@@ -95,7 +68,44 @@ class MainApp extends HookConsumerWidget {
|
||||
// brightness: Brightness.dark,
|
||||
// ),
|
||||
),
|
||||
routerConfig: router,
|
||||
);
|
||||
|
||||
return initializationResult.fold(
|
||||
(initializationState) {
|
||||
if (!initializationState.initialized) {
|
||||
return const Center(
|
||||
child: CircularProgressIndicator(),
|
||||
);
|
||||
}
|
||||
|
||||
return MaterialApp.router(
|
||||
debugShowCheckedModeBanner: false,
|
||||
theme: themeData,
|
||||
routerConfig: router,
|
||||
);
|
||||
},
|
||||
onFailure: (errorMessage) {
|
||||
return MaterialApp(
|
||||
debugShowCheckedModeBanner: false,
|
||||
theme: themeData,
|
||||
home: Scaffold(
|
||||
appBar: AppBar(
|
||||
title: const Text('Initiallization Error'),
|
||||
),
|
||||
body: Center(
|
||||
child: FailureWidget(
|
||||
title: 'Could not initialize App',
|
||||
exception: errorMessage.toString(),
|
||||
onRetry: () async {
|
||||
await ref
|
||||
.read(appInitializationServiceProvider.notifier)
|
||||
.reinitialize();
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user