Skip to content

Commit

Permalink
Improved example application
Browse files Browse the repository at this point in the history
  • Loading branch information
JaffaKetchup committed Dec 18, 2024
1 parent 5f70fe6 commit 0af37da
Show file tree
Hide file tree
Showing 24 changed files with 724 additions and 194 deletions.
6 changes: 6 additions & 0 deletions example/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ 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/recoverable_regions_provider.dart';
import 'src/shared/state/region_selection_provider.dart';

void main() async {
Expand Down Expand Up @@ -95,6 +96,7 @@ class _AppContainer extends StatelessWidget {
),
ChangeNotifierProvider(
create: (_) => ExportSelectionProvider(),
lazy: true,
),
ChangeNotifierProvider(
create: (_) => RegionSelectionProvider(),
Expand All @@ -105,6 +107,10 @@ class _AppContainer extends StatelessWidget {
),
ChangeNotifierProvider(
create: (_) => DownloadingProvider(),
// cannot be lazy as must persist when user disposed
),
ChangeNotifierProvider(
create: (_) => RecoverableRegionsProvider(),
),
],
child: MaterialApp(
Expand Down
389 changes: 232 additions & 157 deletions example/lib/src/screens/main/main.dart

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import 'package:collection/collection.dart';
import 'package:flutter/material.dart';
import 'package:flutter_map/flutter_map.dart';
import 'package:latlong2/latlong.dart';
import 'package:provider/provider.dart';

import '../../../../../shared/state/recoverable_regions_provider.dart';

class RecoveryRegions extends StatelessWidget {
const RecoveryRegions({super.key});

@override
Widget build(BuildContext context) => Consumer<RecoverableRegionsProvider>(
builder: (context, provider, _) {
final map =
<HSLColor, List<({List<List<LatLng>> pointss, String label})>>{};
for (final MapEntry(key: region, value: color)
in provider.failedRegions.entries) {
(map[color] ??= []).add(
(
pointss: region.region.regions
.map((e) => e.toOutline().toList())
.toList(),
label: "To '${region.storeName}'",
),
);
}

return PolygonLayer(
polygons: map.entries
.map(
(e) => e.value
.map(
(region) => region.pointss.map(
(points) => Polygon(
points: points,
color: e.key.toColor().withAlpha(255 ~/ 2),
borderColor: e.key.toColor(),
borderStrokeWidth: 2,
label: region.label,
labelPlacement: PolygonLabelPlacement.polylabel,
),
),
)
.flattened,
)
.flattened
.toList(),
);
},
);
}
37 changes: 23 additions & 14 deletions example/lib/src/screens/main/map_view/map_view.dart
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,15 @@ import '../../../shared/state/region_selection_provider.dart';
import 'components/additional_overlay/additional_overlay.dart';
import 'components/debugging_tile_builder/debugging_tile_builder.dart';
//import 'components/download_progress/download_progress_masker.dart';
import 'components/recovery_regions/recovery_regions.dart';
import 'components/region_selection/crosshairs.dart';
import 'components/region_selection/custom_polygon_snapping_indicator.dart';
import 'components/region_selection/region_shape.dart';

enum MapViewMode {
standard,
downloadRegion,
recovery,
}

class MapView extends StatefulWidget {
Expand Down Expand Up @@ -369,6 +371,8 @@ class _MapViewState extends State<MapView> with TickerProviderStateMixin {
const RegionShape(),
const CustomPolygonSnappingIndicator(),
],
if (widget.mode == MapViewMode.recovery)
const RecoveryRegions(),
if (widget.bottomPaddingWrapperBuilder case final bpwb?)
Builder(builder: (context) => bpwb(context, attribution))
else
Expand All @@ -381,21 +385,26 @@ class _MapViewState extends State<MapView> with TickerProviderStateMixin {
children: [
MouseRegion(
opaque: false,
cursor: widget.mode == MapViewMode.standard ||
context.select<RegionSelectionProvider, bool>(
(p) => p.isDownloadSetupPanelVisible,
) ||
context.select<RegionSelectionProvider,
RegionSelectionMethod>(
(p) => p.regionSelectionMethod,
) ==
RegionSelectionMethod.useMapCenter
? MouseCursor.defer
: context.select<RegionSelectionProvider, bool>(
cursor: switch (widget.mode) {
MapViewMode.standard => MouseCursor.defer,
MapViewMode.recovery => MouseCursor.defer,
MapViewMode.downloadRegion
when context.select<RegionSelectionProvider, bool>(
(p) => p.isDownloadSetupPanelVisible,
) ||
context.select<RegionSelectionProvider,
RegionSelectionMethod>(
(p) => p.regionSelectionMethod,
) ==
RegionSelectionMethod.useMapCenter =>
MouseCursor.defer,
MapViewMode.downloadRegion
when context.select<RegionSelectionProvider, bool>(
(p) => p.customPolygonSnap,
)
? SystemMouseCursors.none
: SystemMouseCursors.precise,
) =>
SystemMouseCursors.none,
MapViewMode.downloadRegion => SystemMouseCursors.precise,
},
child: map,
),
if (isCrosshairsVisible) const Center(child: Crosshairs()),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,12 @@ class StoreSelector extends StatefulWidget {
super.key,
this.storeName,
required this.onStoreNameSelected,
this.enabled = true,
});

final String? storeName;
final void Function(String?) onStoreNameSelected;
final bool enabled;

@override
State<StoreSelector> createState() => _StoreSelectorState();
Expand Down Expand Up @@ -70,6 +72,7 @@ class _StoreSelectorState extends State<StoreSelector> {
filled: true,
helperMaxLines: 2,
),
enabled: widget.enabled,
);
},
),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ class _ConfigOptionsState extends State<ConfigOptions> {
context.select<DownloadConfigurationProvider, bool>(
(p) => p.retryFailedRequestTiles,
);
final fromRecovery = context
.select<DownloadConfigurationProvider, int?>((p) => p.fromRecovery);

return SingleChildScrollView(
child: Column(
Expand All @@ -49,6 +51,7 @@ class _ConfigOptionsState extends State<ConfigOptions> {
onStoreNameSelected: (storeName) => context
.read<DownloadConfigurationProvider>()
.selectedStoreName = storeName,
enabled: fromRecovery == null,
),
const Divider(height: 24),
Row(
Expand All @@ -60,8 +63,9 @@ class _ConfigOptionsState extends State<ConfigOptions> {
values: RangeValues(minZoom.toDouble(), maxZoom.toDouble()),
max: 20,
divisions: 20,
onChanged: (r) =>
context.read<DownloadConfigurationProvider>()
onChanged: fromRecovery != null
? null
: (r) => context.read<DownloadConfigurationProvider>()
..minZoom = r.start.toInt()
..maxZoom = r.end.toInt(),
),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import 'dart:async';

import 'package:flutter/material.dart';
import 'package:flutter_map/flutter_map.dart';
import 'package:flutter_map_tile_caching/flutter_map_tile_caching.dart';
Expand Down Expand Up @@ -43,6 +45,9 @@ class _ConfirmationPanelState extends State<ConfirmationPanel> {
(p) => p.selectedStoreName,
) !=
null;
final fromRecovery = context.select<DownloadConfigurationProvider, int?>(
(p) => p.fromRecovery,
);

final tileCountableRegion = MultiRegion(regions).toDownloadable(
minZoom: minZoom,
Expand Down Expand Up @@ -100,7 +105,7 @@ class _ConfirmationPanelState extends State<ConfirmationPanel> {
else
Text(
NumberFormat.decimalPatternDigits(decimalDigits: 0)
.format(snapshot.data),
.format(snapshot.requireData),
style: Theme.of(context)
.textTheme
.headlineLarge!
Expand Down Expand Up @@ -190,6 +195,13 @@ class _ConfirmationPanelState extends State<ConfirmationPanel> {
icon: _loadingDownloader ? null : const Icon(Icons.download),
),
),
if (fromRecovery != null) ...[
const SizedBox(height: 4),
Text(
'This will delete the recoverable region',
style: Theme.of(context).textTheme.labelSmall,
),
],
],
),
);
Expand Down Expand Up @@ -243,6 +255,11 @@ class _ConfirmationPanelState extends State<ConfirmationPanel> {
downloadStreams: downloadStreams,
);

if (downloadConfiguration.fromRecovery case final recoveryId?) {
unawaited(FMTCRoot.recovery.cancel(recoveryId));
downloadConfiguration.fromRecovery = null;
}

// The downloading view is switched to by `assignDownload`, when the first
// event is recieved from the stream (indicating the preparation is
// complete and the download is starting).
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';

import '../../../../../shared/state/download_configuration_provider.dart';
import '../../../../../shared/state/region_selection_provider.dart';
import '../../../../../shared/state/selected_tab_state.dart';
import '../../layouts/side/components/panel.dart';
import 'components/config_options/config_options.dart';
import 'components/confirmation_panel/confirmation_panel.dart';
Expand All @@ -22,9 +24,19 @@ class DownloadConfigurationViewSide extends StatelessWidget {
padding: const EdgeInsets.all(4),
child: IconButton(
onPressed: () {
context
.read<RegionSelectionProvider>()
.isDownloadSetupPanelVisible = false;
final regionSelectionProvider =
context.read<RegionSelectionProvider>();
final downloadConfigProvider =
context.read<DownloadConfigurationProvider>();

regionSelectionProvider.isDownloadSetupPanelVisible = false;

if (downloadConfigProvider.fromRecovery == null) return;

regionSelectionProvider.clearConstructedRegions();
downloadConfigProvider.fromRecovery = null;

selectedTabState.value = 2;
},
icon: const Icon(Icons.arrow_back),
tooltip: 'Return to selection',
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import 'package:flutter/material.dart';

class NoRegions extends StatelessWidget {
const NoRegions({super.key});

@override
Widget build(BuildContext context) => SliverFillRemaining(
hasScrollBody: false,
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 32, vertical: 12),
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Icon(Icons.auto_fix_off, size: 42),
const SizedBox(height: 12),
Text(
'No failed downloads',
style: Theme.of(context).textTheme.titleLarge,
),
const SizedBox(height: 6),
const Text(
"If a download fails unexpectedly, it'll appear here! You can "
'then finish the end of the download.',
textAlign: TextAlign.center,
),
],
),
),
),
);
}
Loading

0 comments on commit 0af37da

Please sign in to comment.