martin config

This commit is contained in:
Shautvast 2026-03-31 21:01:08 +02:00
parent c6e2cab237
commit f94a888a92
15 changed files with 549 additions and 277 deletions

View file

@ -61,9 +61,9 @@ services:
- maps-net
ports:
- "3001:3001"
environment:
DATABASE_URL: "postgres://maps:maps@postgres:5432/maps"
command: ["--listen-addresses", "0.0.0.0:3001"]
volumes:
- ./martin.yaml:/martin.yaml:ro
command: ["--config", "/martin.yaml"]
depends_on:
- postgres

37
backend/martin.yaml Normal file
View file

@ -0,0 +1,37 @@
listen_addresses: '0.0.0.0:3001'
postgres:
connection_string: 'postgres://maps:maps@postgres:5432/maps'
tables:
planet_osm_polygon:
schema: public
table: planet_osm_polygon
srid: 3857
geometry_column: way
geometry_type: GEOMETRY
minzoom: 0
maxzoom: 14
planet_osm_line:
schema: public
table: planet_osm_line
srid: 3857
geometry_column: way
geometry_type: GEOMETRY
minzoom: 0
maxzoom: 14
planet_osm_point:
schema: public
table: planet_osm_point
srid: 3857
geometry_column: way
geometry_type: GEOMETRY
minzoom: 0
maxzoom: 14
planet_osm_roads:
schema: public
table: planet_osm_roads
srid: 3857
geometry_column: way
geometry_type: GEOMETRY
minzoom: 0
maxzoom: 14

View file

@ -1,8 +1,12 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<application
android:label="privacy_maps"
android:name="${applicationName}"
android:icon="@mipmap/ic_launcher">
android:icon="@mipmap/ic_launcher"
android:usesCleartextTraffic="true">
<activity
android:name=".MainActivity"
android:exported="true"
@ -25,6 +29,10 @@
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<!-- Disable Impeller/Vulkan — fallback to Skia/OpenGL for devices with poor Vulkan support -->
<meta-data
android:name="io.flutter.embedding.android.EnableImpeller"
android:value="false" />
<!-- Don't delete the meta-data below.
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
<meta-data

View file

@ -19,7 +19,7 @@ pluginManagement {
plugins {
id("dev.flutter.flutter-plugin-loader") version "1.0.0"
id("com.android.application") version "8.7.0" apply false
id("org.jetbrains.kotlin.android") version "1.8.22" apply false
id("org.jetbrains.kotlin.android") version "2.1.0" apply false
}
include(":app")

View file

@ -65,12 +65,12 @@ class SelectedPlace {
});
}
class MapNotifier extends StateNotifier<MapState> {
MapNotifier()
: super(MapState(
class MapNotifier extends Notifier<MapState> {
@override
MapState build() => MapState(
center: AppConstants.defaultCenter,
zoom: AppConstants.defaultZoom,
));
);
void updateCamera(LatLng center, double zoom) {
state = state.copyWith(center: center, zoom: zoom);
@ -153,6 +153,4 @@ class MapNotifier extends StateNotifier<MapState> {
}
}
final mapProvider = StateNotifierProvider<MapNotifier, MapState>((ref) {
return MapNotifier();
});
final mapProvider = NotifierProvider<MapNotifier, MapState>(MapNotifier.new);

View file

@ -67,41 +67,32 @@ class OfflineState {
}
}
class OfflineNotifier extends StateNotifier<OfflineState> {
final OfflineRepository _repository;
class OfflineNotifier extends Notifier<OfflineState> {
late OfflineRepository _repository;
OfflineNotifier(this._repository) : super(const OfflineState()) {
_init();
}
Future<void> _init() async {
await loadAvailableRegions();
_repository.watchDownloadedRegions().listen((regions) {
if (mounted) {
@override
OfflineState build() {
_repository = ref.watch(offlineRepositoryProvider);
final subscription = _repository.watchDownloadedRegions().listen((regions) {
state = state.copyWith(downloadedRegions: regions);
}
});
ref.onDispose(subscription.cancel);
Future.microtask(loadAvailableRegions);
return const OfflineState();
}
Future<void> loadAvailableRegions() async {
state = state.copyWith(isLoading: true, clearError: true);
try {
final regions = await _repository.getAvailableRegions();
if (mounted) {
state = state.copyWith(
availableRegions: regions,
isLoading: false,
);
}
state = state.copyWith(availableRegions: regions, isLoading: false);
} catch (e) {
if (mounted) {
state = state.copyWith(
isLoading: false,
error: 'Could not load available regions.',
);
}
}
}
Future<void> downloadRegion(OfflineRegionInfo region) async {
state = state.copyWith(
@ -120,7 +111,6 @@ class OfflineNotifier extends StateNotifier<OfflineState> {
await _repository.downloadRegion(
region: region,
onProgress: (component, received, total) {
if (mounted) {
state = state.copyWith(
downloadProgress: {
...state.downloadProgress,
@ -132,19 +122,15 @@ class OfflineNotifier extends StateNotifier<OfflineState> {
),
},
);
}
},
);
if (mounted) {
final newProgress = Map<String, DownloadProgress>.from(
state.downloadProgress);
final newProgress =
Map<String, DownloadProgress>.from(state.downloadProgress);
newProgress.remove(region.id);
state = state.copyWith(downloadProgress: newProgress);
}
} catch (e) {
if (mounted) {
final newProgress = Map<String, DownloadProgress>.from(
state.downloadProgress);
final newProgress =
Map<String, DownloadProgress>.from(state.downloadProgress);
newProgress.remove(region.id);
state = state.copyWith(
downloadProgress: newProgress,
@ -152,20 +138,15 @@ class OfflineNotifier extends StateNotifier<OfflineState> {
);
}
}
}
Future<void> deleteRegion(String regionId) async {
try {
await _repository.deleteRegion(regionId);
} catch (e) {
if (mounted) {
state = state.copyWith(error: 'Could not delete region.');
}
}
}
}
final offlineProvider =
StateNotifierProvider<OfflineNotifier, OfflineState>((ref) {
return OfflineNotifier(ref.watch(offlineRepositoryProvider));
});
NotifierProvider<OfflineNotifier, OfflineState>(OfflineNotifier.new);

View file

@ -31,19 +31,20 @@ class PlacesState {
}
}
class PlacesNotifier extends StateNotifier<PlacesState> {
final PlacesRepository _repository;
class PlacesNotifier extends Notifier<PlacesState> {
late PlacesRepository _repository;
PlacesNotifier(this._repository) : super(const PlacesState()) {
_loadFavorites();
@override
PlacesState build() {
_repository = ref.watch(placesRepositoryProvider);
Future.microtask(_loadFavorites);
return const PlacesState();
}
Future<void> _loadFavorites() async {
final favorites = await _repository.getAllFavorites();
if (mounted) {
state = state.copyWith(favorites: favorites);
}
}
Future<void> loadPoisInViewport({
required double minLon,
@ -61,16 +62,9 @@ class PlacesNotifier extends StateNotifier<PlacesState> {
maxLat: maxLat,
category: category,
);
if (mounted) {
state = state.copyWith(pois: pois, isLoading: false);
}
} catch (e) {
if (mounted) {
state = state.copyWith(
isLoading: false,
error: 'Could not load places.',
);
}
state = state.copyWith(isLoading: false, error: 'Could not load places.');
}
}
@ -86,6 +80,4 @@ class PlacesNotifier extends StateNotifier<PlacesState> {
}
final placesProvider =
StateNotifierProvider<PlacesNotifier, PlacesState>((ref) {
return PlacesNotifier(ref.watch(placesRepositoryProvider));
});
NotifierProvider<PlacesNotifier, PlacesState>(PlacesNotifier.new);

View file

@ -1,9 +1,9 @@
import 'package:flutter/material.dart';
import 'package:flutter_map/flutter_map.dart';
import 'package:flutter_map_cancellable_tile_provider/flutter_map_cancellable_tile_provider.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:latlong2/latlong.dart';
import '../../../map/providers/map_provider.dart';
import '../../../search/data/search_repository.dart';
import '../../providers/routing_provider.dart';
import '../widgets/route_summary.dart';
import '../widgets/step_list.dart';
@ -70,26 +70,32 @@ class _RouteScreenState extends ConsumerState<RouteScreen> {
padding: const EdgeInsets.all(16),
child: Column(
children: [
TextField(
readOnly: true,
decoration: InputDecoration(
labelText: 'From',
prefixIcon: const Icon(Icons.trip_origin),
hintText: routingState.originName,
),
controller:
TextEditingController(text: routingState.originName),
_LocationField(
label: 'From',
icon: Icons.trip_origin,
value: routingState.originName,
onSelected: (result) {
ref.read(routingProvider.notifier).setOrigin(
result.latitude,
result.longitude,
result.name,
);
ref.read(routingProvider.notifier).calculateRoute();
},
),
const SizedBox(height: 8),
TextField(
readOnly: true,
decoration: InputDecoration(
labelText: 'To',
prefixIcon: const Icon(Icons.flag),
hintText: routingState.destName,
),
controller:
TextEditingController(text: routingState.destName),
_LocationField(
label: 'To',
icon: Icons.flag,
value: routingState.destName,
onSelected: (result) {
ref.read(routingProvider.notifier).setDestination(
result.latitude,
result.longitude,
result.name,
);
ref.read(routingProvider.notifier).calculateRoute();
},
),
],
),
@ -228,6 +234,30 @@ class _RouteScreenState extends ConsumerState<RouteScreen> {
if (p.longitude > maxLon) maxLon = p.longitude;
}
// Guard against degenerate bounds (single point or near-identical coords)
// which cause CameraFit.bounds to produce infinite zoom NaN crash.
final isDegenerate =
(maxLat - minLat).abs() < 1e-6 && (maxLon - minLon).abs() < 1e-6;
final mapOptions = isDegenerate
? MapOptions(
initialCenter: LatLng(minLat, minLon),
initialZoom: 15,
interactionOptions:
const InteractionOptions(flags: InteractiveFlag.none),
)
: MapOptions(
initialCameraFit: CameraFit.bounds(
bounds: LatLngBounds(
LatLng(minLat, minLon),
LatLng(maxLat, maxLon),
),
padding: const EdgeInsets.all(32),
),
interactionOptions:
const InteractionOptions(flags: InteractiveFlag.none),
);
return Container(
height: 250,
margin: const EdgeInsets.all(16),
@ -236,22 +266,11 @@ class _RouteScreenState extends ConsumerState<RouteScreen> {
borderRadius: BorderRadius.circular(12),
),
child: FlutterMap(
options: MapOptions(
initialCameraFit: CameraFit.bounds(
bounds: LatLngBounds(
LatLng(minLat, minLon),
LatLng(maxLat, maxLon),
),
padding: const EdgeInsets.all(32),
),
interactionOptions: const InteractionOptions(
flags: InteractiveFlag.none,
),
),
options: mapOptions,
children: [
TileLayer(
urlTemplate: 'https://tile.openstreetmap.org/{z}/{x}/{y}.png',
tileProvider: CancellableNetworkTileProvider(),
tileProvider: NetworkTileProvider(),
userAgentPackageName: 'com.privacymaps.app',
),
// Draw all routes, non-selected as faint, selected as bold.
@ -341,3 +360,134 @@ class _ProfileChip extends StatelessWidget {
);
}
}
/// Tappable location field that opens an inline search dialog.
class _LocationField extends ConsumerStatefulWidget {
final String label;
final IconData icon;
final String? value;
final ValueChanged<SearchResult> onSelected;
const _LocationField({
required this.label,
required this.icon,
required this.value,
required this.onSelected,
});
@override
ConsumerState<_LocationField> createState() => _LocationFieldState();
}
class _LocationFieldState extends ConsumerState<_LocationField> {
Future<void> _openSearch() async {
final result = await showDialog<SearchResult>(
context: context,
builder: (ctx) => _LocationSearchDialog(label: widget.label),
);
if (result != null) widget.onSelected(result);
}
@override
Widget build(BuildContext context) {
return InkWell(
onTap: _openSearch,
borderRadius: BorderRadius.circular(8),
child: InputDecorator(
decoration: InputDecoration(
labelText: widget.label,
prefixIcon: Icon(widget.icon),
suffixIcon: const Icon(Icons.edit, size: 16),
border: const OutlineInputBorder(),
),
child: Text(widget.value ?? ''),
),
);
}
}
/// Dialog with a search field and live results.
class _LocationSearchDialog extends ConsumerStatefulWidget {
final String label;
const _LocationSearchDialog({required this.label});
@override
ConsumerState<_LocationSearchDialog> createState() =>
_LocationSearchDialogState();
}
class _LocationSearchDialogState
extends ConsumerState<_LocationSearchDialog> {
final _controller = TextEditingController();
List<SearchResult> _results = [];
bool _loading = false;
@override
void dispose() {
_controller.dispose();
super.dispose();
}
Future<void> _search(String query) async {
if (query.trim().length < 2) {
setState(() => _results = []);
return;
}
setState(() => _loading = true);
try {
final repo = ref.read(searchRepositoryProvider);
final results = await repo.search(query);
if (mounted) setState(() => _results = results);
} finally {
if (mounted) setState(() => _loading = false);
}
}
@override
Widget build(BuildContext context) {
return AlertDialog(
title: Text(widget.label),
contentPadding: const EdgeInsets.fromLTRB(16, 12, 16, 0),
content: SizedBox(
width: 400,
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
TextField(
controller: _controller,
autofocus: true,
decoration: const InputDecoration(
hintText: 'Search location…',
prefixIcon: Icon(Icons.search),
),
onChanged: _search,
),
if (_loading) const LinearProgressIndicator(),
ConstrainedBox(
constraints: const BoxConstraints(maxHeight: 300),
child: ListView.builder(
shrinkWrap: true,
itemCount: _results.length,
itemBuilder: (ctx, i) {
final r = _results[i];
return ListTile(
title: Text(r.name),
subtitle: Text(r.displayAddress,
maxLines: 1, overflow: TextOverflow.ellipsis),
onTap: () => Navigator.of(ctx).pop(r),
);
},
),
),
],
),
),
actions: [
TextButton(
onPressed: () => Navigator.of(context).pop(),
child: const Text('Cancel'),
),
],
);
}
}

View file

@ -63,10 +63,14 @@ class RoutingState {
: null;
}
class RoutingNotifier extends StateNotifier<RoutingState> {
final RoutingRepository _repository;
class RoutingNotifier extends Notifier<RoutingState> {
late RoutingRepository _repository;
RoutingNotifier(this._repository) : super(const RoutingState());
@override
RoutingState build() {
_repository = ref.watch(routingRepositoryProvider);
return const RoutingState();
}
void setOrigin(double lat, double lon, String name) {
state = state.copyWith(
@ -113,15 +117,12 @@ class RoutingNotifier extends StateNotifier<RoutingState> {
destLat: state.destLat!,
destLon: state.destLon!,
);
if (mounted) {
state = state.copyWith(
routes: routes,
selectedRouteIndex: 0,
isLoading: false,
);
}
} catch (e) {
if (mounted) {
state = state.copyWith(
isLoading: false,
error: 'Could not calculate route. Please try again.',
@ -129,9 +130,8 @@ class RoutingNotifier extends StateNotifier<RoutingState> {
}
}
}
}
final routingProvider =
StateNotifierProvider.autoDispose<RoutingNotifier, RoutingState>((ref) {
return RoutingNotifier(ref.watch(routingRepositoryProvider));
});
NotifierProvider.autoDispose<RoutingNotifier, RoutingState>(
RoutingNotifier.new,
);

View file

@ -38,20 +38,22 @@ class SearchState {
}
}
class SearchNotifier extends StateNotifier<SearchState> {
final SearchRepository _repository;
class SearchNotifier extends Notifier<SearchState> {
late SearchRepository _repository;
Timer? _debounce;
SearchNotifier(this._repository) : super(const SearchState()) {
_loadHistory();
@override
SearchState build() {
_repository = ref.watch(searchRepositoryProvider);
ref.onDispose(() => _debounce?.cancel());
Future.microtask(_loadHistory);
return const SearchState();
}
Future<void> _loadHistory() async {
final history = await _repository.getRecentSearches();
if (mounted) {
state = state.copyWith(recentSearches: history);
}
}
void updateQuery(String query) {
state = state.copyWith(query: query, clearError: true);
@ -72,18 +74,16 @@ class SearchNotifier extends StateNotifier<SearchState> {
Future<void> _performSearch(String query) async {
try {
final results = await _repository.search(query);
if (mounted && state.query == query) {
if (state.query == query) {
state = state.copyWith(results: results, isLoading: false);
}
} catch (e) {
if (mounted) {
state = state.copyWith(
isLoading: false,
error: 'Search failed. Please try again.',
);
}
}
}
Future<void> selectResult(SearchResult result) async {
await _repository.saveToHistory(
@ -103,15 +103,9 @@ class SearchNotifier extends StateNotifier<SearchState> {
await _repository.clearHistory();
await _loadHistory();
}
@override
void dispose() {
_debounce?.cancel();
super.dispose();
}
}
final searchProvider =
StateNotifierProvider.autoDispose<SearchNotifier, SearchState>((ref) {
return SearchNotifier(ref.watch(searchRepositoryProvider));
});
NotifierProvider.autoDispose<SearchNotifier, SearchState>(
SearchNotifier.new,
);

View file

@ -6,20 +6,21 @@ import '../../../../core/database/app_database.dart';
/// ThemeMode provider, watched by PrivacyMapsApp.
final themeModeProvider =
StateNotifierProvider<ThemeModeNotifier, ThemeMode>((ref) {
return ThemeModeNotifier(ref.watch(appDatabaseProvider));
});
NotifierProvider<ThemeModeNotifier, ThemeMode>(ThemeModeNotifier.new);
class ThemeModeNotifier extends StateNotifier<ThemeMode> {
final AppDatabase _db;
class ThemeModeNotifier extends Notifier<ThemeMode> {
late AppDatabase _db;
ThemeModeNotifier(this._db) : super(ThemeMode.system) {
_load();
@override
ThemeMode build() {
_db = ref.watch(appDatabaseProvider);
Future.microtask(_load);
return ThemeMode.system;
}
Future<void> _load() async {
final value = await _db.getSetting(AppConstants.settingThemeMode);
if (value != null && mounted) {
if (value != null) {
state = _parse(value);
}
}

View file

@ -6,9 +6,11 @@ import FlutterMacOS
import Foundation
import geolocator_apple
import package_info_plus
import sqlite3_flutter_libs
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
GeolocatorPlugin.register(with: registry.registrar(forPlugin: "GeolocatorPlugin"))
FPPPackageInfoPlusPlugin.register(with: registry.registrar(forPlugin: "FPPPackageInfoPlusPlugin"))
Sqlite3FlutterLibsPlugin.register(with: registry.registrar(forPlugin: "Sqlite3FlutterLibsPlugin"))
}

View file

@ -3,6 +3,8 @@ PODS:
- geolocator_apple (1.2.0):
- Flutter
- FlutterMacOS
- package_info_plus (0.0.1):
- FlutterMacOS
- sqlite3 (3.52.0):
- sqlite3/common (= 3.52.0)
- sqlite3/common (3.52.0)
@ -32,6 +34,7 @@ PODS:
DEPENDENCIES:
- FlutterMacOS (from `Flutter/ephemeral`)
- geolocator_apple (from `Flutter/ephemeral/.symlinks/plugins/geolocator_apple/darwin`)
- package_info_plus (from `Flutter/ephemeral/.symlinks/plugins/package_info_plus/macos`)
- sqlite3_flutter_libs (from `Flutter/ephemeral/.symlinks/plugins/sqlite3_flutter_libs/darwin`)
SPEC REPOS:
@ -43,12 +46,15 @@ EXTERNAL SOURCES:
:path: Flutter/ephemeral
geolocator_apple:
:path: Flutter/ephemeral/.symlinks/plugins/geolocator_apple/darwin
package_info_plus:
:path: Flutter/ephemeral/.symlinks/plugins/package_info_plus/macos
sqlite3_flutter_libs:
:path: Flutter/ephemeral/.symlinks/plugins/sqlite3_flutter_libs/darwin
SPEC CHECKSUMS:
FlutterMacOS: d0db08ddef1a9af05a5ec4b724367152bb0500b1
geolocator_apple: ab36aa0e8b7d7a2d7639b3b4e48308394e8cef5e
package_info_plus: f0052d280d17aa382b932f399edf32507174e870
sqlite3: a51c07cf16e023d6c48abd5e5791a61a47354921
sqlite3_flutter_libs: b3e120efe9a82017e5552a620f696589ed4f62ab

View file

@ -5,26 +5,26 @@ packages:
dependency: transitive
description:
name: _fe_analyzer_shared
sha256: da0d9209ca76bde579f2da330aeb9df62b6319c834fa7baae052021b0462401f
sha256: c209688d9f5a5f26b2fb47a188131a6fb9e876ae9e47af3737c0b4f58a93470d
url: "https://pub.dev"
source: hosted
version: "85.0.0"
version: "91.0.0"
analyzer:
dependency: transitive
description:
name: analyzer
sha256: f4ad0fea5f102201015c9aae9d93bc02f75dd9491529a8c21f88d17a8523d44c
sha256: f51c8499b35f9b26820cfe914828a6a98a94efd5cc78b37bb7d03debae3a1d08
url: "https://pub.dev"
source: hosted
version: "7.6.0"
analyzer_plugin:
version: "8.4.1"
analyzer_buffer:
dependency: transitive
description:
name: analyzer_plugin
sha256: a5ab7590c27b779f3d4de67f31c4109dbe13dd7339f86461a6f2a8ab2594d8ce
name: analyzer_buffer
sha256: aba2f75e63b3135fd1efaa8b6abefe1aa6e41b6bd9806221620fa48f98156033
url: "https://pub.dev"
source: hosted
version: "0.13.4"
version: "0.1.11"
args:
dependency: transitive
description:
@ -53,18 +53,18 @@ packages:
dependency: transitive
description:
name: build
sha256: "51dc711996cbf609b90cbe5b335bbce83143875a9d58e4b5c6d3c4f684d3dda7"
sha256: aadd943f4f8cc946882c954c187e6115a84c98c81ad1d9c6cbf0895a8c85da9c
url: "https://pub.dev"
source: hosted
version: "2.5.4"
version: "4.0.5"
build_config:
dependency: transitive
description:
name: build_config
sha256: "4ae2de3e1e67ea270081eaee972e1bd8f027d459f249e0f1186730784c2e7e33"
sha256: "4070d2a59f8eec34c97c86ceb44403834899075f66e8a9d59706f8e7834f6f71"
url: "https://pub.dev"
source: hosted
version: "1.1.2"
version: "1.3.0"
build_daemon:
dependency: transitive
description:
@ -73,30 +73,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "4.1.1"
build_resolvers:
dependency: transitive
description:
name: build_resolvers
sha256: ee4257b3f20c0c90e72ed2b57ad637f694ccba48839a821e87db762548c22a62
url: "https://pub.dev"
source: hosted
version: "2.5.4"
build_runner:
dependency: "direct dev"
description:
name: build_runner
sha256: "382a4d649addbfb7ba71a3631df0ec6a45d5ab9b098638144faf27f02778eb53"
sha256: "521daf8d189deb79ba474e43a696b41c49fb3987818dbacf3308f1e03673a75e"
url: "https://pub.dev"
source: hosted
version: "2.5.4"
build_runner_core:
dependency: transitive
description:
name: build_runner_core
sha256: "85fbbb1036d576d966332a3f5ce83f2ce66a40bea1a94ad2d5fc29a19a0d3792"
url: "https://pub.dev"
source: hosted
version: "9.1.2"
version: "2.13.1"
built_collection:
dependency: transitive
description:
@ -137,6 +121,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.0.4"
cli_config:
dependency: transitive
description:
name: cli_config
sha256: ac20a183a07002b700f0c25e61b7ee46b23c309d76ab7b7640a028f18e4d99ec
url: "https://pub.dev"
source: hosted
version: "0.2.0"
cli_util:
dependency: transitive
description:
@ -185,6 +177,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "3.1.2"
coverage:
dependency: transitive
description:
name: coverage
sha256: "5da775aa218eaf2151c721b16c01c7676fbfdd99cebba2bf64e8b807a28ff94d"
url: "https://pub.dev"
source: hosted
version: "1.15.0"
crypto:
dependency: transitive
description:
@ -193,22 +193,6 @@ packages:
url: "https://pub.dev"
source: hosted
version: "3.0.7"
custom_lint_core:
dependency: transitive
description:
name: custom_lint_core
sha256: "31110af3dde9d29fb10828ca33f1dce24d2798477b167675543ce3d208dee8be"
url: "https://pub.dev"
source: hosted
version: "0.7.5"
custom_lint_visitor:
dependency: transitive
description:
name: custom_lint_visitor
sha256: "4a86a0d8415a91fbb8298d6ef03e9034dc8e323a599ddc4120a0e36c433983a2"
url: "https://pub.dev"
source: hosted
version: "1.0.0+7.7.0"
dart_earcut:
dependency: transitive
description:
@ -221,10 +205,18 @@ packages:
dependency: transitive
description:
name: dart_style
sha256: "8a0e5fba27e8ee025d2ffb4ee820b4e6e2cf5e4246a6b1a477eb66866947e0bb"
sha256: a9c30492da18ff84efe2422ba2d319a89942d93e58eb0b73d32abe822ef54b7b
url: "https://pub.dev"
source: hosted
version: "3.1.1"
version: "3.1.3"
dbus:
dependency: transitive
description:
name: dbus
sha256: d0c98dcd4f5169878b6cf8f6e0a52403a9dff371a3e2f019697accbf6f44a270
url: "https://pub.dev"
source: hosted
version: "0.7.12"
dio:
dependency: "direct main"
description:
@ -253,10 +245,10 @@ packages:
dependency: "direct dev"
description:
name: drift_dev
sha256: "68c138e884527d2bd61df2ade276c3a144df84d1adeb0ab8f3196b5afe021bd4"
sha256: "4db0eeedc7e8bed117a9f22d867ab7a3a294300fed5c269aac90d0b3545967ca"
url: "https://pub.dev"
source: hosted
version: "2.28.0"
version: "2.28.3"
executor_lib:
dependency: transitive
description:
@ -318,22 +310,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "7.0.2"
flutter_map_cancellable_tile_provider:
dependency: "direct main"
description:
name: flutter_map_cancellable_tile_provider
sha256: "03662220ce0cd784ad2f2a45c36fc379b8b315c74f5c12b5ff4a0515eab1acd1"
url: "https://pub.dev"
source: hosted
version: "3.0.2"
flutter_riverpod:
dependency: "direct main"
description:
name: flutter_riverpod
sha256: "9532ee6db4a943a1ed8383072a2e3eeda041db5657cdf6d2acecf3c21ecbe7e1"
sha256: "38ec6c303e2c83ee84512f5fc2a82ae311531021938e63d7137eccc107bf3c02"
url: "https://pub.dev"
source: hosted
version: "2.6.1"
version: "3.1.0"
flutter_test:
dependency: "direct dev"
description: flutter
@ -348,18 +332,18 @@ packages:
dependency: "direct dev"
description:
name: freezed
sha256: "59a584c24b3acdc5250bb856d0d3e9c0b798ed14a4af1ddb7dc1c7b41df91c9c"
sha256: "13065f10e135263a4f5a4391b79a8efc5fb8106f8dd555a9e49b750b45393d77"
url: "https://pub.dev"
source: hosted
version: "2.5.8"
version: "3.2.3"
freezed_annotation:
dependency: "direct main"
description:
name: freezed_annotation
sha256: c2e2d632dd9b8a2b7751117abcfc2b4888ecfe181bd9fca7170d9ef02e595fe2
sha256: "7294967ff0a6d98638e7acb774aac3af2550777accd8149c90af5b014e6d44d8"
url: "https://pub.dev"
source: hosted
version: "2.4.4"
version: "3.1.0"
frontend_server_client:
dependency: transitive
description:
@ -368,22 +352,30 @@ packages:
url: "https://pub.dev"
source: hosted
version: "4.0.0"
geoclue:
dependency: transitive
description:
name: geoclue
sha256: c2a998c77474fc57aa00c6baa2928e58f4b267649057a1c76738656e9dbd2a7f
url: "https://pub.dev"
source: hosted
version: "0.1.1"
geolocator:
dependency: "direct main"
description:
name: geolocator
sha256: "149876cc5207a0f5daf4fdd3bfcf0a0f27258b3fe95108fa084f527ad0568f1b"
sha256: "79939537046c9025be47ec645f35c8090ecadb6fe98eba146a0d25e8c1357516"
url: "https://pub.dev"
source: hosted
version: "12.0.0"
version: "14.0.2"
geolocator_android:
dependency: transitive
description:
name: geolocator_android
sha256: fcb1760a50d7500deca37c9a666785c047139b5f9ee15aa5469fae7dbbe3170d
sha256: "179c3cb66dfa674fc9ccbf2be872a02658724d1c067634e2c427cf6df7df901a"
url: "https://pub.dev"
source: hosted
version: "4.6.2"
version: "5.0.2"
geolocator_apple:
dependency: transitive
description:
@ -392,6 +384,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.3.13"
geolocator_linux:
dependency: transitive
description:
name: geolocator_linux
sha256: d64112a205931926f4363bb6bd48f14cb38e7326833041d170615586cd143797
url: "https://pub.dev"
source: hosted
version: "0.2.4"
geolocator_platform_interface:
dependency: transitive
description:
@ -440,6 +440,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.3.2"
gsettings:
dependency: transitive
description:
name: gsettings
sha256: "1b0ce661f5436d2db1e51f3c4295a49849f03d304003a7ba177d01e3a858249c"
url: "https://pub.dev"
source: hosted
version: "0.2.8"
hooks:
dependency: transitive
description:
@ -488,14 +496,6 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.0.5"
js:
dependency: transitive
description:
name: js
sha256: "53385261521cc4a0c4658fd0ad07a7d14591cf8fc33abbceae306ddb974888dc"
url: "https://pub.dev"
source: hosted
version: "0.7.2"
json_annotation:
dependency: "direct main"
description:
@ -508,10 +508,10 @@ packages:
dependency: "direct dev"
description:
name: json_serializable
sha256: c50ef5fc083d5b5e12eef489503ba3bf5ccc899e487d691584699b4bdefeea8c
sha256: c5b2ee75210a0f263c6c7b9eeea80553dbae96ea1bf57f02484e806a3ffdffa3
url: "https://pub.dev"
source: hosted
version: "6.9.5"
version: "6.11.2"
latlong2:
dependency: "direct main"
description:
@ -616,6 +616,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.0.0"
mockito:
dependency: transitive
description:
name: mockito
sha256: eff30d002f0c8bf073b6f929df4483b543133fcafce056870163587b03f1d422
url: "https://pub.dev"
source: hosted
version: "5.6.4"
native_toolchain_c:
dependency: transitive
description:
@ -624,6 +632,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "0.17.6"
node_preamble:
dependency: transitive
description:
name: node_preamble
sha256: "6e7eac89047ab8a8d26cf16127b5ed26de65209847630400f9aefd7cd5c730db"
url: "https://pub.dev"
source: hosted
version: "2.0.2"
objective_c:
dependency: transitive
description:
@ -640,6 +656,22 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.2.0"
package_info_plus:
dependency: transitive
description:
name: package_info_plus
sha256: "468c26b4254ab01979fa5e4a98cb343ea3631b9acee6f21028997419a80e1a20"
url: "https://pub.dev"
source: hosted
version: "9.0.1"
package_info_plus_platform_interface:
dependency: transitive
description:
name: package_info_plus_platform_interface
sha256: "202a487f08836a592a6bd4f901ac69b3a8f146af552bbd14407b6b41e1c3f086"
url: "https://pub.dev"
source: hosted
version: "3.2.1"
path:
dependency: "direct main"
description:
@ -696,6 +728,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.3.0"
petitparser:
dependency: transitive
description:
name: petitparser
sha256: "91bd59303e9f769f108f8df05e371341b15d59e995e6806aefab827b58336675"
url: "https://pub.dev"
source: hosted
version: "7.0.2"
platform:
dependency: transitive
description:
@ -772,34 +812,34 @@ packages:
dependency: transitive
description:
name: riverpod
sha256: "59062512288d3056b2321804332a13ffdd1bf16df70dcc8e506e411280a72959"
sha256: "16ff608d21e8ea64364f2b7c049c94a02ab81668f78845862b6e88b71dd4935a"
url: "https://pub.dev"
source: hosted
version: "2.6.1"
version: "3.1.0"
riverpod_analyzer_utils:
dependency: transitive
description:
name: riverpod_analyzer_utils
sha256: "837a6dc33f490706c7f4632c516bcd10804ee4d9ccc8046124ca56388715fdf3"
sha256: "947b05d04c52a546a2ac6b19ef2a54b08520ff6bdf9f23d67957a4c8df1c3bc0"
url: "https://pub.dev"
source: hosted
version: "0.5.9"
version: "1.0.0-dev.8"
riverpod_annotation:
dependency: "direct main"
description:
name: riverpod_annotation
sha256: e14b0bf45b71326654e2705d462f21b958f987087be850afd60578fcd502d1b8
sha256: cc1474bc2df55ec3c1da1989d139dcef22cd5e2bd78da382e867a69a8eca2e46
url: "https://pub.dev"
source: hosted
version: "2.6.1"
version: "4.0.0"
riverpod_generator:
dependency: "direct dev"
description:
name: riverpod_generator
sha256: "120d3310f687f43e7011bb213b90a436f1bbc300f0e4b251a72c39bccb017a4f"
sha256: e43b1537229cc8f487f09b0c20d15dba840acbadcf5fc6dad7ad5e8ab75950dc
url: "https://pub.dev"
source: hosted
version: "2.6.4"
version: "4.0.0+1"
shelf:
dependency: transitive
description:
@ -808,6 +848,22 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.4.2"
shelf_packages_handler:
dependency: transitive
description:
name: shelf_packages_handler
sha256: "89f967eca29607c933ba9571d838be31d67f53f6e4ee15147d5dc2934fee1b1e"
url: "https://pub.dev"
source: hosted
version: "3.0.2"
shelf_static:
dependency: transitive
description:
name: shelf_static
sha256: c87c3875f91262785dade62d135760c2c69cb217ac759485334c5857ad89f6e3
url: "https://pub.dev"
source: hosted
version: "1.1.3"
shelf_web_socket:
dependency: transitive
description:
@ -825,18 +881,34 @@ packages:
dependency: transitive
description:
name: source_gen
sha256: "35c8150ece9e8c8d263337a265153c3329667640850b9304861faea59fc98f6b"
sha256: "732792cfd197d2161a65bb029606a46e0a18ff30ef9e141a7a82172b05ea8ecd"
url: "https://pub.dev"
source: hosted
version: "2.0.0"
version: "4.2.2"
source_helper:
dependency: transitive
description:
name: source_helper
sha256: a447acb083d3a5ef17f983dd36201aeea33fedadb3228fa831f2f0c92f0f3aca
sha256: "6a3c6cc82073a8797f8c4dc4572146114a39652851c157db37e964d9c7038723"
url: "https://pub.dev"
source: hosted
version: "1.3.7"
version: "1.3.8"
source_map_stack_trace:
dependency: transitive
description:
name: source_map_stack_trace
sha256: c0713a43e323c3302c2abe2a1cc89aa057a387101ebd280371d6a6c9fa68516b
url: "https://pub.dev"
source: hosted
version: "2.1.2"
source_maps:
dependency: transitive
description:
name: source_maps
sha256: "190222579a448b03896e0ca6eca5998fa810fda630c1d65e2f78b3f638f54812"
url: "https://pub.dev"
source: hosted
version: "0.10.13"
source_span:
dependency: transitive
description:
@ -917,6 +989,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.2.2"
test:
dependency: transitive
description:
name: test
sha256: "280d6d890011ca966ad08df7e8a4ddfab0fb3aa49f96ed6de56e3521347a9ae7"
url: "https://pub.dev"
source: hosted
version: "1.30.0"
test_api:
dependency: transitive
description:
@ -925,14 +1005,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "0.7.10"
timing:
test_core:
dependency: transitive
description:
name: timing
sha256: "62ee18aca144e4a9f29d212f5a4c6a053be252b895ab14b5821996cff4ed90fe"
name: test_core
sha256: "0381bd1585d1a924763c308100f2138205252fb90c9d4eeaf28489ee65ccde51"
url: "https://pub.dev"
source: hosted
version: "1.0.2"
version: "0.6.16"
typed_data:
dependency: transitive
description:
@ -1029,6 +1109,22 @@ packages:
url: "https://pub.dev"
source: hosted
version: "3.0.3"
webkit_inspection_protocol:
dependency: transitive
description:
name: webkit_inspection_protocol
sha256: "87d3f2333bb240704cd3f1c6b5b7acd8a10e7f0bc28c28dcf14e782014f4a572"
url: "https://pub.dev"
source: hosted
version: "1.2.1"
win32:
dependency: transitive
description:
name: win32
sha256: d7cb55e04cd34096cd3a79b3330245f54cb96a370a1c27adb3c84b917de8b08e
url: "https://pub.dev"
source: hosted
version: "5.15.0"
wkt_parser:
dependency: transitive
description:
@ -1045,6 +1141,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.1.0"
xml:
dependency: transitive
description:
name: xml
sha256: "971043b3a0d3da28727e40ed3e0b5d18b742fa5a68665cca88e74b7876d5e025"
url: "https://pub.dev"
source: hosted
version: "6.6.1"
yaml:
dependency: transitive
description:

View file

@ -31,17 +31,16 @@ dependencies:
flutter:
sdk: flutter
flutter_map: ^7.0.0
flutter_map_cancellable_tile_provider: ^3.0.0
vector_map_tiles: ^8.0.0
flutter_riverpod: ^2.5.0
riverpod_annotation: ^2.3.0
flutter_riverpod: ^3.0.0
riverpod_annotation: ^4.0.0
dio: ^5.4.0
drift: ^2.16.0
drift: ^2.28.0
sqlite3_flutter_libs: ^0.5.0
path_provider: ^2.1.0
geolocator: ^12.0.0
geolocator: ^14.0.0
go_router: ^14.0.0
freezed_annotation: ^2.4.0
freezed_annotation: ^3.0.0
json_annotation: ^4.9.0
latlong2: ^0.9.0
path: ^1.9.0
@ -50,11 +49,11 @@ dev_dependencies:
flutter_test:
sdk: flutter
flutter_lints: ^5.0.0
build_runner: ^2.4.0
freezed: ^2.5.0
build_runner: ^2.13.0
freezed: ^3.0.0
json_serializable: ^6.7.0
drift_dev: ^2.16.0
riverpod_generator: ^2.4.0
drift_dev: ^2.28.0
riverpod_generator: ^4.0.0
# For information on the generic Dart part of this file, see the
# following page: https://dart.dev/tools/pub/pubspec