moving the right direction

This commit is contained in:
stopflock committed 2025-08-06 20:37:25 -05:00
1 parent db93d83efe
commit ca64859df6
4 files changed
+197 -38

No files matched your search

+45 -18
View File
@@ -96,16 +96,38 @@ class DownloadAreaDialog extends StatefulWidget {
class _DownloadAreaDialogState extends State<DownloadAreaDialog> {
double _zoom = 15;
int? _minZoom;
int? _tileCount;
double? _mbEstimate;
// Fake estimation: about 0.5 MB per zoom per km² for now
String get _storageEstimate {
// This can be improved later to use map bounds
final estMb = (0.5 * (_zoom - 11)).clamp(1, 50);
return 'Est: ${estMb.toStringAsFixed(1)} MB';
@override
void initState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback((_) => _recomputeEstimates());
}
void _recomputeEstimates() {
final bounds = widget.controller.camera.visibleBounds;
final minZoom = OfflineAreaService().findDynamicMinZoom(bounds);
final maxZoom = _zoom.toInt();
final allTiles = OfflineAreaService().computeTileList(bounds, minZoom, maxZoom);
final worldTiles = OfflineAreaService().computeTileList(
OfflineAreaService().globalWorldBounds(), 1, 4);
final nTiles = allTiles.length + worldTiles.length;
const kbPerTile = 25; // Average PNG tile size
final totalMb = (nTiles * kbPerTile) / 1024.0;
setState(() {
_minZoom = minZoom;
_tileCount = nTiles;
_mbEstimate = totalMb;
});
}
@override
Widget build(BuildContext context) {
final bounds = widget.controller.camera.visibleBounds;
final maxZoom = _zoom.toInt();
// We recompute estimates when the zoom slider changes
return AlertDialog(
title: Row(
children: const [
@@ -132,16 +154,29 @@ class _DownloadAreaDialogState extends State<DownloadAreaDialog> {
divisions: 7,
label: 'Z${_zoom.toStringAsFixed(0)}',
value: _zoom,
onChanged: (v) => setState(() => _zoom = v),
onChanged: (v) {
setState(() => _zoom = v);
WidgetsBinding.instance.addPostFrameCallback((_) => _recomputeEstimates());
},
),
const SizedBox(height: 8),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
const Text('Storage estimate:'),
Text(_storageEstimate),
Text(_mbEstimate == null
? '…'
: '${_tileCount} tiles, ${_mbEstimate!.toStringAsFixed(1)} MB'),
],
),
if (_minZoom != null)
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
const Text('Min zoom:'),
Text('Z$_minZoom'),
],
)
],
),
),
@@ -153,16 +188,13 @@ class _DownloadAreaDialogState extends State<DownloadAreaDialog> {
ElevatedButton(
onPressed: () async {
try {
final bounds = widget.controller.camera.visibleBounds;
final maxZoom = _zoom.toInt();
final minZoom = _findDynamicMinZoom(bounds);
final id = DateTime.now().toIso8601String().replaceAll(':', '-');
final dir = '/tmp/offline_areas/$id';
final appDocDir = await OfflineAreaService().getOfflineAreaDir();
final dir = "${appDocDir.path}/$id";
await OfflineAreaService().downloadArea(
id: id,
bounds: bounds,
minZoom: minZoom,
minZoom: _minZoom ?? 12,
maxZoom: maxZoom,
directory: dir,
onProgress: (progress) {},
@@ -188,10 +220,5 @@ class _DownloadAreaDialogState extends State<DownloadAreaDialog> {
],
);
}
int _findDynamicMinZoom(LatLngBounds bounds) {
// For now, just pick 12 as min; can implement dynamic min‑zoom by area
return 12;
}
}
+16 -11
View File
@@ -262,19 +262,24 @@ class SettingsScreen extends StatelessWidget {
// show dialog with text (replace with file contents as needed)
showDialog(
context: context,
builder: (context) => AlertDialog(
title: const Text('About This App'),
content: SingleChildScrollView(
child: Text(
'Flock Map App\n\nBuilt with Flutter.\n\nOffline areas, privacy-respecting, designed for OpenStreetMap camera tagging.\n\n(Replace this with info.txt contents.)',
builder: (context) => FutureBuilder<String>(
future: DefaultAssetBundle.of(context).loadString('assets/info.txt'),
builder: (context, snapshot) => AlertDialog(
title: const Text('About This App'),
content: SingleChildScrollView(
child: Text(
snapshot.connectionState == ConnectionState.done
? (snapshot.data ?? 'No info available.')
: 'Loading...',
),
),
actions: [
TextButton(
onPressed: () => Navigator.pop(context),
child: const Text('OK'),
),
],
),
actions: [
TextButton(
onPressed: () => Navigator.pop(context),
child: const Text('OK'),
),
],
),
);
},