mirror of
https://github.com/FoggedLens/deflock-app.git
synced 2026-02-12 16:52:51 +00:00
Merge pull request #10 from stopflock/camera-edits
Everything but camera edits
This commit is contained in:
7
.gitignore
vendored
7
.gitignore
vendored
@@ -80,3 +80,10 @@ Thumbs.db
|
||||
*.keystore
|
||||
.env
|
||||
|
||||
# ───────────────────────────────
|
||||
# For now - not targeting these
|
||||
# ───────────────────────────────
|
||||
linux/
|
||||
macos/
|
||||
web/
|
||||
windows/
|
||||
@@ -72,7 +72,7 @@ class AppState extends ChangeNotifier {
|
||||
}
|
||||
|
||||
// Upload mode: production, sandbox, or simulate (in-memory, no uploads)
|
||||
UploadMode _uploadMode = UploadMode.production;
|
||||
UploadMode _uploadMode = UploadMode.simulate;
|
||||
static const String _uploadModePrefsKey = 'upload_mode';
|
||||
UploadMode get uploadMode => _uploadMode;
|
||||
Future<void> setUploadMode(UploadMode mode) async {
|
||||
|
||||
@@ -10,6 +10,18 @@ const double kTileEstimateKb = 25.0;
|
||||
const double kDirectionConeHalfAngle = 20.0; // degrees
|
||||
const double kDirectionConeBaseLength = 0.0012; // multiplier
|
||||
|
||||
// Add Camera pin vertical offset (for pin tip to match coordinate on map)
|
||||
const double kAddPinYOffset = -16.0;
|
||||
|
||||
// Bottom overlay vertical positions (distance from bottom of screen)
|
||||
const double kAttributionBottom = 5.0;
|
||||
const double kScaleBarBottom = 40.0;
|
||||
const double kZoomIndicatorBottom = 70.0;
|
||||
|
||||
// Client name and version for OSM uploads ("created_by" tag)
|
||||
const String kClientName = 'FlockMap';
|
||||
const String kClientVersion = '0.8.1';
|
||||
|
||||
// Marker/camera interaction
|
||||
const int kCameraMinZoomLevel = 10; // Minimum zoom to show cameras or warning
|
||||
const Duration kMarkerTapTimeout = Duration(milliseconds: 250);
|
||||
|
||||
@@ -20,10 +20,7 @@ class CameraProfile {
|
||||
name: 'Generic Flock',
|
||||
tags: const {
|
||||
'man_made': 'surveillance',
|
||||
'surveillance': 'public',
|
||||
'surveillance:zone': 'traffic',
|
||||
'surveillance:type': 'ALPR', // left for backward compatibility — you may want to revisit per OSM best practice
|
||||
'camera:type': 'fixed',
|
||||
'surveillance:type': 'ALPR',
|
||||
'manufacturer': 'Flock Safety',
|
||||
'manufacturer:wikidata': 'Q108485435',
|
||||
},
|
||||
|
||||
@@ -27,10 +27,12 @@ class _HomeScreenState extends State<HomeScreen> {
|
||||
void _openAddCameraSheet() {
|
||||
final appState = context.read<AppState>();
|
||||
appState.startAddSession();
|
||||
final session = appState.session!; // guaranteed non‑null now
|
||||
final session = appState.session!; // guaranteed non‑null now
|
||||
|
||||
_scaffoldKey.currentState!.showBottomSheet(
|
||||
(ctx) => AddCameraSheet(session: session),
|
||||
showModalBottomSheet(
|
||||
context: context,
|
||||
isScrollControlled: true,
|
||||
builder: (ctx) => AddCameraSheet(session: session),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -66,31 +68,49 @@ class _HomeScreenState extends State<HomeScreen> {
|
||||
if (_followMe) setState(() => _followMe = false);
|
||||
},
|
||||
),
|
||||
floatingActionButton: appState.session == null
|
||||
? Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.end,
|
||||
children: [
|
||||
FloatingActionButton.extended(
|
||||
onPressed: _openAddCameraSheet,
|
||||
bottomNavigationBar: BottomAppBar(
|
||||
elevation: 10,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||
children: [
|
||||
Expanded(
|
||||
child: ElevatedButton.icon(
|
||||
icon: const Icon(Icons.add_location_alt),
|
||||
label: const Text('Tag Camera'),
|
||||
heroTag: 'tag_camera_fab',
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
FloatingActionButton.extended(
|
||||
onPressed: () => showDialog(
|
||||
context: context,
|
||||
builder: (ctx) => DownloadAreaDialog(controller: _mapController),
|
||||
onPressed: () {
|
||||
if (appState.session == null) {
|
||||
_openAddCameraSheet();
|
||||
}
|
||||
},
|
||||
style: ElevatedButton.styleFrom(
|
||||
minimumSize: const Size(0, 48),
|
||||
textStyle: const TextStyle(fontSize: 16),
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 12),
|
||||
Expanded(
|
||||
child: ElevatedButton.icon(
|
||||
icon: const Icon(Icons.download_for_offline),
|
||||
label: const Text('Download'),
|
||||
heroTag: 'download_fab',
|
||||
onPressed: appState.session == null
|
||||
? () => showDialog(
|
||||
context: context,
|
||||
builder: (ctx) => DownloadAreaDialog(controller: _mapController),
|
||||
)
|
||||
: null, // Disabled while camera sheet active
|
||||
style: ElevatedButton.styleFrom(
|
||||
minimumSize: const Size(0, 48),
|
||||
textStyle: const TextStyle(fontSize: 16),
|
||||
),
|
||||
),
|
||||
],
|
||||
)
|
||||
: null,
|
||||
floatingActionButtonLocation: FloatingActionButtonLocation.endFloat,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ import 'dart:async';
|
||||
import 'package:http/http.dart' as http;
|
||||
|
||||
import '../models/pending_upload.dart';
|
||||
|
||||
import '../dev_config.dart';
|
||||
import '../app_state.dart';
|
||||
|
||||
class Uploader {
|
||||
@@ -20,7 +20,7 @@ class Uploader {
|
||||
final csXml = '''
|
||||
<osm>
|
||||
<changeset>
|
||||
<tag k="created_by" v="FlockMap 0.5"/>
|
||||
<tag k="created_by" v="$kClientName $kClientVersion"/>
|
||||
<tag k="comment" v="Add surveillance camera"/>
|
||||
</changeset>
|
||||
</osm>''';
|
||||
|
||||
@@ -311,7 +311,7 @@ class _MapViewState extends State<MapView> {
|
||||
// Built-in scale bar from flutter_map
|
||||
Scalebar(
|
||||
alignment: Alignment.bottomLeft,
|
||||
padding: EdgeInsets.only(left: 8, bottom: 54), // above attribution
|
||||
padding: EdgeInsets.only(left: 8, bottom: kScaleBarBottom), // from dev_config, above attribution & BottomAppBar
|
||||
textStyle: TextStyle(color: Colors.black, fontWeight: FontWeight.bold),
|
||||
lineColor: Colors.black,
|
||||
strokeWidth: 3,
|
||||
@@ -353,7 +353,7 @@ class _MapViewState extends State<MapView> {
|
||||
// Zoom indicator, positioned above scale bar
|
||||
Positioned(
|
||||
left: 10,
|
||||
bottom: 92,
|
||||
bottom: kZoomIndicatorBottom, // from dev_config
|
||||
child: Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 7, vertical: 2),
|
||||
decoration: BoxDecoration(
|
||||
@@ -377,7 +377,7 @@ class _MapViewState extends State<MapView> {
|
||||
),
|
||||
// Attribution overlay
|
||||
Positioned(
|
||||
bottom: 20,
|
||||
bottom: kAttributionBottom, // from dev_config
|
||||
left: 10,
|
||||
child: Container(
|
||||
color: Colors.white70,
|
||||
@@ -391,9 +391,12 @@ class _MapViewState extends State<MapView> {
|
||||
|
||||
// Fixed pin when adding camera
|
||||
if (session != null)
|
||||
const IgnorePointer(
|
||||
IgnorePointer(
|
||||
child: Center(
|
||||
child: Icon(Icons.place, size: 40, color: Colors.redAccent),
|
||||
child: Transform.translate(
|
||||
offset: Offset(0, kAddPinYOffset),
|
||||
child: Icon(Icons.place, size: 40, color: Colors.redAccent),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
|
||||
Reference in New Issue
Block a user