Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
92 commits
Select commit Hold shift + click to select a range
e9a67b3
feat: assets
whes1015 Aug 9, 2026
39e7521
fix: background
whes1015 Aug 9, 2026
01c64f7
fix: lang
whes1015 Aug 9, 2026
1b56b42
fix: background
whes1015 Aug 9, 2026
01ec52a
fix: android crash
whes1015 Aug 9, 2026
869b511
fix: background
whes1015 Aug 9, 2026
47dea66
fix: pin maplibre_gl to gzip fix
whes1015 Aug 9, 2026
ee5ec55
fix: developer mode
whes1015 Aug 10, 2026
91bf45c
fix: home page weather card
whes1015 Aug 10, 2026
3246c08
fix: home page weather icon
whes1015 Aug 10, 2026
42589dc
fix: home page weather background
whes1015 Aug 10, 2026
1e1eeec
feat: home sheet next-hour rain trend from rainforecast API
whes1015 Aug 10, 2026
fd8db7d
fix: home background blur/dim flicker
whes1015 Aug 10, 2026
8776ea3
feat: weather phenomenon icons finer than the backdrop modes
whes1015 Aug 10, 2026
46a9245
feat: beautify data page
whes1015 Aug 10, 2026
b777bf1
feat: home rain trend summary + minute axis
whes1015 Aug 10, 2026
3bce5ad
feat: wind map arrows with baked-in outline, speed-coloured
whes1015 Aug 10, 2026
30e38f8
feat: wind chart segments coloured by speed bucket
whes1015 Aug 10, 2026
6f73fb3
fix: wind chart tooltip crash on segmented bars
whes1015 Aug 10, 2026
9f97889
feat: 24M tile cache with fill-style warm injection
whes1015 Aug 10, 2026
1fab8d7
feat: QPESUMS forecast overlay with scan/county/town chrome
whes1015 Aug 10, 2026
b9493ad
fix: self-heal map platform view on iOS hot restart
whes1015 Aug 10, 2026
163c289
fix: compass above all overlays
whes1015 Aug 10, 2026
d740ca8
fix: space the QPESUMS layer label
whes1015 Aug 10, 2026
7e3c228
refactor: extract notification tap routing into its own file
whes1015 Aug 10, 2026
2d1a290
feat: open DPM points in an external map app
whes1015 Aug 10, 2026
5187dca
style: reformat the notification route navigator typedef
whes1015 Aug 10, 2026
e51250d
feat: show rain-trend update time and a no-data pane
whes1015 Aug 10, 2026
cd54102
feat: outline lightning markers for visibility over pale tiles
whes1015 Aug 10, 2026
e9126d4
refactor: bake lightning colours in so the outline survives tinting
whes1015 Aug 10, 2026
42b18ea
style: thicken the lightning outline to match the wind arrows
whes1015 Aug 10, 2026
087140d
feat: expose the township-name toggle on every map layer
whes1015 Aug 10, 2026
96e3793
fix: settle the compass needle on reset and park it lower
whes1015 Aug 10, 2026
0906bf9
feat: use the Flutter MapCompass on the report and replay maps
whes1015 Aug 10, 2026
a430cc4
feat: treat a dry rain-hour forecast as no rain
whes1015 Aug 10, 2026
a0d69dd
feat: grow the hero forecast card on a dry hour
whes1015 Aug 10, 2026
70a4d8e
feat: centre the home backdrop on GPS in current-location mode
whes1015 Aug 10, 2026
f006195
perf: square the radar scan-range terms by multiplication
whes1015 Aug 10, 2026
6f74601
perf: binary-search the wind chart's nearest sample
whes1015 Aug 10, 2026
82f34cb
refactor: share the wind arrow outline directions
whes1015 Aug 10, 2026
d6dc1bd
refactor: drop the dead string sort in the lightning cache eviction
whes1015 Aug 10, 2026
cf5b42c
refactor: tidy the tile-cache inject chunk boundary
whes1015 Aug 10, 2026
1348358
perf: cut scroll-frame cost on the home sheet
whes1015 Aug 10, 2026
55199aa
perf: cut the home backdrop's per-frame cost and fix forced-look rain
whes1015 Aug 10, 2026
e9c750d
feat: custom layer order in the map layer picker
whes1015 Aug 10, 2026
d918991
feat: add QPESUMS as a default map layer choice
whes1015 Aug 10, 2026
a451a02
feat: group map layers into six ordered categories
whes1015 Aug 10, 2026
0bf2b48
feat: let the layer order editor reorder categories too
whes1015 Aug 10, 2026
a934af4
refactor: split the layer order editor into two levels
whes1015 Aug 10, 2026
00cbb55
feat: reorder default map-layer categories
whes1015 Aug 10, 2026
c0bf2e1
chore: bump flutter-maplibre-gl to 7c2e249
whes1015 Aug 10, 2026
1e5f950
perf: render weather/cloud shaders at mediump precision
whes1015 Aug 10, 2026
6354040
refactor: merge the three v2 tile APIs and repositories
whes1015 Aug 10, 2026
82ac382
refactor: share degToRad, rampColor, and drop dead ramp code
whes1015 Aug 10, 2026
9ff5ab0
refactor: give MapLayer a defaults mixin for unused members
whes1015 Aug 10, 2026
589ff91
refactor: share meteor repo decodes, bounds, and calibrated time
whes1015 Aug 10, 2026
d08cde6
refactor: fold RainMapLayer into a generic station layer
whes1015 Aug 11, 2026
c9d68ce
refactor: generalize the meteor snapshot API and repositories
whes1015 Aug 11, 2026
17199cf
refactor: share typhoon payload decoding
whes1015 Aug 11, 2026
0f749f1
refactor: route Taipei wall-clock conversions through AppTime.taipei
whes1015 Aug 11, 2026
2c73243
refactor: share small inline UI building blocks
whes1015 Aug 11, 2026
3ed307d
refactor: share the map sheets' extent plumbing and chrome
whes1015 Aug 11, 2026
bdcefa0
refactor: centralize API path constants and drop the dead v1 report e…
whes1015 Aug 11, 2026
5fd2d02
feat: more satellite channel
whes1015 Aug 11, 2026
7459bc8
feat: expand satellite channels to all Himawari bands and products
whes1015 Aug 11, 2026
3ec3845
feat: bright-yellow admin frame over satellite layers
whes1015 Aug 11, 2026
eb3a22b
feat: satellite layer styles, legends and switcher subtitles
whes1015 Aug 11, 2026
165eb53
fix: degrade 所在地 to nationwide when GPS is unavailable
whes1015 Aug 11, 2026
9650b6d
chore: pin maplibre_gl git dependency in pubspec.lock
whes1015 Aug 11, 2026
bac1a7f
fix: clear the stale township frame when 所在地 loses GPS
whes1015 Aug 11, 2026
2c8ee7a
fix: weather icon
whes1015 Aug 11, 2026
c109471
feat: ECMWF/GFS wind-forecast overlays with particle animation
whes1015 Aug 11, 2026
0453678
feat: 國界 borders default-off on every reference overlay
whes1015 Aug 11, 2026
1c5d122
refactor: legend units always shown under the scale
whes1015 Aug 11, 2026
19de96d
feat: cache wind-forecast tiles in the immutable ETag store
whes1015 Aug 11, 2026
0e307e5
perf: equivalent simplification of the wind particle hot path
whes1015 Aug 11, 2026
b08405d
feat: per-hour usage history chart on the Debug page
whes1015 Aug 11, 2026
ddcaf56
feat: colour-coded 現在/歷史/未來 eras on the map timeline
whes1015 Aug 11, 2026
a26bb82
refactor: extract Debug network chart into a tested public widget
whes1015 Aug 11, 2026
c3a94ab
style: reformat drifted map timeline and wind files
whes1015 Aug 11, 2026
2996ce6
feat: red/green network chart with mixed or single-series toggle
whes1015 Aug 11, 2026
a83a1d1
feat: 24h/7d window toggle on the network usage chart
whes1015 Aug 11, 2026
eed7c4d
fix: space out x-axis labels on the network usage chart
whes1015 Aug 11, 2026
358382c
fix: keep the network chart tooltip inside the screen
whes1015 Aug 11, 2026
fa2474c
fix: a future forecast step is never labelled 現在
whes1015 Aug 11, 2026
d7b535b
feat: surface a snackbar when the chosen map app cannot open
whes1015 Aug 11, 2026
55bda87
feat: map timeline shows a forecast's issue time and valid span
whes1015 Aug 11, 2026
36f36ad
refactor: DPM sheet accents per sub-layer, drop category filters
whes1015 Aug 11, 2026
4c473ef
style: polish typhoon warning and waypoint cards
whes1015 Aug 11, 2026
8c072ae
fix: restore maplibre_gl git dependency in pubspec.lock
whes1015 Aug 11, 2026
4b6e76a
fix: typhoon cards
whes1015 Aug 11, 2026
37220f1
fix: typhoon cards
whes1015 Aug 11, 2026
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
Prev Previous commit
Next Next commit
feat: bright-yellow admin frame over satellite layers
Satellite imagery is fully opaque and overall dark, so the white admin
frame washes out on it. AdminOutline.add takes an optional lineColor and
satellite draws bright yellow country/county + dark yellow township
borders (typhoon's satellite underlay too); radar/QPESUMS keep the white
core. Add an onReloadActive hook to MapLayer chrome so a style change can
re-mount a layer, and stop moving the camera on a bare layer switch.
  • Loading branch information
whes1015 committed Aug 11, 2026
commit 3ec3845f54b3aea95f801cbcf23c6244b355fe06
Original file line number Diff line number Diff line change
Expand Up @@ -611,6 +611,7 @@ class DisasterMapLayer with MapLayerDefaults implements MapLayer {
BuildContext context, {
required ValueListenable<bool> showTownLabels,
required ValueChanged<bool> onShowTownLabelsChanged,
required Future<void> Function() onReloadActive,
}) => DisasterMapOverlayMenu(
layer: this,
showTownLabels: showTownLabels,
Expand Down
1 change: 1 addition & 0 deletions lib/features/map/presentation/layers/qpesums_layer.dart
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ class QpesumsMapLayer extends RasterTimelineLayer with ScanRangeOverlayChrome {
BuildContext context, {
required ValueListenable<bool> showTownLabels,
required ValueChanged<bool> onShowTownLabelsChanged,
required Future<void> Function() onReloadActive,
}) => ScanRangeOverlayMenu(
layer: this,
tooltip: AppLocalizations.of(context).qpesumsOverlayMenuTooltip,
Expand Down
1 change: 1 addition & 0 deletions lib/features/map/presentation/layers/radar_layer.dart
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ class RadarMapLayer extends RasterTimelineLayer with ScanRangeOverlayChrome {
BuildContext context, {
required ValueListenable<bool> showTownLabels,
required ValueChanged<bool> onShowTownLabelsChanged,
required Future<void> Function() onReloadActive,
}) => RadarOverlayMenu(
layer: this,
showTownLabels: showTownLabels,
Expand Down
1 change: 1 addition & 0 deletions lib/features/map/presentation/layers/rain_layer.dart
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,7 @@ class RainMapLayer
BuildContext context, {
required ValueListenable<bool> showTownLabels,
required ValueChanged<bool> onShowTownLabelsChanged,
required Future<void> Function() onReloadActive,
}) {
final l10n = AppLocalizations.of(context);
final colors = Theme.of(context).colorScheme;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import 'package:dpip/app/theme/app_spacing.dart';
import 'package:dpip/core/logging/log.dart';
import 'package:dpip/features/map/presentation/layers/radar_scan_range.dart';
import 'package:dpip/l10n/gen/app_localizations.dart';
import 'package:dpip/shared/color_hex.dart';
import 'package:dpip/shared/map/admin_outline.dart';
import 'package:dpip/shared/map/map_style.dart';
import 'package:dpip/shared/map/raster_timeline_layer.dart';
Expand Down Expand Up @@ -202,7 +203,7 @@ mixin ScanRangeOverlayChrome on RasterTimelineLayer {
if (showCountyOutline.value)
SymbolLegendItem(
swatch: LineSwatch(
color: const Color(0xFFFFFFFF),
color: colorFromHexRgb(AdminOutline.lineColor)!,
width: AdminBoundary.county.lineWidth,
opacity: AdminBoundary.county.lineOpacity,
casingColor: const Color(0xFF000000),
Expand All @@ -214,7 +215,7 @@ mixin ScanRangeOverlayChrome on RasterTimelineLayer {
if (showTownOutline.value)
SymbolLegendItem(
swatch: LineSwatch(
color: const Color(0xFFFFFFFF),
color: colorFromHexRgb(AdminOutline.lineColor)!,
width: AdminBoundary.town.lineWidth,
opacity: AdminBoundary.town.lineOpacity,
casingColor: const Color(0xFF000000),
Expand Down
100 changes: 85 additions & 15 deletions lib/features/map/presentation/layers/typhoon_layer.dart
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import 'package:dpip/features/typhoon/domain/typhoon_warning.dart';
import 'package:dpip/features/weather/domain/radar_repository.dart';
import 'package:dpip/features/weather/domain/satellite_repository.dart';
import 'package:dpip/l10n/gen/app_localizations.dart';
import 'package:dpip/shared/color_hex.dart';
import 'package:dpip/shared/map/base_map.dart';
import 'package:dpip/shared/map/camera_fit.dart';
import 'package:dpip/shared/map/map_layer.dart';
Expand Down Expand Up @@ -113,6 +114,7 @@ class TyphoonMapLayer with MapLayerDefaults implements MapLayer {
final ValueNotifier<bool> showTownOutline = ValueNotifier(true);

bool _rangeShown = false;
bool _globalShown = false;
final Set<AdminBoundary> _boundariesShown = {};

/// Blue-grey, matching the radar surface — distinct from every dBZ colour so
Expand Down Expand Up @@ -793,7 +795,7 @@ class TyphoonMapLayer with MapLayerDefaults implements MapLayer {
_queue(() => _syncRadarChrome(controller));
}

/// Turns the 縣市 borders on/off (radar underlay only).
/// Turns the 縣市 borders on/off (radar and satellite underlays).
void setShowCountyOutline(bool value) {
if (showCountyOutline.value == value) return;
showCountyOutline.value = value;
Expand All @@ -802,7 +804,7 @@ class TyphoonMapLayer with MapLayerDefaults implements MapLayer {
_queue(() => _syncRadarChrome(controller));
}

/// Turns the 鄉鎮 borders on/off (radar underlay only).
/// Turns the 鄉鎮 borders on/off (radar and satellite underlays).
void setShowTownOutline(bool value) {
if (showTownOutline.value == value) return;
showTownOutline.value = value;
Expand All @@ -811,20 +813,28 @@ class TyphoonMapLayer with MapLayerDefaults implements MapLayer {
_queue(() => _syncRadarChrome(controller));
}

/// Adds or removes the radar underlay's chrome — the coverage outline and the
/// county borders — to match the toggles.
/// Adds or removes the weather underlay's chrome — the scan-range outline
/// (radar only), the country/global border (satellite only), and the county
/// and township borders (both underlays) — to match the toggles.
///
/// Anchored under the lowest typhoon vector, not on top as on the radar
/// surface: here the track and the storm bands are the subject, and a white
/// border crossing them would compete with the thing being read. Below the
/// vectors it still clears the echo, which is the whole problem.
Future<void> _syncRadarChrome(MapLibreMapController controller) async {
final isRadar = weatherOverlay.value == TyphoonWeatherOverlay.radar;
final kind = weatherOverlay.value;
final isRadar = kind == TyphoonWeatherOverlay.radar;
final hasUnderlay = kind != TyphoonWeatherOverlay.none;
final wantRange = isRadar && showScanRange.value;
// Both underlays are opaque weather rasters, so the admin frame is drawn
// over each. Satellite is fully opaque and covers the country edges too,
// so its country border is drawn as well — the frame a satellite viewer
// navigates by.
final wantBoundaries = <AdminBoundary>{
if (isRadar && showTownOutline.value) AdminBoundary.town,
if (isRadar && showCountyOutline.value) AdminBoundary.county,
if (hasUnderlay && showTownOutline.value) AdminBoundary.town,
if (hasUnderlay && showCountyOutline.value) AdminBoundary.county,
};
final wantGlobal = hasUnderlay && !isRadar && showCountyOutline.value;

final below = _warningNames.isNotEmpty ? _warnLyr : _probLyr;
try {
Expand All @@ -840,8 +850,30 @@ class TyphoonMapLayer with MapLayerDefaults implements MapLayer {
await RadarScanRange.remove(controller);
}
}
// Borders after the range so they insert above it: the dashed range is a
// hint, the borders are the reference frame.
if (wantGlobal != _globalShown) {
_globalShown = wantGlobal;
if (wantGlobal) {
await controller.addLineLayer(
AdminOutline.sourceId,
satelliteGlobalOutlineLayerId,
LineLayerProperties(
lineColor: satelliteOutlineColor,
lineWidth: 1.0,
),
sourceLayer: 'global',
belowLayerId: below,
enableInteraction: false,
);
} else {
try {
await controller.removeLayer(satelliteGlobalOutlineLayerId);
} catch (_) {}
}
}
// Borders after the range/global so they insert above it: the dashed
// range is a hint, the borders are the reference frame. Satellite's
// frame is bright yellow — the hue that survives fully-opaque imagery;
// radar keeps the default white core.
for (final boundary in AdminBoundary.values) {
final shown = _boundariesShown.contains(boundary);
if (wantBoundaries.contains(boundary) == shown) continue;
Expand All @@ -850,15 +882,29 @@ class TyphoonMapLayer with MapLayerDefaults implements MapLayer {
await AdminOutline.remove(controller, boundary);
} else {
_boundariesShown.add(boundary);
await AdminOutline.add(controller, boundary, belowLayerId: below);
await AdminOutline.add(
controller,
boundary,
lineColor: isRadar
? AdminOutline.lineColor
: boundary == AdminBoundary.town
? satelliteTownOutlineColor
: satelliteOutlineColor,
belowLayerId: below,
);
}
}
} catch (error, stackTrace) {
// A style reload or an overlay switch can race this; the next sync
// rebuilds from a known-clean state.
_rangeShown = false;
_globalShown = false;
_boundariesShown.clear();
Log.handle(error, stackTrace, 'Failed to sync the typhoon radar chrome');
Log.handle(
error,
stackTrace,
'Failed to sync the typhoon weather chrome',
);
}
}

Expand Down Expand Up @@ -940,6 +986,12 @@ class TyphoonMapLayer with MapLayerDefaults implements MapLayer {
_rangeShown = false;
await RadarScanRange.remove(controller);
}
if (_globalShown) {
_globalShown = false;
try {
await controller.removeLayer(satelliteGlobalOutlineLayerId);
} catch (_) {}
}
for (final boundary in _boundariesShown.toList()) {
_boundariesShown.remove(boundary);
await AdminOutline.remove(controller, boundary);
Expand Down Expand Up @@ -1072,6 +1124,7 @@ class TyphoonMapLayer with MapLayerDefaults implements MapLayer {
BuildContext context, {
required ValueListenable<bool> showTownLabels,
required ValueChanged<bool> onShowTownLabelsChanged,
required Future<void> Function() onReloadActive,
}) => TyphoonOverlayMenu(
layer: this,
showTownLabels: showTownLabels,
Expand All @@ -1098,6 +1151,8 @@ class TyphoonMapLayer with MapLayerDefaults implements MapLayer {
// has to follow it: naming a line that is not on the map is worse than
// saying nothing.
final isRadar = weatherOverlay.value == TyphoonWeatherOverlay.radar;
final isSatellite =
weatherOverlay.value == TyphoonWeatherOverlay.satellite;
return MapLegendCard(
child: SymbolLegend(
items: [
Expand Down Expand Up @@ -1243,10 +1298,20 @@ class TyphoonMapLayer with MapLayerDefaults implements MapLayer {
),
label: l10n.radarScanRange,
),
if (isRadar && showCountyOutline.value)
if (isSatellite && showCountyOutline.value)
SymbolLegendItem(
swatch: const LineSwatch(
color: Color(0xFFFFD400),
width: 1.0,
),
label: l10n.mapLayerSatelliteGlobalOutline,
),
if ((isRadar || isSatellite) && showCountyOutline.value)
SymbolLegendItem(
swatch: LineSwatch(
color: const Color(0xFFFFFFFF),
color: colorFromHexRgb(
isRadar ? AdminOutline.lineColor : satelliteOutlineColor,
)!,
width: AdminBoundary.county.lineWidth,
opacity: AdminBoundary.county.lineOpacity,
casingColor: const Color(0xFF000000),
Expand All @@ -1255,10 +1320,14 @@ class TyphoonMapLayer with MapLayerDefaults implements MapLayer {
),
label: l10n.radarCountyOutline,
),
if (isRadar && showTownOutline.value)
if ((isRadar || isSatellite) && showTownOutline.value)
SymbolLegendItem(
swatch: LineSwatch(
color: const Color(0xFFFFFFFF),
color: colorFromHexRgb(
isRadar
? AdminOutline.lineColor
: satelliteTownOutlineColor,
)!,
width: AdminBoundary.town.lineWidth,
opacity: AdminBoundary.town.lineOpacity,
casingColor: const Color(0xFF000000),
Expand Down Expand Up @@ -1287,6 +1356,7 @@ class TyphoonMapLayer with MapLayerDefaults implements MapLayer {
// the next attach re-adds instead of no-oping on stale state.
_added = false;
_rangeShown = false;
_globalShown = false;
_boundariesShown.clear();
}

Expand Down
12 changes: 8 additions & 4 deletions lib/shared/map/admin_outline.dart
Original file line number Diff line number Diff line change
Expand Up @@ -73,13 +73,17 @@ abstract final class AdminOutline {

/// Adds [boundary]'s two strokes. Casing first so the core paints over it.
///
/// [belowLayerId] omitted puts them on top, which is what the radar surface
/// wants. The typhoon surface passes an anchor instead: there the borders
/// still need to clear the echo, but the track and storm bands are the
/// subject and must not be crossed by a white line.
/// [lineColor] overrides the default light core — the typhoon surface's
/// satellite underlay passes bright yellow there, because on fully-opaque
/// imagery the default white does not survive. [belowLayerId] omitted puts
/// them on top, which is what the radar surface wants; the typhoon surface
/// passes an anchor instead: there the borders still need to clear the
/// echo, but the track and storm bands are the subject and must not be
/// crossed by a white line.
static Future<void> add(
MapLibreMapController controller,
AdminBoundary boundary, {
String lineColor = AdminOutline.lineColor,
String? belowLayerId,
}) async {
await controller.addLineLayer(
Expand Down
13 changes: 13 additions & 0 deletions lib/shared/map/map_layer.dart
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,10 @@ abstract interface class MapLayer {
/// The switcher label (localised by the implementation via [context]).
String label(BuildContext context);

/// Secondary switcher line under [label] — formula, band composition, or
/// anything that differentiates the layer at a glance. `null` hides it.
String? subtitle(BuildContext context);

/// The switcher icon — outlined, per the app's icon convention.
IconData get icon;

Expand Down Expand Up @@ -110,10 +114,15 @@ abstract interface class MapLayer {
/// options (one affordance, not a second chip). Layers whose chrome is not a
/// settings menu may ignore them — [MapScaffold] shows a standalone
/// township-label menu for layers that return no chrome.
///
/// [onReloadActive] re-loads this layer from scratch — a chrome option that
/// changes what the layer renders (e.g. the satellite colour style) calls it
/// after mutating its source so the already-mounted tiles re-fetch.
Widget buildTopTrailingChrome(
BuildContext context, {
required ValueListenable<bool> showTownLabels,
required ValueChanged<bool> onShowTownLabelsChanged,
required Future<void> Function() onReloadActive,
});

/// Flutter widgets painted over the map (screen-space callouts, etc.).
Expand Down Expand Up @@ -175,6 +184,9 @@ abstract interface class MapLayer {
/// the scaffold can then call the whole [MapLayer] surface without a chain of
/// empty implementations per layer.
mixin MapLayerDefaults implements MapLayer {
@override
String? subtitle(BuildContext context) => null;

@override
Future<Result<List<MapFrame>>> frames() async => const Ok([]);

Expand Down Expand Up @@ -214,6 +226,7 @@ mixin MapLayerDefaults implements MapLayer {
BuildContext context, {
required ValueListenable<bool> showTownLabels,
required ValueChanged<bool> onShowTownLabelsChanged,
required Future<void> Function() onReloadActive,
}) => const SizedBox.shrink();

@override
Expand Down
Loading