Skip to content
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

v10: Improved multi-store usage support #156

Draft
wants to merge 73 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
73 commits
Select commit Hold shift + click to select a range
15a82c5
Added support for using multiple stores simultaneously in the `FMTCTi…
JaffaKetchup May 24, 2024
ecebf42
Merge branch 'main' into multi-store-provider
JaffaKetchup May 27, 2024
692fb6b
Updated version to v10
JaffaKetchup May 28, 2024
9c0ca70
Removed deprecations
JaffaKetchup May 28, 2024
6778e8a
Updated versioning and CHANGELOG
JaffaKetchup May 28, 2024
99826bd
Started update of example app
JaffaKetchup Jun 12, 2024
8f5ce14
Improved performance of recovery updates during bulk downloading (onl…
JaffaKetchup Jun 12, 2024
37fc1bf
More example app improvements
JaffaKetchup Jun 18, 2024
0e89c6e
Added improved multiple stores support to `FMTCTileProvider`
JaffaKetchup Jul 4, 2024
63c6704
Implemented initial tile loading debug system
JaffaKetchup Jul 10, 2024
603e523
Minor meta refactoring and renaming
JaffaKetchup Jul 11, 2024
31b8248
Minor meta refactoring and renaming
JaffaKetchup Jul 11, 2024
6c74803
Minor meta refactoring and renaming
JaffaKetchup Jul 11, 2024
2db92df
Added `FMTCTileProvider.tileLoadingDebugger` and related classes
JaffaKetchup Jul 14, 2024
d009ba7
Prepare for v10.0.0-dev.2 prerelease
JaffaKetchup Jul 15, 2024
298f8dc
Removed completed TODOs
JaffaKetchup Jul 15, 2024
d61250d
Fixed dependency versions
JaffaKetchup Jul 15, 2024
9d2e1de
Fixed discrepancy between same property name (`<track/record>HitsAndM…
JaffaKetchup Jul 15, 2024
756ff11
Fixed accidental dependency pinning
JaffaKetchup Jul 15, 2024
8b645ba
Improved quality/accuracy of circle tile generation & count algorithm
JaffaKetchup Jul 15, 2024
8e9eaf7
Merge branch 'main' into multi-store-provider
JaffaKetchup Jul 16, 2024
2a6bcac
Improved circle tile generation/count algorithms
JaffaKetchup Jul 16, 2024
cb2a261
Fixed lint & regenerated ObjectBox
JaffaKetchup Jul 16, 2024
2bb3db6
Fixed bug within recovery system initialisation
JaffaKetchup Jul 16, 2024
9102680
Removed `setMetadata` worker function in favour of `setBulkMetadata`
JaffaKetchup Jul 20, 2024
3affe10
Minor documentation improvements
JaffaKetchup Jul 22, 2024
73d1d1e
Improved example application
JaffaKetchup Jul 24, 2024
57f680b
Minor example application improvement
JaffaKetchup Jul 24, 2024
26211aa
Improved example application
JaffaKetchup Jul 24, 2024
0c76e3f
Minor example application improvements
JaffaKetchup Jul 28, 2024
b9b9e55
Escape `link` & `delimiter` in `urlTransformerOmitKeyValues` internal…
JaffaKetchup Jul 29, 2024
b351bc1
Updated CHANGELOG
JaffaKetchup Jul 29, 2024
a244fe1
Merge branch 'main' into multi-store-provider
JaffaKetchup Aug 7, 2024
9ce9f67
Removed `FMTCTileProviderSettings` & transferred properties to `FMTCT…
JaffaKetchup Aug 9, 2024
503cfef
Minor documentation improvements
JaffaKetchup Aug 9, 2024
3dcdfe5
Added export functionality to example app
JaffaKetchup Aug 11, 2024
348aac3
Improved exporting & importing flows
JaffaKetchup Aug 12, 2024
169f82e
Implemented import flow in example application
JaffaKetchup Aug 12, 2024
e4d6b55
Added return of number of exported tiles to `RootExternal.export`
JaffaKetchup Aug 13, 2024
0725095
Added bulk download support to example app
JaffaKetchup Aug 13, 2024
c96cb73
Added `MultiRegion`
JaffaKetchup Aug 15, 2024
f61e355
Improved (by a lot) tile loading with `_FMTCImageProvider` when fetch…
JaffaKetchup Aug 15, 2024
5f3a3a5
Updated CHANGELOG
JaffaKetchup Aug 15, 2024
0b87644
Minor example application improvements
JaffaKetchup Aug 15, 2024
40d345f
Minor bug fix in example app
JaffaKetchup Aug 19, 2024
4d441a6
Updated Android example app build config
JaffaKetchup Aug 19, 2024
771186d
Removed unnecessary dependencies from example application
JaffaKetchup Aug 19, 2024
d0809ae
Upgrade Kotlin version for example app
JaffaKetchup Aug 19, 2024
9e72a67
Updated Gradle version for example app
JaffaKetchup Aug 19, 2024
05c0f0c
Removed broken workaround from Android example app config
JaffaKetchup Aug 19, 2024
8d9de87
Merge branch 'main' into multi-store-provider
JaffaKetchup Aug 19, 2024
e284f49
Fixed bug where `deleteStore` never completed (but was successful)
JaffaKetchup Aug 19, 2024
bd57c2b
Added `FMTCTileProvider.fakeNetworkDisconnect` for testing (and refle…
JaffaKetchup Aug 21, 2024
d4f917a
Added compact store list layout design for example app
JaffaKetchup Aug 21, 2024
c50a670
Improved example app
JaffaKetchup Aug 22, 2024
a77390f
Fixed bug in example app
JaffaKetchup Aug 24, 2024
2665573
Re-organized & refactored example app source
JaffaKetchup Sep 9, 2024
3fe9e63
Prepare example application for new region selection UI
JaffaKetchup Sep 10, 2024
702dfb5
Improved example app
JaffaKetchup Sep 21, 2024
23e6408
Improved example app
JaffaKetchup Sep 30, 2024
ef8d0e5
Improved example application
JaffaKetchup Sep 30, 2024
9403e8f
Example app experimentation
JaffaKetchup Oct 2, 2024
40acefe
Example app experimentation
JaffaKetchup Oct 3, 2024
ec2130e
Example app experimentation
JaffaKetchup Oct 3, 2024
a3eae60
Added support for `null` values in `FMTCTileProvider.storeNames` to e…
JaffaKetchup Oct 9, 2024
458a6c3
Improved example app
JaffaKetchup Oct 9, 2024
eae1ed7
Fixed bug in bulk downloader where the final tile event was repeated …
JaffaKetchup Oct 14, 2024
c5c223c
Improved example app
JaffaKetchup Oct 15, 2024
699b130
Improved example app
JaffaKetchup Oct 16, 2024
3d11ef7
Improved example app
JaffaKetchup Oct 21, 2024
17f01c0
Prepared for prerelease -dev.6
JaffaKetchup Oct 24, 2024
8a18390
Improved example app
JaffaKetchup Oct 27, 2024
0aa119d
Minor improvement
JaffaKetchup Nov 10, 2024
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
42 changes: 40 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,19 +18,57 @@ Many thanks to my sponsors, no matter how much or how little they donated. Spons

# Changelog

## [10.0.0] - "Better Browsing" - 2024/XX/XX

This update builds on v9 to fully embrace the new many-to-many relationship between tiles and stores, which allows for more flexibility when constructing the `FMTCTileProvider`.
This allows a new paradigm to be used: stores may now be treated as bulk downloaded regions, and all the regions/stores can be used at once - no more switching between them. This allows huge amounts of flexibility and a better UX in a complex application. Additionally, each store may now have its own `BrowseStoreStrategy` when browsing, which allows more flexibility: for example, stores may now contain more than one URL template/source, but control is retained.

Additionally, vector tiles are now supported in theory, as the internal caching/retrieval logic of the specialised `ImageProvider` has been exposed, although it is out of scope to fully implement support for it.

* Improvements to the browse caching logic and customizability
* Added support for using multiple stores simultaneously in the `FMTCTileProvider` (through the `FMTCTileProvider.allStores` & `FMTCTileProvider.multipleStores` constructors)
* Added `FMTCTileProvider.getBytes` method to expose internal caching mechanisms for external use
* Added `BrowseStoreStrategy` for increased control over caching behaviour
* Added 'tile loading interceptor' feature (`FMTCTileProvider.tileLoadingInterceptor`) to track (eg. for debugging and logging) the internal tile loading mechanisms
* Added toggle for hit/miss stat recording, to improve performance where these statistics are never read
* Replaced `FMTCTileProviderSettings.maxStoreLength` with a `maxLength` property on each store individually
* Replaced `CacheBehavior` with `BrowseLoadingStrategy`
* Replaced `FMTCBrowsingErrorHandler` with `BrowsingExceptionHandler`, which may now return bytes to be displayed instead of (re)throwing exception
* Replaced `obscureQueryParams` with more flexible `urlTransformer` (and static `FMTCTileProvider.urlTransformerOmitKeyValues` utility method to provide old behaviour with more customizability) - also applies to bulk downloading in `StoreDownload.startForeground`
* Removed `FMTCTileProviderSettings` & absorbed properties directly into `FMTCTileProvider`
* Performance of the internal tile image provider has been significantly improved when fetching images from the network URL
> There was a significant time loss due to attempting to handle the network request response as a stream of incoming bytes, which allowed for `chunkEvents` to be reported back to Flutter (allowing it to get progress updates on the state of the tile), but meant the bytes had to be collected and built manually. Removing this functionality allows the network requests to use more streamlined 'package:http' methods, which does not expose a stream of incoming bytes, meaning that bytes no longer have to be treated manually. This can save hundreds of milliseconds on tile loading - a significant time save of potentially up to ~50% in some cases!

* Improvements, additions, and removals for bulk downloadable `BaseRegion`s
* Added `MultiRegion`, which contains multiple other `BaseRegion`s
* Improved speed (by massive amounts) and accuracy & reduced memory consumption of `CircleRegion`'s tile generation & counting algorithm
* Deprecated `BaseRegion.(maybe)When` - this is easy to perform using a standard pattern-matched switch

* Changes to bulk downloading
* `DownloadProgress.latestTileEvent` is now nullable

* Exporting stores is now more stable, and has improved documentation
The method now works in a dedicated temporary environment and attempts to perform two different strategies to move/copy-and-delete the result to the specified directory at the end before failing. Improved documentation covers the potential pitfalls of permissions and now recommends exporting to an app directory, then using the system share functionality on some devices. It now also returns the number of exported tiles.

* Removed deprecated remnants from v9.*

* Other generic improvements (performance, stability, and documentation)

* Brand new example app to (partially!) showcase the new levels of flexibility and customizability

## [9.1.3] - 2024/08/19

* Fixed bug where any operation that attempted to delete tiles fatally crashed on some iOS devices
This appears to be an [ObjectBox issue](https://github.com/objectbox/objectbox-dart/issues/654) where streaming the results of a database query caused the crash. Instead, FMTC now uses a custom chunking system to avoid streaming and also avoid loading potentially many tiles into memory.

## [9.1.2] - 2024/08/07

* Fixed compilation on web platforms: FMTC now internally overrides the `FMTCObjectBoxBackend` and becomes a no-op
* Fixed compilation on web platforms: FMTC now internally overrides the `FMTCObjectBoxBackend` and becomes a no-op on non-FFI platforms
* Minor documentation improvements

## [9.1.1] - 2024/07/16

* Fixed bug where errors within the import functionality would not be catchable by the original invoker
* Fixed bug where errors within the import functionality would not always be catchable by the original invoker
* Minor other improvements

## [9.1.0] - 2024/05/27
Expand Down
11 changes: 6 additions & 5 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,23 @@

## Reporting A Bug

FMTC is a large, platform-dependent package, and there's only one person running manual tests on it before releases, so there's a decent chance that a bug you've found is actually a bug. Reporting it is always appreciated!
I try to test FMTC on as many platforms as I have access to, using a combination of automated tests and manual tests through the example application. However, I only have access to Android and Windows devices. Due to the number of platform-dependent plugins this package uses, bugs are often only present on one platform, which is often iOS. However, they can of course occur on any platform if I've missed one. Reporting any bugs you find is always appreciated!

Before reporting a bug, please:

* Check if there is already an open or closed issue that is similar to yours
* Ensure that your Flutter environment is correctly installed & set-up
* Ensure that this package, 'flutter_map', and any modules are correctly installed & set-up
* Ensure that Flutter, this package, 'flutter_map', and any modules are correctly installed & set-up
* Follow the bug reporting issue template

## Contributing Code

Contributors are always welcome, and support is always greatly appreciated! Before opening a Pull Request, however, please open a feature request or bug report to link the PR to.

Please note that all contributions may be dually licensed under an alternative proprietary license on a case-by-case basis, which grants no extra rights to contributors.

When submitting code, please:

* Keep code concise and in a similar style to surrounding code
* Document all public APIs in detail and with correct grammar
* Document all new public APIs
* Use the included linting rules
* Update the example application to appropriately consume any public API changes
* Avoid incrementing this package's version number or changelog
3 changes: 3 additions & 0 deletions example/.gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
# Custom
old_lib/

# Miscellaneous
*.class
*.log
Expand Down
10 changes: 5 additions & 5 deletions example/.metadata
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
# This file should be version controlled and should not be manually edited.

version:
revision: "29babcb32a591b9e5be8c6a6075d4fe605d46ad3"
revision: "7c6b7e9ca485f7eaaed913c6bb50f4be6da47e30"
channel: "beta"

project_type: app
Expand All @@ -13,11 +13,11 @@ project_type: app
migration:
platforms:
- platform: root
create_revision: 29babcb32a591b9e5be8c6a6075d4fe605d46ad3
base_revision: 29babcb32a591b9e5be8c6a6075d4fe605d46ad3
create_revision: 7c6b7e9ca485f7eaaed913c6bb50f4be6da47e30
base_revision: 7c6b7e9ca485f7eaaed913c6bb50f4be6da47e30
- platform: android
create_revision: 29babcb32a591b9e5be8c6a6075d4fe605d46ad3
base_revision: 29babcb32a591b9e5be8c6a6075d4fe605d46ad3
create_revision: 7c6b7e9ca485f7eaaed913c6bb50f4be6da47e30
base_revision: 7c6b7e9ca485f7eaaed913c6bb50f4be6da47e30

# User provided section

Expand Down
3 changes: 3 additions & 0 deletions example/devtools_options.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
description: This file stores settings for Dart & Flutter DevTools.
documentation: https://docs.flutter.dev/tools/devtools/extensions#configure-extension-enablement-states
extensions:
81 changes: 55 additions & 26 deletions example/lib/main.dart
Original file line number Diff line number Diff line change
@@ -1,25 +1,24 @@
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_map_tile_caching/flutter_map_tile_caching.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:provider/provider.dart';
import 'package:shared_preferences/shared_preferences.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';
import 'screens/main/pages/region_selection/state/region_selection_provider.dart';
import 'shared/state/general_provider.dart';
import 'src/screens/import/import.dart';
import 'src/screens/initialisation_error/initialisation_error.dart';
import 'src/screens/main/main.dart';
import 'src/screens/main/secondary_view/contents/home/components/stores_list/state/export_selection_provider.dart';
import 'src/screens/store_editor/store_editor.dart';
import 'src/shared/misc/shared_preferences.dart';
import 'src/shared/state/download_configuration_provider.dart';
import 'src/shared/state/download_provider.dart';
import 'src/shared/state/general_provider.dart';
import 'src/shared/state/region_selection_provider.dart';

void main() async {
WidgetsFlutterBinding.ensureInitialized();
SystemChrome.setSystemUIOverlayStyle(
const SystemUiOverlayStyle(
statusBarColor: Colors.transparent,
statusBarIconBrightness: Brightness.dark,
),
);

sharedPrefs = await SharedPreferences.getInstance();

Object? initErr;
try {
Expand All @@ -38,18 +37,45 @@ class _AppContainer extends StatelessWidget {

final Object? initialisationError;

static final _routes = <String,
({
Widget Function(BuildContext)? std,
PageRoute Function(BuildContext, RouteSettings)? custom,
})>{
MainScreen.route: (
std: (BuildContext context) => const MainScreen(),
custom: null,
),
StoreEditorPopup.route: (
std: null,
custom: (context, settings) => MaterialPageRoute(
builder: (context) => const StoreEditorPopup(),
settings: settings,
fullscreenDialog: true,
),
),
ImportPopup.route: (
std: null,
custom: (context, settings) => MaterialPageRoute(
builder: (context) => const ImportPopup(),
settings: settings,
fullscreenDialog: true,
),
),
};

@override
Widget build(BuildContext context) {
final themeData = ThemeData(
brightness: Brightness.dark,
brightness: Brightness.light,
useMaterial3: true,
textTheme: GoogleFonts.ubuntuTextTheme(ThemeData.dark().textTheme),
colorSchemeSeed: Colors.red,
textTheme: GoogleFonts.ubuntuTextTheme(ThemeData.light().textTheme),
colorSchemeSeed: Colors.teal,
switchTheme: SwitchThemeData(
thumbIcon: WidgetStateProperty.resolveWith(
(states) => Icon(
states.contains(WidgetState.selected) ? Icons.check : Icons.close,
),
(states) => states.contains(WidgetState.selected)
? const Icon(Icons.check)
: null,
),
),
);
Expand All @@ -68,26 +94,29 @@ class _AppContainer extends StatelessWidget {
create: (_) => GeneralProvider(),
),
ChangeNotifierProvider(
create: (_) => MapProvider(),
lazy: true,
create: (_) => ExportSelectionProvider(),
),
ChangeNotifierProvider(
create: (_) => RegionSelectionProvider(),
lazy: true,
),
ChangeNotifierProvider(
create: (_) => ConfigureDownloadProvider(),
lazy: true,
create: (_) => DownloadConfigurationProvider(),
),
ChangeNotifierProvider(
create: (_) => DownloadingProvider(),
lazy: true,
),
],
child: MaterialApp(
title: 'FMTC Demo',
restorationScopeId: 'FMTC Demo',
theme: themeData,
home: const MainScreen(),
initialRoute: MainScreen.route,
onGenerateRoute: (settings) {
final route = _routes[settings.name]!;
if (route.custom != null) return route.custom!(context, settings);
return MaterialPageRoute(builder: route.std!, settings: settings);
},
),
);
}
Expand Down

This file was deleted.

Loading
Loading