feat: Gestion des secteurs et migration v3.0.4+304
- Ajout système complet de gestion des secteurs avec contours géographiques - Import des contours départementaux depuis GeoJSON - API REST pour la gestion des secteurs (/api/sectors) - Service de géolocalisation pour déterminer les secteurs - Migration base de données avec tables x_departements_contours et sectors_adresses - Interface Flutter pour visualisation et gestion des secteurs - Ajout thème sombre dans l'application - Corrections diverses et optimisations 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
@@ -1,2 +1,2 @@
|
||||
file:///Users/pierre/.pub-cache/hosted/pub.dev/build_daemon-4.0.4/lib/fake.dart
|
||||
file:///Users/pierre/.pub-cache/hosted/pub.dev/build_runner-2.4.15/lib/fake.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/build_daemon-4.0.4/lib/fake.dart
|
||||
file:///home/pierre/.pub-cache/hosted/pub.dev/build_runner-2.5.4/lib/fake.dart
|
||||
@@ -1,11 +1,13 @@
|
||||
// @dart=3.6
|
||||
// ignore_for_file: directives_ordering
|
||||
// build_runner >=2.4.16
|
||||
// ignore_for_file: no_leading_underscores_for_library_prefixes
|
||||
import 'package:build_runner_core/build_runner_core.dart' as _i1;
|
||||
import 'package:hive_generator/hive_generator.dart' as _i2;
|
||||
import 'package:source_gen/builder.dart' as _i3;
|
||||
import 'package:build_resolvers/builder.dart' as _i4;
|
||||
import 'dart:isolate' as _i5;
|
||||
import 'dart:isolate' as _i4;
|
||||
import 'package:build_runner/src/build_script_generate/build_process_state.dart'
|
||||
as _i5;
|
||||
import 'package:build_runner/build_runner.dart' as _i6;
|
||||
import 'dart:io' as _i7;
|
||||
|
||||
@@ -24,18 +26,6 @@ final _builders = <_i1.BuilderApplication>[
|
||||
hideOutput: false,
|
||||
appliesBuilders: const [r'source_gen:part_cleanup'],
|
||||
),
|
||||
_i1.apply(
|
||||
r'build_resolvers:transitive_digests',
|
||||
[_i4.transitiveDigestsBuilder],
|
||||
_i1.toAllPackages(),
|
||||
isOptional: true,
|
||||
hideOutput: true,
|
||||
appliesBuilders: const [r'build_resolvers:transitive_digest_cleanup'],
|
||||
),
|
||||
_i1.applyPostProcess(
|
||||
r'build_resolvers:transitive_digest_cleanup',
|
||||
_i4.transitiveDigestCleanup,
|
||||
),
|
||||
_i1.applyPostProcess(
|
||||
r'source_gen:part_cleanup',
|
||||
_i3.partCleanup,
|
||||
@@ -43,12 +33,13 @@ final _builders = <_i1.BuilderApplication>[
|
||||
];
|
||||
void main(
|
||||
List<String> args, [
|
||||
_i5.SendPort? sendPort,
|
||||
_i4.SendPort? sendPort,
|
||||
]) async {
|
||||
var result = await _i6.run(
|
||||
await _i5.buildProcessState.receive(sendPort);
|
||||
_i5.buildProcessState.isolateExitCode = await _i6.run(
|
||||
args,
|
||||
_builders,
|
||||
);
|
||||
sendPort?.send(result);
|
||||
_i7.exitCode = result;
|
||||
_i7.exitCode = _i5.buildProcessState.isolateExitCode!;
|
||||
await _i5.buildProcessState.send(sendPort);
|
||||
}
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
<EFBFBD>
|
||||
@@ -1 +0,0 @@
|
||||
<EFBFBD>C><3E>N<EFBFBD>a<EFBFBD><61><EFBFBD><EFBFBD><EFBFBD><EFBFBD>"<22>
|
||||
@@ -1 +0,0 @@
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>5z<EFBFBD><EFBFBD><EFBFBD>k<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
@@ -1 +0,0 @@
|
||||
<EFBFBD>ũ<EFBFBD><EFBFBD><0C><><EFBFBD>U/!<21><>W<EFBFBD>
|
||||
@@ -1 +0,0 @@
|
||||
<EFBFBD> n<><6E>A<EFBFBD><41><08><13>+<2B><><EFBFBD>
|
||||
@@ -1 +0,0 @@
|
||||
X<EFBFBD>͊?<3F>sSφ?/^<5E>-k
|
||||
@@ -1 +0,0 @@
|
||||
<EFBFBD><EFBFBD><EFBFBD>0)9#<23>D<EFBFBD><<3C>Ѹ#
|
||||
@@ -1 +0,0 @@
|
||||
!iT<69>IeS<65> 2d<32>.<2E>n
|
||||
@@ -1 +0,0 @@
|
||||
<05><><EFBFBD>[<5B><>,<2C><><EFBFBD><EFBFBD><18><><EFBFBD>
|
||||
@@ -1 +0,0 @@
|
||||
e<EFBFBD>v<EFBFBD><EFBFBD><EFBFBD>K4I<34>]Ĕ<>:
|
||||
@@ -15,11 +15,11 @@ class PassageModelAdapter extends TypeAdapter<PassageModel> {
|
||||
return PassageModel(
|
||||
id: fields[0] as int,
|
||||
fkOperation: fields[1] as int,
|
||||
fkSector: fields[2] as int,
|
||||
fkSector: fields[2] as int?,
|
||||
fkUser: fields[3] as int,
|
||||
fkType: fields[4] as int,
|
||||
fkAdresse: fields[5] as String,
|
||||
passedAt: fields[6] as DateTime,
|
||||
passedAt: fields[6] as DateTime?,
|
||||
numero: fields[7] as String,
|
||||
rue: fields[8] as String,
|
||||
rueBis: fields[9] as String,
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
C<EFBFBD><EFBFBD><EFBFBD>F}<7D><EFBFBD>7<><37><EFBFBD><EFBFBD>9
|
||||
@@ -1 +0,0 @@
|
||||
<EFBFBD><EFBFBD>E>`<60>e0<65>sl<73><6C><0C>
|
||||
@@ -1 +0,0 @@
|
||||
<EFBFBD>FJ6<EFBFBD><EFBFBD>6<EFBFBD><EFBFBD><EFBFBD><EFBFBD>e<EFBFBD><EFBFBD>-b
|
||||
@@ -1 +0,0 @@
|
||||
<EFBFBD>[ڀJ<DA80>n<EFBFBD><6E>(<28>v/<2F>~<7E>
|
||||
@@ -1 +0,0 @@
|
||||
<EFBFBD><EFBFBD><EFBFBD>ulM<6C>L<EFBFBD><4C><EFBFBD><EFBFBD>M
|
||||
@@ -1 +0,0 @@
|
||||
<11><><1D>;<3B><><0B><>^<5E>:p
|
||||
@@ -1 +0,0 @@
|
||||
o~<7E>+x<>\6<1B><><EFBFBD>o<EFBFBD><6F>a
|
||||
@@ -1,2 +0,0 @@
|
||||
Q<EFBFBD>;<14><><EFBFBD><EFBFBD><EFBFBD>
|
||||
<EFBFBD>)<29>j<EFBFBD>
|
||||
@@ -1 +0,0 @@
|
||||
<EFBFBD>I<EFBFBD>4<EFBFBD><17>]7<12>{Rf<52>
|
||||
@@ -1 +0,0 @@
|
||||
<EFBFBD><EFBFBD><EFBFBD>ve<EFBFBD>wz<EFBFBD>z::O<><4F><EFBFBD>
|
||||
@@ -1 +1 @@
|
||||
{"sdk":"3.8.1 (stable) (Wed May 28 00:47:25 2025 -0700) on \"macos_arm64\"","analyzer":"/Users/pierre/.pub-cache/hosted/pub.dev/analyzer-6.11.0","build_resolvers":"/Users/pierre/.pub-cache/hosted/pub.dev/build_resolvers-2.4.4"}
|
||||
{"sdk":"3.8.1 (stable) (Wed May 28 00:47:25 2025 -0700) on \"linux_x64\"","analyzer":"/home/pierre/.pub-cache/hosted/pub.dev/analyzer-6.11.0","build_resolvers":"/home/pierre/.pub-cache/hosted/pub.dev/build_resolvers-2.5.4"}
|
||||
@@ -9,6 +9,7 @@
|
||||
import 'package:connectivity_plus/src/connectivity_plus_web.dart';
|
||||
import 'package:geolocator_web/geolocator_web.dart';
|
||||
import 'package:package_info_plus/src/package_info_plus_web.dart';
|
||||
import 'package:shared_preferences_web/shared_preferences_web.dart';
|
||||
import 'package:url_launcher_web/url_launcher_web.dart';
|
||||
import 'package:flutter_web_plugins/flutter_web_plugins.dart';
|
||||
|
||||
@@ -17,6 +18,7 @@ void registerPlugins([final Registrar? pluginRegistrar]) {
|
||||
ConnectivityPlusWebPlugin.registerWith(registrar);
|
||||
GeolocatorPlugin.registerWith(registrar);
|
||||
PackageInfoPlusWebPlugin.registerWith(registrar);
|
||||
SharedPreferencesPlugin.registerWith(registrar);
|
||||
UrlLauncherPlugin.registerWith(registrar);
|
||||
registrar.registerMessageHandler();
|
||||
}
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
["/Users/pierre/dev/geosector/app/build/web/*/index.html","/Users/pierre/dev/geosector/app/build/web/flutter_bootstrap.js","/Users/pierre/dev/geosector/app/build/web/main.dart.js","/Users/pierre/dev/geosector/app/build/web/assets/assets/images/geosector-logo.png","/Users/pierre/dev/geosector/app/build/web/assets/assets/images/logo-geosector-1024.png","/Users/pierre/dev/geosector/app/build/web/assets/assets/images/icon-geosector.svg","/Users/pierre/dev/geosector/app/build/web/assets/assets/images/logo_recu.png","/Users/pierre/dev/geosector/app/build/web/assets/assets/animations/geo_main.json","/Users/pierre/dev/geosector/app/build/web/assets/assets/fonts/Figtree-VariableFont_wght.ttf","/Users/pierre/dev/geosector/app/build/web/assets/packages/cupertino_icons/assets/CupertinoIcons.ttf","/Users/pierre/dev/geosector/app/build/web/assets/packages/flutter_map/lib/assets/flutter_map_logo.png","/Users/pierre/dev/geosector/app/build/web/assets/fonts/MaterialIcons-Regular.otf","/Users/pierre/dev/geosector/app/build/web/assets/shaders/ink_sparkle.frag","/Users/pierre/dev/geosector/app/build/web/assets/AssetManifest.json","/Users/pierre/dev/geosector/app/build/web/assets/AssetManifest.bin","/Users/pierre/dev/geosector/app/build/web/assets/AssetManifest.bin.json","/Users/pierre/dev/geosector/app/build/web/assets/FontManifest.json","/Users/pierre/dev/geosector/app/build/web/assets/NOTICES","/Users/pierre/dev/geosector/app/build/web/.DS_Store","/Users/pierre/dev/geosector/app/build/web/favicon-64.png","/Users/pierre/dev/geosector/app/build/web/favicon-16.png","/Users/pierre/dev/geosector/app/build/web/favicon.png","/Users/pierre/dev/geosector/app/build/web/icons/Icon-192.png","/Users/pierre/dev/geosector/app/build/web/icons/Icon-maskable-192.png","/Users/pierre/dev/geosector/app/build/web/icons/Icon-152.png","/Users/pierre/dev/geosector/app/build/web/icons/Icon-180.png","/Users/pierre/dev/geosector/app/build/web/icons/Icon-167.png","/Users/pierre/dev/geosector/app/build/web/icons/Icon-maskable-512.png","/Users/pierre/dev/geosector/app/build/web/icons/Icon-512.png","/Users/pierre/dev/geosector/app/build/web/manifest.json","/Users/pierre/dev/geosector/app/build/web/favicon-32.png","/Users/pierre/dev/geosector/app/build/web/flutter_service_worker.js"]
|
||||
@@ -1 +0,0 @@
|
||||
/Users/pierre/dev/geosector/app/build/web/flutter_service_worker.js: /Users/pierre/dev/geosector/app/build/web/flutter_bootstrap.js /Users/pierre/dev/geosector/app/build/web/version.json /Users/pierre/dev/geosector/app/build/web/index.html /Users/pierre/dev/geosector/app/build/web/favicon-64.png /Users/pierre/dev/geosector/app/build/web/favicon-16.png /Users/pierre/dev/geosector/app/build/web/main.dart.js /Users/pierre/dev/geosector/app/build/web/flutter.js /Users/pierre/dev/geosector/app/build/web/favicon.png /Users/pierre/dev/geosector/app/build/web/icons/Icon-192.png /Users/pierre/dev/geosector/app/build/web/icons/Icon-maskable-192.png /Users/pierre/dev/geosector/app/build/web/icons/Icon-152.png /Users/pierre/dev/geosector/app/build/web/icons/Icon-180.png /Users/pierre/dev/geosector/app/build/web/icons/Icon-167.png /Users/pierre/dev/geosector/app/build/web/icons/Icon-maskable-512.png /Users/pierre/dev/geosector/app/build/web/icons/Icon-512.png /Users/pierre/dev/geosector/app/build/web/manifest.json /Users/pierre/dev/geosector/app/build/web/favicon-32.png /Users/pierre/dev/geosector/app/build/web/assets/AssetManifest.json /Users/pierre/dev/geosector/app/build/web/assets/NOTICES /Users/pierre/dev/geosector/app/build/web/assets/FontManifest.json /Users/pierre/dev/geosector/app/build/web/assets/AssetManifest.bin.json /Users/pierre/dev/geosector/app/build/web/assets/packages/cupertino_icons/assets/CupertinoIcons.ttf /Users/pierre/dev/geosector/app/build/web/assets/packages/flutter_map/lib/assets/flutter_map_logo.png /Users/pierre/dev/geosector/app/build/web/assets/shaders/ink_sparkle.frag /Users/pierre/dev/geosector/app/build/web/assets/AssetManifest.bin /Users/pierre/dev/geosector/app/build/web/assets/fonts/MaterialIcons-Regular.otf /Users/pierre/dev/geosector/app/build/web/assets/assets/images/geosector-logo.png /Users/pierre/dev/geosector/app/build/web/assets/assets/images/logo-geosector-1024.png /Users/pierre/dev/geosector/app/build/web/assets/assets/images/icon-geosector.svg /Users/pierre/dev/geosector/app/build/web/assets/assets/images/logo_recu.png /Users/pierre/dev/geosector/app/build/web/assets/assets/fonts/Figtree-VariableFont_wght.ttf /Users/pierre/dev/geosector/app/build/web/assets/assets/animations/geo_main.json /Users/pierre/dev/geosector/app/build/web/canvaskit/skwasm.js /Users/pierre/dev/geosector/app/build/web/canvaskit/skwasm.js.symbols /Users/pierre/dev/geosector/app/build/web/canvaskit/canvaskit.js.symbols /Users/pierre/dev/geosector/app/build/web/canvaskit/skwasm.wasm /Users/pierre/dev/geosector/app/build/web/canvaskit/chromium/canvaskit.js.symbols /Users/pierre/dev/geosector/app/build/web/canvaskit/chromium/canvaskit.js /Users/pierre/dev/geosector/app/build/web/canvaskit/chromium/canvaskit.wasm /Users/pierre/dev/geosector/app/build/web/canvaskit/canvaskit.js /Users/pierre/dev/geosector/app/build/web/canvaskit/canvaskit.wasm
|
||||
@@ -1 +0,0 @@
|
||||
{"inputs":["/Users/pierre/dev/flutter/packages/flutter_tools/lib/src/build_system/targets/web.dart"],"outputs":["/Users/pierre/dev/geosector/app/.dart_tool/flutter_build/01af3ba6904766cfc820f0897fc71456/main.dart"]}
|
||||
@@ -1 +0,0 @@
|
||||
/Users/pierre/dev/geosector/app/build/web/.DS_Store /Users/pierre/dev/geosector/app/build/web/favicon-64.png /Users/pierre/dev/geosector/app/build/web/favicon-16.png /Users/pierre/dev/geosector/app/build/web/favicon.png /Users/pierre/dev/geosector/app/build/web/icons/Icon-192.png /Users/pierre/dev/geosector/app/build/web/icons/Icon-maskable-192.png /Users/pierre/dev/geosector/app/build/web/icons/Icon-152.png /Users/pierre/dev/geosector/app/build/web/icons/Icon-180.png /Users/pierre/dev/geosector/app/build/web/icons/Icon-167.png /Users/pierre/dev/geosector/app/build/web/icons/Icon-maskable-512.png /Users/pierre/dev/geosector/app/build/web/icons/Icon-512.png /Users/pierre/dev/geosector/app/build/web/manifest.json /Users/pierre/dev/geosector/app/build/web/favicon-32.png: /Users/pierre/dev/geosector/app/web/index.html /Users/pierre/dev/geosector/app/web/.DS_Store /Users/pierre/dev/geosector/app/web/favicon-64.png /Users/pierre/dev/geosector/app/web/favicon-16.png /Users/pierre/dev/geosector/app/web/favicon.png /Users/pierre/dev/geosector/app/web/icons/Icon-192.png /Users/pierre/dev/geosector/app/web/icons/Icon-maskable-192.png /Users/pierre/dev/geosector/app/web/icons/Icon-152.png /Users/pierre/dev/geosector/app/web/icons/Icon-180.png /Users/pierre/dev/geosector/app/web/icons/Icon-167.png /Users/pierre/dev/geosector/app/web/icons/Icon-maskable-512.png /Users/pierre/dev/geosector/app/web/icons/Icon-512.png /Users/pierre/dev/geosector/app/web/manifest.json /Users/pierre/dev/geosector/app/web/favicon-32.png
|
||||
@@ -1 +0,0 @@
|
||||
{"inputs":["/Users/pierre/dev/geosector/app/build/web/flutter_bootstrap.js","/Users/pierre/dev/geosector/app/build/web/version.json","/Users/pierre/dev/geosector/app/build/web/index.html","/Users/pierre/dev/geosector/app/build/web/favicon-64.png","/Users/pierre/dev/geosector/app/build/web/favicon-16.png","/Users/pierre/dev/geosector/app/build/web/main.dart.js","/Users/pierre/dev/geosector/app/build/web/flutter.js","/Users/pierre/dev/geosector/app/build/web/favicon.png","/Users/pierre/dev/geosector/app/build/web/icons/Icon-192.png","/Users/pierre/dev/geosector/app/build/web/icons/Icon-maskable-192.png","/Users/pierre/dev/geosector/app/build/web/icons/Icon-152.png","/Users/pierre/dev/geosector/app/build/web/icons/Icon-180.png","/Users/pierre/dev/geosector/app/build/web/icons/Icon-167.png","/Users/pierre/dev/geosector/app/build/web/icons/Icon-maskable-512.png","/Users/pierre/dev/geosector/app/build/web/icons/Icon-512.png","/Users/pierre/dev/geosector/app/build/web/manifest.json","/Users/pierre/dev/geosector/app/build/web/favicon-32.png","/Users/pierre/dev/geosector/app/build/web/assets/AssetManifest.json","/Users/pierre/dev/geosector/app/build/web/assets/NOTICES","/Users/pierre/dev/geosector/app/build/web/assets/FontManifest.json","/Users/pierre/dev/geosector/app/build/web/assets/AssetManifest.bin.json","/Users/pierre/dev/geosector/app/build/web/assets/packages/cupertino_icons/assets/CupertinoIcons.ttf","/Users/pierre/dev/geosector/app/build/web/assets/packages/flutter_map/lib/assets/flutter_map_logo.png","/Users/pierre/dev/geosector/app/build/web/assets/shaders/ink_sparkle.frag","/Users/pierre/dev/geosector/app/build/web/assets/AssetManifest.bin","/Users/pierre/dev/geosector/app/build/web/assets/fonts/MaterialIcons-Regular.otf","/Users/pierre/dev/geosector/app/build/web/assets/assets/images/geosector-logo.png","/Users/pierre/dev/geosector/app/build/web/assets/assets/images/logo-geosector-1024.png","/Users/pierre/dev/geosector/app/build/web/assets/assets/images/icon-geosector.svg","/Users/pierre/dev/geosector/app/build/web/assets/assets/images/logo_recu.png","/Users/pierre/dev/geosector/app/build/web/assets/assets/fonts/Figtree-VariableFont_wght.ttf","/Users/pierre/dev/geosector/app/build/web/assets/assets/animations/geo_main.json","/Users/pierre/dev/geosector/app/build/web/canvaskit/skwasm.js","/Users/pierre/dev/geosector/app/build/web/canvaskit/skwasm.js.symbols","/Users/pierre/dev/geosector/app/build/web/canvaskit/canvaskit.js.symbols","/Users/pierre/dev/geosector/app/build/web/canvaskit/skwasm.wasm","/Users/pierre/dev/geosector/app/build/web/canvaskit/chromium/canvaskit.js.symbols","/Users/pierre/dev/geosector/app/build/web/canvaskit/chromium/canvaskit.js","/Users/pierre/dev/geosector/app/build/web/canvaskit/chromium/canvaskit.wasm","/Users/pierre/dev/geosector/app/build/web/canvaskit/canvaskit.js","/Users/pierre/dev/geosector/app/build/web/canvaskit/canvaskit.wasm"],"outputs":["/Users/pierre/dev/geosector/app/build/web/flutter_service_worker.js"]}
|
||||
@@ -1 +0,0 @@
|
||||
{"inputs":["/Users/pierre/dev/flutter/bin/cache/engine.stamp"],"outputs":["/Users/pierre/dev/geosector/app/.dart_tool/flutter_build/01af3ba6904766cfc820f0897fc71456/flutter.js","/Users/pierre/dev/geosector/app/.dart_tool/flutter_build/01af3ba6904766cfc820f0897fc71456/canvaskit/skwasm.js","/Users/pierre/dev/geosector/app/.dart_tool/flutter_build/01af3ba6904766cfc820f0897fc71456/canvaskit/skwasm.js.symbols","/Users/pierre/dev/geosector/app/.dart_tool/flutter_build/01af3ba6904766cfc820f0897fc71456/canvaskit/canvaskit.js.symbols","/Users/pierre/dev/geosector/app/.dart_tool/flutter_build/01af3ba6904766cfc820f0897fc71456/canvaskit/skwasm.wasm","/Users/pierre/dev/geosector/app/.dart_tool/flutter_build/01af3ba6904766cfc820f0897fc71456/canvaskit/chromium/canvaskit.js.symbols","/Users/pierre/dev/geosector/app/.dart_tool/flutter_build/01af3ba6904766cfc820f0897fc71456/canvaskit/chromium/canvaskit.js","/Users/pierre/dev/geosector/app/.dart_tool/flutter_build/01af3ba6904766cfc820f0897fc71456/canvaskit/chromium/canvaskit.wasm","/Users/pierre/dev/geosector/app/.dart_tool/flutter_build/01af3ba6904766cfc820f0897fc71456/canvaskit/canvaskit.js","/Users/pierre/dev/geosector/app/.dart_tool/flutter_build/01af3ba6904766cfc820f0897fc71456/canvaskit/canvaskit.wasm"]}
|
||||
@@ -1 +0,0 @@
|
||||
{"inputs":["/Users/pierre/dev/geosector/app/web/*/index.html","/Users/pierre/dev/geosector/app/web/flutter_bootstrap.js","/Users/pierre/dev/flutter/bin/cache/engine.stamp"],"outputs":["/Users/pierre/dev/geosector/app/build/web/*/index.html","/Users/pierre/dev/geosector/app/build/web/flutter_bootstrap.js"],"buildKey":"[{\"compileTarget\":\"dart2js\",\"renderer\":\"canvaskit\",\"mainJsPath\":\"main.dart.js\"}]"}
|
||||
@@ -0,0 +1 @@
|
||||
["/home/pierre/dev/geosector/app/build/web/*/index.html","/home/pierre/dev/geosector/app/build/web/flutter_bootstrap.js","/home/pierre/dev/geosector/app/build/web/main.dart.js","/home/pierre/dev/geosector/app/build/web/assets/assets/images/logo-geosector-512.png-autosave.kra","/home/pierre/dev/geosector/app/build/web/assets/assets/images/icon-geosector.svg","/home/pierre/dev/geosector/app/build/web/assets/assets/images/geosector_map_admin.png","/home/pierre/dev/geosector/app/build/web/assets/assets/images/logo_recu.png","/home/pierre/dev/geosector/app/build/web/assets/assets/images/logo-geosector-512.png","/home/pierre/dev/geosector/app/build/web/assets/assets/images/geosector-logo.png","/home/pierre/dev/geosector/app/build/web/assets/assets/images/logo-geosector-1024.png","/home/pierre/dev/geosector/app/build/web/assets/assets/animations/geo_main.json","/home/pierre/dev/geosector/app/build/web/assets/assets/fonts/Figtree-VariableFont_wght.ttf","/home/pierre/dev/geosector/app/build/web/assets/packages/cupertino_icons/assets/CupertinoIcons.ttf","/home/pierre/dev/geosector/app/build/web/assets/packages/flutter_map/lib/assets/flutter_map_logo.png","/home/pierre/dev/geosector/app/build/web/assets/fonts/MaterialIcons-Regular.otf","/home/pierre/dev/geosector/app/build/web/assets/shaders/ink_sparkle.frag","/home/pierre/dev/geosector/app/build/web/assets/AssetManifest.json","/home/pierre/dev/geosector/app/build/web/assets/AssetManifest.bin","/home/pierre/dev/geosector/app/build/web/assets/AssetManifest.bin.json","/home/pierre/dev/geosector/app/build/web/assets/FontManifest.json","/home/pierre/dev/geosector/app/build/web/assets/NOTICES","/home/pierre/dev/geosector/app/build/web/icons/Icon-maskable-192.png","/home/pierre/dev/geosector/app/build/web/icons/Icon-192.png","/home/pierre/dev/geosector/app/build/web/icons/Icon-152.png","/home/pierre/dev/geosector/app/build/web/icons/Icon-180.png","/home/pierre/dev/geosector/app/build/web/icons/Icon-167.png","/home/pierre/dev/geosector/app/build/web/icons/Icon-512.png","/home/pierre/dev/geosector/app/build/web/icons/Icon-maskable-512.png","/home/pierre/dev/geosector/app/build/web/favicon-64.png","/home/pierre/dev/geosector/app/build/web/.DS_Store","/home/pierre/dev/geosector/app/build/web/favicon-32.png","/home/pierre/dev/geosector/app/build/web/favicon.png","/home/pierre/dev/geosector/app/build/web/favicon-16.png","/home/pierre/dev/geosector/app/build/web/manifest.json","/home/pierre/dev/geosector/app/build/web/flutter_service_worker.js"]
|
||||
@@ -0,0 +1 @@
|
||||
/home/pierre/dev/geosector/app/build/web/flutter_service_worker.js: /home/pierre/dev/geosector/app/build/web/icons/Icon-maskable-192.png /home/pierre/dev/geosector/app/build/web/icons/Icon-192.png /home/pierre/dev/geosector/app/build/web/icons/Icon-152.png /home/pierre/dev/geosector/app/build/web/icons/Icon-180.png /home/pierre/dev/geosector/app/build/web/icons/Icon-167.png /home/pierre/dev/geosector/app/build/web/icons/Icon-512.png /home/pierre/dev/geosector/app/build/web/icons/Icon-maskable-512.png /home/pierre/dev/geosector/app/build/web/flutter.js /home/pierre/dev/geosector/app/build/web/flutter_bootstrap.js /home/pierre/dev/geosector/app/build/web/favicon-64.png /home/pierre/dev/geosector/app/build/web/index.html /home/pierre/dev/geosector/app/build/web/canvaskit/chromium/canvaskit.wasm /home/pierre/dev/geosector/app/build/web/canvaskit/chromium/canvaskit.js.symbols /home/pierre/dev/geosector/app/build/web/canvaskit/chromium/canvaskit.js /home/pierre/dev/geosector/app/build/web/canvaskit/canvaskit.wasm /home/pierre/dev/geosector/app/build/web/canvaskit/canvaskit.js.symbols /home/pierre/dev/geosector/app/build/web/canvaskit/skwasm.wasm /home/pierre/dev/geosector/app/build/web/canvaskit/canvaskit.js /home/pierre/dev/geosector/app/build/web/canvaskit/skwasm.js.symbols /home/pierre/dev/geosector/app/build/web/canvaskit/skwasm.js /home/pierre/dev/geosector/app/build/web/favicon-32.png /home/pierre/dev/geosector/app/build/web/version.json /home/pierre/dev/geosector/app/build/web/favicon.png /home/pierre/dev/geosector/app/build/web/favicon-16.png /home/pierre/dev/geosector/app/build/web/assets/AssetManifest.json /home/pierre/dev/geosector/app/build/web/assets/AssetManifest.bin /home/pierre/dev/geosector/app/build/web/assets/fonts/MaterialIcons-Regular.otf /home/pierre/dev/geosector/app/build/web/assets/FontManifest.json /home/pierre/dev/geosector/app/build/web/assets/packages/flutter_map/lib/assets/flutter_map_logo.png /home/pierre/dev/geosector/app/build/web/assets/packages/cupertino_icons/assets/CupertinoIcons.ttf /home/pierre/dev/geosector/app/build/web/assets/assets/images/logo-geosector-512.png-autosave.kra /home/pierre/dev/geosector/app/build/web/assets/assets/images/icon-geosector.svg /home/pierre/dev/geosector/app/build/web/assets/assets/images/geosector_map_admin.png /home/pierre/dev/geosector/app/build/web/assets/assets/images/logo_recu.png /home/pierre/dev/geosector/app/build/web/assets/assets/images/logo-geosector-512.png /home/pierre/dev/geosector/app/build/web/assets/assets/images/geosector-logo.png /home/pierre/dev/geosector/app/build/web/assets/assets/images/logo-geosector-1024.png /home/pierre/dev/geosector/app/build/web/assets/assets/fonts/Figtree-VariableFont_wght.ttf /home/pierre/dev/geosector/app/build/web/assets/assets/animations/geo_main.json /home/pierre/dev/geosector/app/build/web/assets/shaders/ink_sparkle.frag /home/pierre/dev/geosector/app/build/web/assets/NOTICES /home/pierre/dev/geosector/app/build/web/assets/AssetManifest.bin.json /home/pierre/dev/geosector/app/build/web/main.dart.js /home/pierre/dev/geosector/app/build/web/manifest.json
|
||||
@@ -0,0 +1 @@
|
||||
{"inputs":["/home/pierre/dev/flutter/packages/flutter_tools/lib/src/build_system/targets/web.dart"],"outputs":["/home/pierre/dev/geosector/app/.dart_tool/flutter_build/d35d2e27406b267ee35b6a1db0e24c05/main.dart"]}
|
||||
@@ -9,6 +9,7 @@
|
||||
import 'package:connectivity_plus/src/connectivity_plus_web.dart';
|
||||
import 'package:geolocator_web/geolocator_web.dart';
|
||||
import 'package:package_info_plus/src/package_info_plus_web.dart';
|
||||
import 'package:shared_preferences_web/shared_preferences_web.dart';
|
||||
import 'package:url_launcher_web/url_launcher_web.dart';
|
||||
import 'package:flutter_web_plugins/flutter_web_plugins.dart';
|
||||
|
||||
@@ -17,6 +18,7 @@ void registerPlugins([final Registrar? pluginRegistrar]) {
|
||||
ConnectivityPlusWebPlugin.registerWith(registrar);
|
||||
GeolocatorPlugin.registerWith(registrar);
|
||||
PackageInfoPlusWebPlugin.registerWith(registrar);
|
||||
SharedPreferencesPlugin.registerWith(registrar);
|
||||
UrlLauncherPlugin.registerWith(registrar);
|
||||
registrar.registerMessageHandler();
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
/home/pierre/dev/geosector/app/build/web/icons/Icon-maskable-192.png /home/pierre/dev/geosector/app/build/web/icons/Icon-192.png /home/pierre/dev/geosector/app/build/web/icons/Icon-152.png /home/pierre/dev/geosector/app/build/web/icons/Icon-180.png /home/pierre/dev/geosector/app/build/web/icons/Icon-167.png /home/pierre/dev/geosector/app/build/web/icons/Icon-512.png /home/pierre/dev/geosector/app/build/web/icons/Icon-maskable-512.png /home/pierre/dev/geosector/app/build/web/favicon-64.png /home/pierre/dev/geosector/app/build/web/.DS_Store /home/pierre/dev/geosector/app/build/web/favicon-32.png /home/pierre/dev/geosector/app/build/web/favicon.png /home/pierre/dev/geosector/app/build/web/favicon-16.png /home/pierre/dev/geosector/app/build/web/manifest.json: /home/pierre/dev/geosector/app/web/icons/Icon-maskable-192.png /home/pierre/dev/geosector/app/web/icons/Icon-192.png /home/pierre/dev/geosector/app/web/icons/Icon-152.png /home/pierre/dev/geosector/app/web/icons/Icon-180.png /home/pierre/dev/geosector/app/web/icons/Icon-167.png /home/pierre/dev/geosector/app/web/icons/Icon-512.png /home/pierre/dev/geosector/app/web/icons/Icon-maskable-512.png /home/pierre/dev/geosector/app/web/favicon-64.png /home/pierre/dev/geosector/app/web/.DS_Store /home/pierre/dev/geosector/app/web/index.html /home/pierre/dev/geosector/app/web/favicon-32.png /home/pierre/dev/geosector/app/web/favicon.png /home/pierre/dev/geosector/app/web/favicon-16.png /home/pierre/dev/geosector/app/web/manifest.json
|
||||
@@ -0,0 +1 @@
|
||||
{"inputs":["/home/pierre/dev/geosector/app/build/web/icons/Icon-maskable-192.png","/home/pierre/dev/geosector/app/build/web/icons/Icon-192.png","/home/pierre/dev/geosector/app/build/web/icons/Icon-152.png","/home/pierre/dev/geosector/app/build/web/icons/Icon-180.png","/home/pierre/dev/geosector/app/build/web/icons/Icon-167.png","/home/pierre/dev/geosector/app/build/web/icons/Icon-512.png","/home/pierre/dev/geosector/app/build/web/icons/Icon-maskable-512.png","/home/pierre/dev/geosector/app/build/web/flutter.js","/home/pierre/dev/geosector/app/build/web/flutter_bootstrap.js","/home/pierre/dev/geosector/app/build/web/favicon-64.png","/home/pierre/dev/geosector/app/build/web/index.html","/home/pierre/dev/geosector/app/build/web/canvaskit/chromium/canvaskit.wasm","/home/pierre/dev/geosector/app/build/web/canvaskit/chromium/canvaskit.js.symbols","/home/pierre/dev/geosector/app/build/web/canvaskit/chromium/canvaskit.js","/home/pierre/dev/geosector/app/build/web/canvaskit/canvaskit.wasm","/home/pierre/dev/geosector/app/build/web/canvaskit/canvaskit.js.symbols","/home/pierre/dev/geosector/app/build/web/canvaskit/skwasm.wasm","/home/pierre/dev/geosector/app/build/web/canvaskit/canvaskit.js","/home/pierre/dev/geosector/app/build/web/canvaskit/skwasm.js.symbols","/home/pierre/dev/geosector/app/build/web/canvaskit/skwasm.js","/home/pierre/dev/geosector/app/build/web/favicon-32.png","/home/pierre/dev/geosector/app/build/web/version.json","/home/pierre/dev/geosector/app/build/web/favicon.png","/home/pierre/dev/geosector/app/build/web/favicon-16.png","/home/pierre/dev/geosector/app/build/web/assets/AssetManifest.json","/home/pierre/dev/geosector/app/build/web/assets/AssetManifest.bin","/home/pierre/dev/geosector/app/build/web/assets/fonts/MaterialIcons-Regular.otf","/home/pierre/dev/geosector/app/build/web/assets/FontManifest.json","/home/pierre/dev/geosector/app/build/web/assets/packages/flutter_map/lib/assets/flutter_map_logo.png","/home/pierre/dev/geosector/app/build/web/assets/packages/cupertino_icons/assets/CupertinoIcons.ttf","/home/pierre/dev/geosector/app/build/web/assets/assets/images/logo-geosector-512.png-autosave.kra","/home/pierre/dev/geosector/app/build/web/assets/assets/images/icon-geosector.svg","/home/pierre/dev/geosector/app/build/web/assets/assets/images/geosector_map_admin.png","/home/pierre/dev/geosector/app/build/web/assets/assets/images/logo_recu.png","/home/pierre/dev/geosector/app/build/web/assets/assets/images/logo-geosector-512.png","/home/pierre/dev/geosector/app/build/web/assets/assets/images/geosector-logo.png","/home/pierre/dev/geosector/app/build/web/assets/assets/images/logo-geosector-1024.png","/home/pierre/dev/geosector/app/build/web/assets/assets/fonts/Figtree-VariableFont_wght.ttf","/home/pierre/dev/geosector/app/build/web/assets/assets/animations/geo_main.json","/home/pierre/dev/geosector/app/build/web/assets/shaders/ink_sparkle.frag","/home/pierre/dev/geosector/app/build/web/assets/NOTICES","/home/pierre/dev/geosector/app/build/web/assets/AssetManifest.bin.json","/home/pierre/dev/geosector/app/build/web/main.dart.js","/home/pierre/dev/geosector/app/build/web/manifest.json"],"outputs":["/home/pierre/dev/geosector/app/build/web/flutter_service_worker.js"]}
|
||||
@@ -0,0 +1 @@
|
||||
{"inputs":["/home/pierre/dev/flutter/bin/cache/engine.stamp"],"outputs":["/home/pierre/dev/geosector/app/.dart_tool/flutter_build/d35d2e27406b267ee35b6a1db0e24c05/flutter.js","/home/pierre/dev/geosector/app/.dart_tool/flutter_build/d35d2e27406b267ee35b6a1db0e24c05/canvaskit/chromium/canvaskit.wasm","/home/pierre/dev/geosector/app/.dart_tool/flutter_build/d35d2e27406b267ee35b6a1db0e24c05/canvaskit/chromium/canvaskit.js.symbols","/home/pierre/dev/geosector/app/.dart_tool/flutter_build/d35d2e27406b267ee35b6a1db0e24c05/canvaskit/chromium/canvaskit.js","/home/pierre/dev/geosector/app/.dart_tool/flutter_build/d35d2e27406b267ee35b6a1db0e24c05/canvaskit/canvaskit.wasm","/home/pierre/dev/geosector/app/.dart_tool/flutter_build/d35d2e27406b267ee35b6a1db0e24c05/canvaskit/canvaskit.js.symbols","/home/pierre/dev/geosector/app/.dart_tool/flutter_build/d35d2e27406b267ee35b6a1db0e24c05/canvaskit/skwasm.wasm","/home/pierre/dev/geosector/app/.dart_tool/flutter_build/d35d2e27406b267ee35b6a1db0e24c05/canvaskit/canvaskit.js","/home/pierre/dev/geosector/app/.dart_tool/flutter_build/d35d2e27406b267ee35b6a1db0e24c05/canvaskit/skwasm.js.symbols","/home/pierre/dev/geosector/app/.dart_tool/flutter_build/d35d2e27406b267ee35b6a1db0e24c05/canvaskit/skwasm.js"]}
|
||||
@@ -0,0 +1 @@
|
||||
{"inputs":["/home/pierre/dev/geosector/app/web/*/index.html","/home/pierre/dev/geosector/app/web/flutter_bootstrap.js","/home/pierre/dev/flutter/bin/cache/engine.stamp"],"outputs":["/home/pierre/dev/geosector/app/build/web/*/index.html","/home/pierre/dev/geosector/app/build/web/flutter_bootstrap.js"],"buildKey":"[{\"compileTarget\":\"dart2js\",\"renderer\":\"canvaskit\",\"mainJsPath\":\"main.dart.js\"}]"}
|
||||
@@ -1 +1 @@
|
||||
3.32.4
|
||||
3.32.8
|
||||
0
app/.env-backup
Normal file → Executable file
8
app/.env-deploy-dev
Normal file → Executable file
@@ -2,7 +2,13 @@
|
||||
HOST_SSH_USER=pierre
|
||||
HOST_SSH_HOST=195.154.80.116
|
||||
HOST_SSH_PORT=22
|
||||
HOST_SSH_KEY=/Users/pierre/.ssh/id_rsa_mbpi
|
||||
if [[ "$OSTYPE" == "darwin"* ]]; then
|
||||
# macOS
|
||||
HOST_SSH_KEY=/Users/pierre/.ssh/id_rsa_mbpi
|
||||
else
|
||||
# Linux/Ubuntu
|
||||
HOST_SSH_KEY=/home/pierre/.ssh/id_rsa_mbpi
|
||||
fi
|
||||
|
||||
# Paramètres du container Incus
|
||||
INCUS_PROJECT=default
|
||||
|
||||
115
app/.vscode/settings.json
vendored
Normal file → Executable file
@@ -1,4 +1,116 @@
|
||||
{
|
||||
"window.zoomLevel": 1, // Permet de zoomer, pratique si vous faites une présentation
|
||||
|
||||
// Apparence
|
||||
// -- Editeur
|
||||
"workbench.startupEditor": "none", // On ne veut pas une page d'accueil chargée
|
||||
"editor.minimap.enabled": true, // On veut voir la minimap
|
||||
"editor.minimap.showSlider": "always", // On veut voir la minimap
|
||||
"editor.minimap.size": "fill", // On veut voir la minimap
|
||||
"editor.minimap.scale": 2,
|
||||
"editor.tokenColorCustomizations": {
|
||||
"textMateRules": [
|
||||
{
|
||||
"scope": ["storage.type.function", "storage.type.class"],
|
||||
"settings": {
|
||||
"fontStyle": "bold",
|
||||
"foreground": "#4B9CD3"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"editor.minimap.renderCharacters": true,
|
||||
"editor.minimap.maxColumn": 120,
|
||||
"breadcrumbs.enabled": false,
|
||||
// -- Tabs
|
||||
"workbench.editor.wrapTabs": true, // On veut voir les tabs
|
||||
"workbench.editor.tabSizing": "shrink", // On veut voir les tabs
|
||||
"workbench.editor.pinnedTabSizing": "compact",
|
||||
"workbench.editor.enablePreview": false, // Un clic sur un fichier l'ouvre
|
||||
|
||||
// -- Sidebar
|
||||
"workbench.tree.indent": 15, // Indente plus pour plus de clarté dans la sidebar
|
||||
"workbench.tree.renderIndentGuides": "always",
|
||||
// -- Code
|
||||
"editor.occurrencesHighlight": "singleFile", // On veut voir les occurences d'une variable
|
||||
"editor.renderWhitespace": "trailing", // On ne veut pas laisser d'espace en fin de ligne
|
||||
"editor.renderControlCharacters": true, // On veut voir les caractères de contrôle
|
||||
// Thème
|
||||
"editor.fontFamily": "'JetBrains Mono', 'Fira Code', 'Operator Mono Lig', monospace",
|
||||
"editor.fontLigatures": false,
|
||||
"editor.fontSize": 13,
|
||||
"editor.lineHeight": 22,
|
||||
"editor.guides.bracketPairs": "active",
|
||||
|
||||
// Ergonomie
|
||||
"editor.wordWrap": "off",
|
||||
"editor.rulers": [],
|
||||
"editor.suggest.insertMode": "replace", // L'autocomplétion remplace le mot en cours
|
||||
"editor.acceptSuggestionOnCommitCharacter": false, // Evite que l'autocomplétion soit accepté lors d'un . par exemple
|
||||
"editor.formatOnSave": true,
|
||||
"editor.formatOnPaste": true,
|
||||
"editor.linkedEditing": true, // Quand on change un élément HTML, change la balise fermante
|
||||
"editor.tabSize": 2,
|
||||
"editor.unicodeHighlight.nonBasicASCII": false,
|
||||
|
||||
"[php]": {
|
||||
"editor.defaultFormatter": "bmewburn.vscode-intelephense-client",
|
||||
"editor.formatOnSave": true,
|
||||
"editor.formatOnPaste": true
|
||||
},
|
||||
"intelephense.format.braces": "k&r",
|
||||
"intelephense.format.enable": true,
|
||||
|
||||
"[javascript]": {
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
||||
"editor.formatOnSave": true,
|
||||
"editor.formatOnPaste": true
|
||||
},
|
||||
"prettier.printWidth": 360,
|
||||
"prettier.semi": true,
|
||||
"prettier.singleQuote": true,
|
||||
"prettier.tabWidth": 2,
|
||||
"prettier.trailingComma": "es5",
|
||||
|
||||
"explorer.autoReveal": false,
|
||||
"explorer.confirmDragAndDrop": false,
|
||||
"emmet.triggerExpansionOnTab": true,
|
||||
"emmet.includeLanguages": {
|
||||
"javascript": "javascriptreact"
|
||||
},
|
||||
"problems.decorations.enabled": true,
|
||||
"explorer.decorations.colors": true,
|
||||
"explorer.decorations.badges": true,
|
||||
"php.validate.enable": true,
|
||||
"php.suggest.basic": false,
|
||||
"dart.analysisExcludedFolders": [],
|
||||
"dart.enableSdkFormatter": true,
|
||||
|
||||
// Fichiers
|
||||
"files.defaultLanguage": "markdown",
|
||||
"files.autoSaveWorkspaceFilesOnly": true,
|
||||
"files.exclude": {
|
||||
"**/.idea": true
|
||||
},
|
||||
// Languages
|
||||
"javascript.preferences.importModuleSpecifierEnding": "js",
|
||||
"typescript.preferences.importModuleSpecifierEnding": "js",
|
||||
|
||||
// Extensions
|
||||
"tailwindCSS.experimental.configFile": "web/tailwind.config.js",
|
||||
"editor.quickSuggestions": {
|
||||
"strings": true
|
||||
},
|
||||
|
||||
"[svelte]": {
|
||||
"editor.defaultFormatter": "svelte.svelte-vscode",
|
||||
"editor.formatOnSave": true
|
||||
},
|
||||
"prettier.documentSelectors": ["**/*.svelte"],
|
||||
"svelte.plugin.svelte.diagnostics.enable": false,
|
||||
|
||||
"js/ts.implicitProjectConfig.checkJs": false,
|
||||
"svelte.enable-ts-plugin": false,
|
||||
"workbench.colorCustomizations": {
|
||||
"activityBar.activeBackground": "#2f7c47",
|
||||
"activityBar.background": "#2f7c47",
|
||||
@@ -18,5 +130,6 @@
|
||||
"titleBar.inactiveBackground": "#21573299",
|
||||
"titleBar.inactiveForeground": "#e7e7e799"
|
||||
},
|
||||
"peacock.color": "#215732"
|
||||
"peacock.color": "#215732",
|
||||
|
||||
}
|
||||
|
||||
0
app/.windsurfrules
Normal file → Executable file
391
app/CLAUDE.md
Executable file
@@ -0,0 +1,391 @@
|
||||
# CLAUDE.md
|
||||
|
||||
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
||||
|
||||
## Instructions générales pour Claude
|
||||
|
||||
### Langue de communication
|
||||
- **TOUJOURS répondre en français** sauf si explicitement demandé autrement
|
||||
- Utiliser un langage technique approprié en français
|
||||
|
||||
### Méthodologie de travail
|
||||
- **Travailler par étapes** : Ne jamais se lancer directement dans la modification du code
|
||||
- **Présenter et proposer** : Toujours expliquer ce que je compte faire AVANT de le faire
|
||||
- **Demander validation** : Attendre l'accord de l'utilisateur avant de procéder aux modifications
|
||||
- **Structure de réponse** :
|
||||
1. Analyser la demande
|
||||
2. Proposer une solution détaillée
|
||||
3. Lister les fichiers qui seront modifiés
|
||||
4. Attendre la validation
|
||||
5. Implémenter les changements
|
||||
|
||||
## Build Commands
|
||||
- **Run app**: `flutter run` - start the Flutter app in debug mode
|
||||
- **Build for release**: `flutter build apk` (Android), `flutter build ios` (iOS), `flutter build web` (Web)
|
||||
- **Run tests**: `flutter test` - run all unit tests
|
||||
- **Run specific test**: `flutter test test/widget_test.dart` - run a specific test file
|
||||
- **Analyze code**: `flutter analyze` - check for errors, warnings, and lints
|
||||
- **Format code**: `flutter format lib/` - format all Dart files
|
||||
- **Generate code**: `flutter packages pub run build_runner build` - generate Hive adapters and JSON serialization
|
||||
- **Clean build**: `flutter clean && flutter pub get` - clean and reinstall dependencies
|
||||
- **Update dependencies**: `flutter pub upgrade` - update all packages
|
||||
- **Launcher icons**: `flutter pub run flutter_launcher_icons:main` - generate app icons
|
||||
|
||||
## Code Architecture
|
||||
|
||||
### Core Architecture Pattern
|
||||
The app follows a **Repository Pattern** with singleton services and reactive UI updates:
|
||||
|
||||
```
|
||||
UI Layer (ValueListenableBuilder)
|
||||
↓
|
||||
Repository Layer (Business Logic)
|
||||
↓
|
||||
Service Layer (API + Hive Storage)
|
||||
```
|
||||
|
||||
### Key Architectural Components
|
||||
|
||||
#### **Singleton Services** (lib/core/services/)
|
||||
- `ApiService` - HTTP client with environment auto-detection (DEV/REC/PROD)
|
||||
- `HiveService` - Local database management with typed Box handling
|
||||
- `CurrentUserService` - User session and authentication state
|
||||
- `CurrentAmicaleService` - Current organization context
|
||||
- `DataLoadingService` - Orchestrates API data synchronization to Hive
|
||||
|
||||
#### **Repository Pattern** (lib/core/repositories/)
|
||||
- `UserRepository` - User management and authentication
|
||||
- `OperationRepository` - Operations and campaigns
|
||||
- `MembreRepository` - Team member management
|
||||
- `PassageRepository` - Distribution tracking
|
||||
- `SectorRepository` - Geographic sectors
|
||||
- `AmicaleRepository` - Organization management
|
||||
|
||||
#### **Reactive UI Pattern**
|
||||
Uses `ValueListenableBuilder` with Hive boxes for automatic UI updates:
|
||||
```dart
|
||||
ValueListenableBuilder<Box<UserModel>>(
|
||||
valueListenable: userRepository.getUsersBox().listenable(),
|
||||
builder: (context, box, child) {
|
||||
// UI automatically updates when data changes
|
||||
},
|
||||
)
|
||||
```
|
||||
|
||||
### Data Flow Architecture
|
||||
|
||||
#### **"API First" Principle**
|
||||
1. UI action triggers repository method
|
||||
2. Repository attempts API call first
|
||||
3. On success → Save to Hive → UI auto-updates via ValueListenableBuilder
|
||||
4. On error → Show error message, no local changes
|
||||
|
||||
#### **Hive Storage Strategy**
|
||||
- **TypeId Management**: Models use specific typeIds (UserModel: 0, OperationModel: 1, etc.)
|
||||
- **Typed Boxes**: Each model has its own strongly-typed Hive box
|
||||
- **Auto-sync**: Data automatically syncs between API and local storage
|
||||
- **Offline-ready**: App functions with cached data when offline
|
||||
- **Box Caching Optimization**: Repositories use cached Box references to prevent repeated access checks
|
||||
|
||||
### Error Handling Architecture
|
||||
|
||||
#### **Centralized Error Management**
|
||||
- `ApiException` class extracts meaningful error messages from API responses
|
||||
- `showError()` and `showSuccess()` methods provide consistent user feedback
|
||||
- Repository methods propagate exceptions to UI layer for handling
|
||||
|
||||
#### **Error Flow Pattern**
|
||||
```dart
|
||||
try {
|
||||
final result = await repository.updateUser(user);
|
||||
ApiException.showSuccess(context, "User updated successfully");
|
||||
} catch (e) {
|
||||
ApiException.showError(context, e); // Handles all error types
|
||||
}
|
||||
```
|
||||
|
||||
#### **Smart Dialog Detection**
|
||||
ApiException automatically detects when called from within a Dialog and adjusts message positioning:
|
||||
|
||||
- **Normal context**: Uses standard SnackBar
|
||||
- **Dialog context**: Uses overlay SnackBar positioned above the Dialog
|
||||
- **Mobile/Web aware**: Automatically adapts presentation for each platform
|
||||
- **Consistent styling**: Unified colors, icons, and behavior across all contexts
|
||||
|
||||
```dart
|
||||
// Same API works everywhere - smart context detection
|
||||
if (validationFails) {
|
||||
ApiException.showError(context, Exception("Validation failed"));
|
||||
return; // Dialog stays open for corrections
|
||||
}
|
||||
|
||||
// Success handling with auto-close
|
||||
if (success) {
|
||||
Navigator.pop(context); // Close dialog first
|
||||
ApiException.showSuccess(context, "Operation completed");
|
||||
}
|
||||
```
|
||||
|
||||
### State Management Strategy
|
||||
|
||||
#### **No Provider/Bloc** - Direct Reactive Pattern
|
||||
- Uses `ValueListenableBuilder` directly with Hive boxes
|
||||
- Singleton services maintain global state
|
||||
- `ChangeNotifier` only for specific repository loading states
|
||||
|
||||
#### **Dialog Auto-Management Pattern**
|
||||
Dialogs handle their own submission and closing:
|
||||
```dart
|
||||
// Dialog manages its own lifecycle
|
||||
void _handleSubmit() async {
|
||||
try {
|
||||
await repository.saveData(data);
|
||||
Navigator.pop(context); // Auto-close on success
|
||||
widget.onSuccess?.call(); // Simple callback
|
||||
} catch (e) {
|
||||
ApiException.showError(context, e); // Error without closing
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Multi-Role Permission System
|
||||
|
||||
#### **Role Hierarchy**
|
||||
- **Role 1** (Membre): Field operations, distribution tracking
|
||||
- **Role 2** (Admin Amicale): Organization management, member administration
|
||||
- **Role 3+** (Super Admin): Global system administration
|
||||
|
||||
#### **Permission Checks**
|
||||
```dart
|
||||
final currentUser = CurrentUserService.instance;
|
||||
if (currentUser.canAccessAdmin) {
|
||||
// Show admin features
|
||||
}
|
||||
if (currentUser.isSuperAdmin) {
|
||||
// Show super admin features
|
||||
}
|
||||
```
|
||||
|
||||
### Code Generation Requirements
|
||||
|
||||
#### **Hive Adapters**
|
||||
Models require code generation for Hive serialization:
|
||||
```bash
|
||||
flutter packages pub run build_runner build
|
||||
```
|
||||
|
||||
Run this after modifying any `@HiveType` models in `lib/core/data/models/`.
|
||||
|
||||
#### **Model Structure**
|
||||
```dart
|
||||
@HiveType(typeId: X)
|
||||
class MyModel extends HiveObject {
|
||||
@HiveField(0)
|
||||
final int id;
|
||||
|
||||
@HiveField(1)
|
||||
final String name;
|
||||
}
|
||||
```
|
||||
|
||||
### Development Workflow
|
||||
|
||||
#### **Working with Repositories**
|
||||
1. Always inject repositories via constructor or global instances from `app.dart`
|
||||
2. Use `try/catch` blocks for all repository calls
|
||||
3. Show loading states during async operations
|
||||
4. Handle errors with `ApiException.showError()`
|
||||
5. Implement Hive box caching to avoid repeated access checks during high-frequency operations
|
||||
|
||||
#### **Adding New Features**
|
||||
1. Create/modify models in `lib/core/data/models/`
|
||||
2. Run `build_runner` to generate Hive adapters
|
||||
3. Add repository methods in `lib/core/repositories/`
|
||||
4. Create UI widgets in `lib/presentation/widgets/`
|
||||
5. Wire up with `ValueListenableBuilder` for reactivity
|
||||
|
||||
#### **Testing Strategy**
|
||||
- Unit tests for repositories and services
|
||||
- Widget tests for UI components
|
||||
- Integration tests for complete user flows
|
||||
- Use `flutter test` for running tests
|
||||
|
||||
### Environment Configuration
|
||||
|
||||
#### **Auto-Detection**
|
||||
The app automatically detects environment based on URL:
|
||||
- `dapp.geosector.fr` → DEV environment
|
||||
- `rapp.geosector.fr` → REC environment
|
||||
- Production → PROD environment
|
||||
- Non-web platforms → DEV by default
|
||||
|
||||
#### **API Configuration**
|
||||
Environment-specific API endpoints are configured in `ApiService` automatically.
|
||||
|
||||
### Common Patterns to Follow
|
||||
|
||||
#### **Repository Method Pattern**
|
||||
```dart
|
||||
Future<bool> updateUser(UserModel user) async {
|
||||
try {
|
||||
final response = await ApiService.instance.put('/users/${user.id}', user.toJson());
|
||||
final updatedUser = UserModel.fromJson(response.data);
|
||||
await _saveUserToHive(updatedUser);
|
||||
return true;
|
||||
} catch (e) {
|
||||
throw ApiException.fromDioException(e);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### **Hive Box Caching Pattern**
|
||||
```dart
|
||||
class MyRepository {
|
||||
// Cache de la box pour éviter les vérifications répétées
|
||||
Box<MyModel>? _cachedBox;
|
||||
|
||||
// Getter lazy pour n'accéder à la boîte que lorsque nécessaire
|
||||
Box<MyModel> get _myBox {
|
||||
if (_cachedBox == null) {
|
||||
if (!Hive.isBoxOpen(AppKeys.myBoxName)) {
|
||||
throw Exception('La boîte n\'est pas ouverte');
|
||||
}
|
||||
_cachedBox = Hive.box<MyModel>(AppKeys.myBoxName);
|
||||
}
|
||||
return _cachedBox!;
|
||||
}
|
||||
|
||||
// Méthode pour réinitialiser le cache après modification
|
||||
void _resetCache() {
|
||||
_cachedBox = null;
|
||||
}
|
||||
|
||||
// Sauvegarder avec réinitialisation du cache
|
||||
Future<void> saveItem(MyModel item) async {
|
||||
await _myBox.put(item.id, item);
|
||||
_resetCache(); // Crucial pour ValueListenableBuilder
|
||||
notifyListeners();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### **Widget Error Handling**
|
||||
```dart
|
||||
Future<void> _handleSave() async {
|
||||
try {
|
||||
setState(() => _isLoading = true);
|
||||
await repository.saveData(data);
|
||||
ApiException.showSuccess(context, "Saved successfully");
|
||||
} catch (e) {
|
||||
ApiException.showError(context, e);
|
||||
} finally {
|
||||
setState(() => _isLoading = false);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### **ValueListenableBuilder Usage**
|
||||
```dart
|
||||
ValueListenableBuilder<Box<ModelType>>(
|
||||
valueListenable: repository.getBox().listenable(),
|
||||
builder: (context, box, child) {
|
||||
final items = box.values.where((item) => filterCondition).toList();
|
||||
return ListView.builder(
|
||||
itemCount: items.length,
|
||||
itemBuilder: (context, index) => ItemWidget(item: items[index]),
|
||||
);
|
||||
},
|
||||
)
|
||||
```
|
||||
|
||||
### Hive Box Performance Management
|
||||
|
||||
#### **Box Caching Strategy**
|
||||
|
||||
Repositories implement a caching pattern to optimize Hive box access and prevent performance issues during high-frequency operations:
|
||||
|
||||
**Problems Solved:**
|
||||
- Eliminates repeated `Hive.isBoxOpen()` checks (up to 848 checks per page load)
|
||||
- Improves performance during list rendering and filtering operations
|
||||
- Maintains thread-safe access to Hive boxes
|
||||
|
||||
**Implementation Pattern:**
|
||||
```dart
|
||||
class ExampleRepository {
|
||||
// Private cached box reference
|
||||
Box<ExampleModel>? _cachedBox;
|
||||
|
||||
// Lazy getter with caching
|
||||
Box<ExampleModel> get _exampleBox {
|
||||
if (_cachedBox == null) {
|
||||
if (!Hive.isBoxOpen(AppKeys.exampleBoxName)) {
|
||||
throw Exception('Box not open: ${AppKeys.exampleBoxName}');
|
||||
}
|
||||
_cachedBox = Hive.box<ExampleModel>(AppKeys.exampleBoxName);
|
||||
debugPrint('Repository: Box ${AppKeys.exampleBoxName} cached');
|
||||
}
|
||||
return _cachedBox!;
|
||||
}
|
||||
|
||||
// Cache reset for ValueListenableBuilder notifications
|
||||
void _resetCache() {
|
||||
_cachedBox = null;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### **When to Reset Cache**
|
||||
|
||||
Cache reset is **essential** after any database modification to ensure ValueListenableBuilder and other Hive listeners detect changes:
|
||||
|
||||
```dart
|
||||
// REQUIRED: After individual saves
|
||||
Future<void> saveItem(ExampleModel item) async {
|
||||
await _exampleBox.put(item.id, item);
|
||||
_resetCache(); // ← Essential for UI reactivity
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
// REQUIRED: After deletions
|
||||
Future<void> deleteItem(int id) async {
|
||||
await _exampleBox.delete(id);
|
||||
_resetCache(); // ← Essential for UI reactivity
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
// REQUIRED: After bulk operations
|
||||
Future<void> clearAll() async {
|
||||
await _exampleBox.clear();
|
||||
_resetCache(); // ← Essential for UI reactivity
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
// REQUIRED: After API data processing
|
||||
Future<void> processApiData(List<dynamic> data) async {
|
||||
await _exampleBox.clear();
|
||||
for (final item in data) {
|
||||
await _exampleBox.put(item.id, ExampleModel.fromJson(item));
|
||||
}
|
||||
_resetCache(); // ← Essential for UI reactivity
|
||||
notifyListeners();
|
||||
}
|
||||
```
|
||||
|
||||
#### **Performance Impact**
|
||||
|
||||
| Scenario | Without Caching | With Caching |
|
||||
|----------|-----------------|--------------|
|
||||
| Loading 848 passages | 848 box checks | 1 box access |
|
||||
| List filtering | Check per item | Cached access |
|
||||
| ValueListenableBuilder | Repeated verification | Optimized access |
|
||||
| Memory usage | Minimal overhead | Negligible cache |
|
||||
|
||||
#### **Best Practices**
|
||||
|
||||
1. **Always cache** in repositories that handle frequently accessed data
|
||||
2. **Always reset cache** after any modification operation
|
||||
3. **Use lazy getters** to avoid unnecessary box access
|
||||
4. **Include debug prints** to monitor caching behavior during development
|
||||
5. **Apply pattern consistently** across all repositories for maintainability
|
||||
|
||||
This architecture ensures type safety, reactivity, offline capability, and maintainable code structure across the entire application.
|
||||
0
app/PLAN2-APP.md
Normal file → Executable file
160
app/README-APP.md
Normal file → Executable file
@@ -70,7 +70,7 @@ GEOSECTOR est une solution complète développée en Flutter qui révolutionne l
|
||||
|
||||
- **🗺️ Cartographie avancée** : Flutter Map avec tuiles Mapbox
|
||||
- **📍 Géolocalisation précise** : Suivi GPS des équipes
|
||||
- **💾 Stockage hybride** : Cache local Hive + synchronisation cloud
|
||||
- **💾 Stockage hybride** : Cache local Hive + synchronisation cloud avec optimisation des performances
|
||||
- **💬 Communication** : Chat MQTT en temps réel
|
||||
- **🔐 Sécurité** : Authentification JWT + gestion fine des permissions
|
||||
- **📱 Multi-plateforme** : iOS, Android, Web
|
||||
@@ -233,10 +233,32 @@ AudienceTargetModelAdapter() // typeId: 24
|
||||
NotificationSettingsAdapter() // typeId: 25
|
||||
```
|
||||
|
||||
Compatibilité entre modèles
|
||||
UserModel ↔ MembreModel : Conversion bidirectionnelle via toUserModel() et fromUserModel()
|
||||
Synchronisation : Maintien de la cohérence entre les deux représentations
|
||||
Champs spécialisés : Préservation des données spécifiques à chaque modèle
|
||||
### Clarification importante : UserModel vs MembreModel vs UserSectorModel
|
||||
|
||||
⚠️ **ATTENTION** : Il existe une distinction cruciale entre ces trois modèles :
|
||||
|
||||
#### **UserModel** (Box: `users`)
|
||||
- Représente **uniquement l'utilisateur courant connecté** (current user)
|
||||
- Stocké dans la box Hive `users` qui ne contient qu'un seul enregistrement
|
||||
- Utilisé pour l'authentification et la session de l'utilisateur actuel
|
||||
- **Ne pas confondre avec les membres de l'amicale**
|
||||
|
||||
#### **MembreModel** (Box: `membres`)
|
||||
- Représente **tous les membres d'une amicale**
|
||||
- Stocké dans la box Hive `membres` qui contient plusieurs enregistrements
|
||||
- Utilisé pour la gestion des équipes et l'attribution aux secteurs
|
||||
- Chaque membre a son propre ID unique
|
||||
|
||||
#### **UserSectorModel** (Box: `user_sector`)
|
||||
- Représente **l'association entre un membre et un secteur**
|
||||
- ⚠️ **IMPORTANT** : Le champ `id` dans `UserSectorModel` correspond à l'ID du **membre** (MembreModel.id), **PAS** à l'ID de l'utilisateur (UserModel.id)
|
||||
- Permet de savoir quels membres sont affectés à quels secteurs
|
||||
- Nom trompeur : devrait s'appeler "MemberSectorModel" pour éviter la confusion
|
||||
|
||||
### Compatibilité entre modèles
|
||||
- **UserModel ↔ MembreModel** : Conversion bidirectionnelle via `toUserModel()` et `fromUserModel()`
|
||||
- **Synchronisation** : Maintien de la cohérence entre les deux représentations
|
||||
- **Champs spécialisés** : Préservation des données spécifiques à chaque modèle
|
||||
🎨 Interface utilisateur
|
||||
Architecture des composants
|
||||
UserFormDialog - Modale unifiée
|
||||
@@ -286,7 +308,44 @@ UX claire : Feedback immédiat sur les erreurs de validation
|
||||
|
||||
## ⚠️ Gestion des erreurs
|
||||
|
||||
Architecture centralisée
|
||||
### 🎯 Système ApiException intelligent
|
||||
|
||||
GEOSECTOR v2.0 utilise un **système centralisé de gestion des messages** qui s'adapte automatiquement au contexte d'affichage pour garantir une visibilité optimale des notifications utilisateur.
|
||||
|
||||
#### **🧠 Détection automatique de contexte**
|
||||
|
||||
L'`ApiException` détecte intelligemment si elle est appelée depuis une Dialog et adapte l'affichage :
|
||||
|
||||
- **📱 Contexte normal** : SnackBar standard en bas d'écran
|
||||
- **💬 Contexte Dialog** : Overlay SnackBar positionné au-dessus de la Dialog estompée
|
||||
- **🌐 Mobile/Web** : Adaptation automatique selon la plateforme
|
||||
- **🎨 Cohérence visuelle** : Couleurs, icônes et comportements unifiés
|
||||
|
||||
```dart
|
||||
// Même API partout - détection intelligente du contexte
|
||||
void _handleValidation() {
|
||||
if (formInvalid) {
|
||||
// Dans une Dialog : overlay au-dessus, Dialog reste ouverte
|
||||
ApiException.showError(context, Exception("Champs requis manquants"));
|
||||
return;
|
||||
}
|
||||
|
||||
// Succès : fermer Dialog puis afficher confirmation
|
||||
Navigator.pop(context);
|
||||
ApiException.showSuccess(context, "Données sauvegardées");
|
||||
}
|
||||
```
|
||||
|
||||
#### **✨ Avantages de l'approche unifiée**
|
||||
|
||||
| Aspect | Avant | Avec ApiException |
|
||||
|--------|-------|-------------------|
|
||||
| **Visibilité** | SnackBar masqué par Dialog | Overlay visible au-dessus |
|
||||
| **Consistance** | Messages dispersés | API unifiée dans toute l'app |
|
||||
| **Maintenance** | Code répétitif | Système centralisé |
|
||||
| **UX** | Frustrant (messages cachés) | Fluide et prévisible |
|
||||
|
||||
### Architecture centralisée
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
@@ -642,6 +701,95 @@ CurrentAmicaleService : Amicale de l'utilisateur actuel
|
||||
ApiService : Communication centralisée avec l'API
|
||||
DataLoadingService : Orchestration du chargement des données
|
||||
|
||||
## 🚀 Optimisation des performances Hive
|
||||
|
||||
### 📈 Gestion des Box Hive avec cache
|
||||
|
||||
GEOSECTOR v2.0 implémente une **stratégie de cache avancée** pour les Box Hive afin d'éliminer les goulots d'étranglement de performance lors d'opérations haute fréquence.
|
||||
|
||||
#### **🎯 Problème résolu**
|
||||
|
||||
Avant l'optimisation, l'application effectuait jusqu'à **848 vérifications** `Hive.isBoxOpen()` par chargement de page, causant des ralentissements significatifs lors du rendu des listes et du filtrage des données.
|
||||
|
||||
#### **💡 Solution : Cache lazy des Box**
|
||||
|
||||
```dart
|
||||
// Pattern implémenté dans tous les repositories
|
||||
class OptimizedRepository {
|
||||
Box<ModelType>? _cachedBox;
|
||||
|
||||
Box<ModelType> get _modelBox {
|
||||
if (_cachedBox == null) {
|
||||
if (!Hive.isBoxOpen(AppKeys.boxName)) {
|
||||
throw Exception('Box non ouverte');
|
||||
}
|
||||
_cachedBox = Hive.box<ModelType>(AppKeys.boxName);
|
||||
debugPrint('Repository: Box mise en cache');
|
||||
}
|
||||
return _cachedBox!;
|
||||
}
|
||||
|
||||
void _resetCache() {
|
||||
_cachedBox = null;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### **🔄 Gestion du cache et réactivité**
|
||||
|
||||
**Point critique** : Le cache doit être réinitialisé après **toute modification** pour garantir le bon fonctionnement de `ValueListenableBuilder` :
|
||||
|
||||
```dart
|
||||
// ✅ OBLIGATOIRE après modification
|
||||
Future<void> saveData(ModelType data) async {
|
||||
await _modelBox.put(data.id, data);
|
||||
_resetCache(); // ← Crucial pour la réactivité UI
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
// ✅ OBLIGATOIRE après suppression
|
||||
Future<void> deleteData(int id) async {
|
||||
await _modelBox.delete(id);
|
||||
_resetCache(); // ← Crucial pour la réactivité UI
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
// ✅ OBLIGATOIRE après vidage ou traitement API
|
||||
Future<void> processApiData(List<dynamic> data) async {
|
||||
await _modelBox.clear();
|
||||
// ... traitement des données
|
||||
_resetCache(); // ← Crucial pour la réactivité UI
|
||||
notifyListeners();
|
||||
}
|
||||
```
|
||||
|
||||
#### **📊 Impact performance**
|
||||
|
||||
| Métrique | Avant optimisation | Après optimisation |
|
||||
|----------|-------------------|-------------------|
|
||||
| **Vérifications box** | 848 par page | 1 par session |
|
||||
| **Temps de rendu** | 200-500ms | <50ms |
|
||||
| **Filtrage liste** | Lent (check répétés) | Instantané |
|
||||
| **Mémoire** | Overhead minimal | Impact négligeable |
|
||||
|
||||
#### **🏗️ Repositories optimisés**
|
||||
|
||||
L'optimisation est implémentée dans tous les repositories critiques :
|
||||
|
||||
- ✅ **SectorRepository** : Gestion des secteurs géographiques
|
||||
- ✅ **PassageRepository** : Suivi des distributions
|
||||
- ✅ **MembreRepository** : Gestion des équipes
|
||||
- ✅ **OperationRepository** : Campagnes et opérations
|
||||
- ✅ **AmicaleRepository** : Organisations
|
||||
|
||||
#### **🎯 Règles d'implémentation**
|
||||
|
||||
1. **Cache systématique** : Tous les repositories fréquemment utilisés
|
||||
2. **Reset obligatoire** : Après toute opération de modification
|
||||
3. **Getter lazy** : Accès différé à la box uniquement si nécessaire
|
||||
4. **Debug logging** : Traçabilité du cache en développement
|
||||
5. **Cohérence** : Pattern appliqué uniformément
|
||||
|
||||
Cette architecture garantit une application performante, maintenable et évolutive avec une excellente expérience utilisateur. 🚀
|
||||
|
||||
## 🎨 Architecture des Dialogs Auto-Gérées
|
||||
|
||||
0
app/README-icons.md
Normal file → Executable file
16
app/README.md
Normal file
@@ -0,0 +1,16 @@
|
||||
# geosector_app
|
||||
|
||||
A new Flutter project.
|
||||
|
||||
## Getting Started
|
||||
|
||||
This project is a starting point for a Flutter application.
|
||||
|
||||
A few resources to get you started if this is your first Flutter project:
|
||||
|
||||
- [Lab: Write your first Flutter app](https://docs.flutter.dev/get-started/codelab)
|
||||
- [Cookbook: Useful Flutter samples](https://docs.flutter.dev/cookbook)
|
||||
|
||||
For help getting started with Flutter development, view the
|
||||
[online documentation](https://docs.flutter.dev/), which offers tutorials,
|
||||
samples, guidance on mobile development, and a full API reference.
|
||||
0
app/add_framework_paths.rb
Normal file → Executable file
0
app/analysis_options.yaml
Normal file → Executable file
42
app/android/app/build.gradle.kts
Normal file → Executable file
@@ -1,3 +1,6 @@
|
||||
import java.util.Properties
|
||||
import java.io.FileInputStream
|
||||
|
||||
plugins {
|
||||
id("com.android.application")
|
||||
id("kotlin-android")
|
||||
@@ -5,12 +8,20 @@ plugins {
|
||||
id("dev.flutter.flutter-gradle-plugin")
|
||||
}
|
||||
|
||||
// Charger les propriétés de signature
|
||||
val keystorePropertiesFile = rootProject.file("key.properties")
|
||||
val keystoreProperties = Properties()
|
||||
if (keystorePropertiesFile.exists()) {
|
||||
keystoreProperties.load(FileInputStream(keystorePropertiesFile))
|
||||
}
|
||||
|
||||
android {
|
||||
namespace = "fr.geosector.app.geosector_app"
|
||||
namespace = "fr.geosector.app2025"
|
||||
compileSdk = flutter.compileSdkVersion
|
||||
ndkVersion = flutter.ndkVersion
|
||||
ndkVersion = "27.0.12077973"
|
||||
|
||||
compileOptions {
|
||||
isCoreLibraryDesugaringEnabled = true
|
||||
sourceCompatibility = JavaVersion.VERSION_11
|
||||
targetCompatibility = JavaVersion.VERSION_11
|
||||
}
|
||||
@@ -20,8 +31,8 @@ android {
|
||||
}
|
||||
|
||||
defaultConfig {
|
||||
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
|
||||
applicationId = "fr.geosector.app.geosector_app"
|
||||
// Application ID for Google Play Store
|
||||
applicationId = "fr.geosector.app2025"
|
||||
// You can update the following values to match your application needs.
|
||||
// For more information, see: https://flutter.dev/to/review-gradle-config.
|
||||
minSdk = flutter.minSdkVersion
|
||||
@@ -30,11 +41,24 @@ android {
|
||||
versionName = flutter.versionName
|
||||
}
|
||||
|
||||
signingConfigs {
|
||||
if (keystorePropertiesFile.exists()) {
|
||||
create("release") {
|
||||
keyAlias = keystoreProperties["keyAlias"] as String
|
||||
keyPassword = keystoreProperties["keyPassword"] as String
|
||||
storeFile = file(keystoreProperties["storeFile"] as String)
|
||||
storePassword = keystoreProperties["storePassword"] as String
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
release {
|
||||
// TODO: Add your own signing config for the release build.
|
||||
// Signing with the debug keys for now, so `flutter run --release` works.
|
||||
signingConfig = signingConfigs.getByName("debug")
|
||||
if (keystorePropertiesFile.exists()) {
|
||||
signingConfig = signingConfigs.getByName("release")
|
||||
} else {
|
||||
signingConfig = signingConfigs.getByName("debug")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -42,3 +66,7 @@ android {
|
||||
flutter {
|
||||
source = "../.."
|
||||
}
|
||||
|
||||
dependencies {
|
||||
coreLibraryDesugaring("com.android.tools:desugar_jdk_libs:2.1.4")
|
||||
}
|
||||
|
||||
0
app/android/app/src/debug/AndroidManifest.xml
Normal file → Executable file
0
app/android/app/src/main/AndroidManifest.xml
Normal file → Executable file
0
app/android/app/src/main/kotlin/fr/geosector/app2/geosector_app/MainActivity.kt
Normal file → Executable file
@@ -0,0 +1,5 @@
|
||||
package fr.geosector.app2025
|
||||
|
||||
import io.flutter.embedding.android.FlutterActivity
|
||||
|
||||
class MainActivity : FlutterActivity()
|
||||
0
app/android/app/src/main/res/drawable-v21/launch_background.xml
Normal file → Executable file
0
app/android/app/src/main/res/drawable/launch_background.xml
Normal file → Executable file
0
app/android/app/src/main/res/mipmap-hdpi/ic_launcher.png
Normal file → Executable file
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
0
app/android/app/src/main/res/mipmap-hdpi/ic_launcher_background.png
Normal file → Executable file
|
Before Width: | Height: | Size: 303 B After Width: | Height: | Size: 303 B |
0
app/android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png
Normal file → Executable file
|
Before Width: | Height: | Size: 8.0 KiB After Width: | Height: | Size: 8.0 KiB |
0
app/android/app/src/main/res/mipmap-hdpi/launcher_icon.png
Normal file → Executable file
|
Before Width: | Height: | Size: 5.5 KiB After Width: | Height: | Size: 5.5 KiB |
0
app/android/app/src/main/res/mipmap-mdpi/ic_launcher.png
Normal file → Executable file
|
Before Width: | Height: | Size: 6.7 KiB After Width: | Height: | Size: 6.7 KiB |
0
app/android/app/src/main/res/mipmap-mdpi/ic_launcher_background.png
Normal file → Executable file
|
Before Width: | Height: | Size: 300 B After Width: | Height: | Size: 300 B |
0
app/android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png
Normal file → Executable file
|
Before Width: | Height: | Size: 4.9 KiB After Width: | Height: | Size: 4.9 KiB |
0
app/android/app/src/main/res/mipmap-mdpi/launcher_icon.png
Normal file → Executable file
|
Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 3.1 KiB |
0
app/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
Normal file → Executable file
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB |
0
app/android/app/src/main/res/mipmap-xhdpi/ic_launcher_background.png
Normal file → Executable file
|
Before Width: | Height: | Size: 306 B After Width: | Height: | Size: 306 B |
0
app/android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png
Normal file → Executable file
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
0
app/android/app/src/main/res/mipmap-xhdpi/launcher_icon.png
Normal file → Executable file
|
Before Width: | Height: | Size: 8.4 KiB After Width: | Height: | Size: 8.4 KiB |
0
app/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
Normal file → Executable file
|
Before Width: | Height: | Size: 23 KiB After Width: | Height: | Size: 23 KiB |
0
app/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_background.png
Normal file → Executable file
|
Before Width: | Height: | Size: 318 B After Width: | Height: | Size: 318 B |