Skip to content

Commit

Permalink
Added initialisation error handler to example app
Browse files Browse the repository at this point in the history
Minor improvements to example app
  • Loading branch information
JaffaKetchup committed Mar 17, 2024
1 parent b31b096 commit 767581f
Show file tree
Hide file tree
Showing 7 changed files with 187 additions and 53 deletions.
104 changes: 62 additions & 42 deletions example/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import 'package:google_fonts/google_fonts.dart';
import 'package:provider/provider.dart';

import 'screens/configure_download/state/configure_download_provider.dart';
import 'screens/initialisation_error/initialisation_error.dart';
import 'screens/main/main.dart';
import 'screens/main/pages/downloading/state/downloading_provider.dart';
import 'screens/main/pages/map/state/map_provider.dart';
Expand All @@ -20,55 +21,74 @@ void main() async {
),
);

// TODO: Implement error handling
await FMTCObjectBoxBackend().initialise();
Object? initErr;
try {
await FMTCObjectBoxBackend().initialise();
} catch (err) {
initErr = err;
}

runApp(const _AppContainer());
runApp(_AppContainer(initialisationError: initErr));
}

class _AppContainer extends StatelessWidget {
const _AppContainer();
const _AppContainer({
required this.initialisationError,
});

final Object? initialisationError;

@override
Widget build(BuildContext context) => MultiProvider(
providers: [
ChangeNotifierProvider(create: (_) => GeneralProvider()),
ChangeNotifierProvider(
create: (_) => MapProvider(),
lazy: true,
),
ChangeNotifierProvider(
create: (_) => RegionSelectionProvider(),
lazy: true,
),
ChangeNotifierProvider(
create: (_) => ConfigureDownloadProvider(),
lazy: true,
Widget build(BuildContext context) {
final themeData = ThemeData(
brightness: Brightness.dark,
useMaterial3: true,
textTheme: GoogleFonts.ubuntuTextTheme(ThemeData.dark().textTheme),
colorSchemeSeed: Colors.red,
switchTheme: SwitchThemeData(
thumbIcon: MaterialStateProperty.resolveWith(
(states) => Icon(
states.contains(MaterialState.selected) ? Icons.check : Icons.close,
),
ChangeNotifierProvider(
create: (_) => DownloadingProvider(),
lazy: true,
),
],
child: MaterialApp(
title: 'FMTC Demo',
theme: ThemeData(
brightness: Brightness.dark,
useMaterial3: true,
textTheme: GoogleFonts.ubuntuTextTheme(const TextTheme()),
colorSchemeSeed: Colors.red,
switchTheme: SwitchThemeData(
thumbIcon: MaterialStateProperty.resolveWith(
(states) => Icon(
states.contains(MaterialState.selected)
? Icons.check
: Icons.close,
),
),
),
),
debugShowCheckedModeBanner: false,
home: const MainScreen(),
),
),
);

if (initialisationError case final err?) {
return MaterialApp(
title: 'FMTC Demo (Initialisation Error)',
theme: themeData,
home: InitialisationError(err: err),
);
}

return MultiProvider(
providers: [
ChangeNotifierProvider(
create: (_) => GeneralProvider(),
),
ChangeNotifierProvider(
create: (_) => MapProvider(),
lazy: true,
),
ChangeNotifierProvider(
create: (_) => RegionSelectionProvider(),
lazy: true,
),
ChangeNotifierProvider(
create: (_) => ConfigureDownloadProvider(),
lazy: true,
),
ChangeNotifierProvider(
create: (_) => DownloadingProvider(),
lazy: true,
),
],
child: MaterialApp(
title: 'FMTC Demo',
theme: themeData,
home: const MainScreen(),
),
);
}
}
16 changes: 7 additions & 9 deletions example/lib/screens/export_import/components/import.dart
Original file line number Diff line number Diff line change
Expand Up @@ -113,15 +113,13 @@ class _ImportState extends State<Import> {
title: Text(storeName),
subtitle: FutureBuilder(
future: FMTCStore(storeName).manage.ready,
builder: (context, snapshot) {
if (!snapshot.hasData) {
return const Text('Checking for conflicts...');
}
if (snapshot.data!) {
return const Text('Conflicts with existing store');
}
return const SizedBox.shrink();
},
builder: (context, snapshot) => Text(
switch (snapshot.data) {
null => 'Checking for conflicts...',
true => 'Conflicts with existing store',
false => 'No conflicts',
},
),
),
dense: true,
trailing: Row(
Expand Down
105 changes: 105 additions & 0 deletions example/lib/screens/initialisation_error/initialisation_error.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
import 'dart:io';

import 'package:flutter/material.dart';
import 'package:path/path.dart' as path;
import 'package:path_provider/path_provider.dart';

import '../../main.dart';

class InitialisationError extends StatelessWidget {
const InitialisationError({super.key, required this.err});

final Object? err;

@override
Widget build(BuildContext context) => Scaffold(
body: SingleChildScrollView(
padding: const EdgeInsets.all(32),
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Icon(Icons.error, size: 64),
const SizedBox(height: 12),
Text(
'Whoops, look like FMTC ran into an error initialising',
style: Theme.of(context)
.textTheme
.displaySmall!
.copyWith(color: Colors.white),
textAlign: TextAlign.center,
),
const SizedBox(height: 32),
SelectableText(
'Type: ${err.runtimeType}',
style: Theme.of(context).textTheme.headlineSmall,
textAlign: TextAlign.center,
),
SelectableText(
'Error: $err',
style: Theme.of(context).textTheme.bodyLarge,
textAlign: TextAlign.center,
),
const SizedBox(height: 32),
Text(
'We recommend trying to delete the existing root, as it may '
'have become corrupt.\nPlease be aware that this will delete '
'any cached data, and will cause the app to restart.',
style: Theme.of(context)
.textTheme
.bodyLarge!
.copyWith(color: Colors.white),
textAlign: TextAlign.center,
),
const SizedBox(height: 16),
OutlinedButton(
onPressed: () async {
void showFailure() {
if (context.mounted) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text(
"Unfortuately, that didn't work. Try clearing "
"the app's storage and cache manually.",
),
),
);
}
}

final dir = Directory(
path.join(
(await getApplicationDocumentsDirectory())
.absolute
.path,
'fmtc',
),
);

if (!await dir.exists()) {
showFailure();
return;
}

try {
await dir.delete(recursive: true);
} on FileSystemException {
showFailure();
rethrow;
}

runApp(const SizedBox.shrink());

main();
},
child: const Text(
'Reset FMTC & attempt re-initialisation',
textAlign: TextAlign.center,
),
),
],
),
),
),
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ class DownloadLayout extends StatelessWidget {
const SizedBox(width: 16),
Expanded(
child: Table(
defaultVerticalAlignment: TableCellVerticalAlignment.middle,
children: [
TableRow(
children: [
Expand All @@ -73,12 +74,12 @@ class DownloadLayout extends StatelessWidget {
children: [
StatDisplay(
statistic:
'${download.skippedTiles} (${download.skippedTiles == 0 ? 0 : (100 - ((download.cachedTiles - download.skippedTiles) / download.cachedTiles) * 100).toStringAsFixed(1)}%)',
'${download.skippedTiles} (${download.skippedTiles == 0 ? 0 : (100 - ((download.cachedTiles - download.skippedTiles) / download.cachedTiles) * 100).clamp(double.minPositive, 100).toStringAsFixed(1)}%)',
description: 'skipped tiles (% saving)',
),
StatDisplay(
statistic:
'${(download.skippedSize * 1024).asReadableSize} (${download.skippedTiles == 0 ? 0 : (100 - ((download.cachedSize - download.skippedSize) / download.cachedSize) * 100).toStringAsFixed(1)}%)',
'${(download.skippedSize * 1024).asReadableSize} (${download.skippedTiles == 0 ? 0 : (100 - ((download.cachedSize - download.skippedSize) / download.cachedSize) * 100).clamp(double.minPositive, 100).toStringAsFixed(1)}%)',
description: 'skipped size (% saving)',
),
],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ class _DownloadingPageState extends State<DownloadingPage>
);
}

// TODO: Make responsive
return DownloadLayout(
storeDirectory:
context.select<RegionSelectionProvider, FMTCStore?>(
Expand Down
1 change: 1 addition & 0 deletions example/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ dependencies:
latlong2: ^0.9.0
osm_nominatim: ^3.0.0
path: ^1.9.0
path_provider: ^2.1.2
provider: ^6.1.2
stream_transform: ^2.1.0
validators: ^3.0.0
Expand Down
8 changes: 8 additions & 0 deletions lib/src/backend/impls/objectbox/backend/internal.dart
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ class _ObjectBoxBackendImpl implements FMTCObjectBoxBackendInternal {
void get expectInitialised => _sendPort ?? (throw RootUnavailable());

// Worker communication protocol storage

SendPort? _sendPort;
final _workerResOneShot = <int, Completer<Map<String, dynamic>?>>{};
final _workerResStreamed = <int, StreamSink<Map<String, dynamic>?>>{};
Expand All @@ -30,9 +31,12 @@ class _ObjectBoxBackendImpl implements FMTCObjectBoxBackendInternal {
late StreamSubscription<dynamic> _workerHandler;

// `removeOldestTilesAboveLimit` tracking & debouncing

Timer? _rotalDebouncer;
String? _rotalStore;

// Define communicators

Future<Map<String, dynamic>?> _sendCmdOneShot({
required _WorkerCmdType type,
Map<String, dynamic> args = const {},
Expand Down Expand Up @@ -99,6 +103,8 @@ class _ObjectBoxBackendImpl implements FMTCObjectBoxBackendInternal {
}
}

// Lifecycle implementations

Future<void> initialise({
required String? rootDirectory,
required int maxDatabaseSize,
Expand Down Expand Up @@ -249,6 +255,8 @@ class _ObjectBoxBackendImpl implements FMTCObjectBoxBackendInternal {
FMTCBackendAccessThreadSafe.internal = null;
}

// Implementation & worker connectors

@override
Future<double> realSize() async =>
(await _sendCmdOneShot(type: _WorkerCmdType.realSize))!['size'];
Expand Down

0 comments on commit 767581f

Please sign in to comment.