mirror of
https://github.com/FoggedLens/deflock-app.git
synced 2026-02-12 16:52:51 +00:00
Disallow new/edit nodes below zoom 15, disallow downloads below zoom 10.
This commit is contained in:
@@ -98,8 +98,6 @@ cp lib/keys.dart.example lib/keys.dart
|
||||
## Roadmap
|
||||
|
||||
### Needed Bugfixes
|
||||
- Disallow new/edit nodes below zoom 10 (15?) (don't allow zooming out beyond that either)
|
||||
- Disallow large downloads or otherwise fix performance issue calculating number of tiles
|
||||
- Update node cache to reflect cleared queue entries
|
||||
- Improve/retune tile fetching backoff/retry
|
||||
- Are offline areas preferred for fast loading even when online? Check working.
|
||||
|
||||
@@ -1,6 +1,12 @@
|
||||
{
|
||||
"1.4.5": {
|
||||
"content": [
|
||||
"• NEW: Minimum zoom level (Z15) enforced for adding and editing surveillance nodes to ensure precise positioning",
|
||||
"• UX: Snackbar explains why add/edit sheets cannot open when zoomed out too far",
|
||||
"• UX: Prevents zooming out below minimum level when add/edit sheets are open",
|
||||
"• Node tags sheet continues to work at all zoom levels for viewing device information",
|
||||
"• NEW: Minimum zoom level (Z10) enforced for offline area downloads to prevent app crashes from large areas",
|
||||
"• UX: Download button shows explanatory message when zoomed out too far instead of hanging",
|
||||
"• IMPROVED: Offline area download confirmation now shows as popup with 'View Progress in Settings' button instead of simple notification",
|
||||
"• UX: Download failures now display as dialog instead of snackbar for better visibility"
|
||||
]
|
||||
|
||||
@@ -80,6 +80,8 @@ bool enableNavigationFeatures({required bool offlineMode}) {
|
||||
// Marker/node interaction
|
||||
const int kNodeMinZoomLevel = 10; // Minimum zoom to show nodes (Overpass)
|
||||
const int kOsmApiMinZoomLevel = 13; // Minimum zoom for OSM API bbox queries (sandbox mode)
|
||||
const int kMinZoomForNodeEditingSheets = 15; // Minimum zoom to open add/edit node sheets
|
||||
const int kMinZoomForOfflineDownload = 10; // Minimum zoom to download offline areas (prevents large area crashes)
|
||||
const Duration kMarkerTapTimeout = Duration(milliseconds: 250);
|
||||
const Duration kDebounceCameraRefresh = Duration(milliseconds: 500);
|
||||
|
||||
|
||||
@@ -118,6 +118,7 @@
|
||||
"enableSubmittableProfile": "Aktivieren Sie ein übertragbares Profil in den Einstellungen, um Knoten zu bearbeiten.",
|
||||
"profileViewOnlyWarning": "Dieses Profil ist nur zum Anzeigen der Karte gedacht. Bitte wählen Sie ein übertragbares Profil aus, um Knoten zu bearbeiten.",
|
||||
"cannotMoveConstrainedNode": "Kann diese Kamera nicht verschieben - sie ist mit einem anderen Kartenelement verbunden (OSM-Weg/Relation). Sie können trotzdem ihre Tags und Richtung bearbeiten.",
|
||||
"zoomInRequiredMessage": "Zoomen Sie auf mindestens Stufe {} heran, um Überwachungsknoten hinzuzufügen oder zu bearbeiten. Dies gewährleistet eine präzise Positionierung für genaues Kartieren.",
|
||||
"extractFromWay": "Knoten aus Weg/Relation extrahieren",
|
||||
"extractFromWaySubtitle": "Neuen Knoten mit gleichen Tags erstellen, Verschieben an neuen Ort ermöglichen",
|
||||
"refineTags": "Tags Verfeinern",
|
||||
@@ -133,6 +134,7 @@
|
||||
"withinTileLimit": "Innerhalb {} Kachel-Limit",
|
||||
"exceedsTileLimit": "Aktuelle Auswahl überschreitet {} Kachel-Limit",
|
||||
"offlineModeWarning": "Downloads im Offline-Modus deaktiviert. Deaktivieren Sie den Offline-Modus, um neue Bereiche herunterzuladen.",
|
||||
"areaTooBigMessage": "Zoomen Sie auf mindestens Stufe {} heran, um Offline-Bereiche herunterzuladen. Downloads großer Gebiete können die App zum Absturz bringen.",
|
||||
"downloadStarted": "Download gestartet! Lade Kacheln und Knoten...",
|
||||
"downloadFailed": "Download konnte nicht gestartet werden: {}"
|
||||
},
|
||||
|
||||
@@ -136,6 +136,7 @@
|
||||
"enableSubmittableProfile": "Enable a submittable profile in Settings to edit nodes.",
|
||||
"profileViewOnlyWarning": "This profile is for map viewing only. Please select a submittable profile to edit nodes.",
|
||||
"cannotMoveConstrainedNode": "Cannot move this camera - it's connected to another map element (OSM way/relation). You can still edit its tags and direction.",
|
||||
"zoomInRequiredMessage": "Zoom in to at least level {} to add or edit surveillance nodes. This ensures precise positioning for accurate mapping.",
|
||||
"extractFromWay": "Extract node from way/relation",
|
||||
"extractFromWaySubtitle": "Create new node with same tags, allow moving to new location",
|
||||
"refineTags": "Refine Tags",
|
||||
@@ -151,6 +152,7 @@
|
||||
"withinTileLimit": "Within {} tile limit",
|
||||
"exceedsTileLimit": "Current selection exceeds {} tile limit",
|
||||
"offlineModeWarning": "Downloads disabled while in offline mode. Disable offline mode to download new areas.",
|
||||
"areaTooBigMessage": "Zoom in to at least level {} to download offline areas. Large area downloads can cause the app to become unresponsive.",
|
||||
"downloadStarted": "Download started! Fetching tiles and nodes...",
|
||||
"downloadFailed": "Failed to start download: {}"
|
||||
},
|
||||
|
||||
@@ -136,6 +136,7 @@
|
||||
"enableSubmittableProfile": "Habilite un perfil envíable en Configuración para editar nodos.",
|
||||
"profileViewOnlyWarning": "Este perfil es solo para visualización del mapa. Por favor, seleccione un perfil envíable para editar nodos.",
|
||||
"cannotMoveConstrainedNode": "No se puede mover esta cámara - está conectada a otro elemento del mapa (OSM way/relation). Aún puede editar sus etiquetas y dirección.",
|
||||
"zoomInRequiredMessage": "Amplíe al menos al nivel {} para agregar o editar nodos de vigilancia. Esto garantiza un posicionamiento preciso para un mapeo exacto.",
|
||||
"extractFromWay": "Extraer nodo de way/relation",
|
||||
"extractFromWaySubtitle": "Crear nuevo nodo con las mismas etiquetas, permitir mover a nueva ubicación",
|
||||
"refineTags": "Refinar Etiquetas",
|
||||
@@ -151,6 +152,7 @@
|
||||
"withinTileLimit": "Dentro del límite de {} mosaicos",
|
||||
"exceedsTileLimit": "La selección actual excede el límite de {} mosaicos",
|
||||
"offlineModeWarning": "Descargas deshabilitadas en modo sin conexión. Deshabilite el modo sin conexión para descargar nuevas áreas.",
|
||||
"areaTooBigMessage": "Amplíe al menos al nivel {} para descargar áreas sin conexión. Las descargas de áreas grandes pueden hacer que la aplicación deje de responder.",
|
||||
"downloadStarted": "¡Descarga iniciada! Obteniendo mosaicos y nodos...",
|
||||
"downloadFailed": "Error al iniciar la descarga: {}"
|
||||
},
|
||||
|
||||
@@ -136,6 +136,7 @@
|
||||
"enableSubmittableProfile": "Activez un profil soumissible dans les Paramètres pour modifier les nœuds.",
|
||||
"profileViewOnlyWarning": "Ce profil est uniquement pour la visualisation de la carte. Veuillez sélectionner un profil soumissible pour modifier les nœuds.",
|
||||
"cannotMoveConstrainedNode": "Impossible de déplacer cette caméra - elle est connectée à un autre élément de carte (OSM way/relation). Vous pouvez toujours modifier ses balises et sa direction.",
|
||||
"zoomInRequiredMessage": "Zoomez au moins au niveau {} pour ajouter ou modifier des nœuds de surveillance. Cela garantit un positionnement précis pour une cartographie exacte.",
|
||||
"extractFromWay": "Extraire le nœud du way/relation",
|
||||
"extractFromWaySubtitle": "Créer un nouveau nœud avec les mêmes balises, permettre le déplacement vers un nouvel emplacement",
|
||||
"refineTags": "Affiner Balises",
|
||||
@@ -151,7 +152,8 @@
|
||||
"withinTileLimit": "Dans la limite de {} tuiles",
|
||||
"exceedsTileLimit": "La sélection actuelle dépasse la limite de {} tuiles",
|
||||
"offlineModeWarning": "Téléchargements désactivés en mode hors ligne. Désactivez le mode hors ligne pour télécharger de nouvelles zones.",
|
||||
"downloadStarted": "Téléchargement démarré! Récupération des tuiles et nœuds...",
|
||||
"areaTooBigMessage": "Zoomez au moins au niveau {} pour télécharger des zones hors ligne. Les téléchargements de grandes zones peuvent rendre l'application non réactive.",
|
||||
"downloadStarted": "Téléchargement démarré ! Récupération des tuiles et nœuds...",
|
||||
"downloadFailed": "Échec du démarrage du téléchargement: {}"
|
||||
},
|
||||
"downloadStarted": {
|
||||
|
||||
@@ -136,6 +136,7 @@
|
||||
"enableSubmittableProfile": "Abilita un profilo inviabile nelle Impostazioni per modificare i nodi.",
|
||||
"profileViewOnlyWarning": "Questo profilo è solo per la visualizzazione della mappa. Per favore seleziona un profilo inviabile per modificare i nodi.",
|
||||
"cannotMoveConstrainedNode": "Impossibile spostare questa telecamera - è collegata a un altro elemento della mappa (OSM way/relation). Puoi ancora modificare i suoi tag e direzione.",
|
||||
"zoomInRequiredMessage": "Ingrandisci almeno al livello {} per aggiungere o modificare nodi di sorveglianza. Questo garantisce un posizionamento preciso per una mappatura accurata.",
|
||||
"extractFromWay": "Estrai nodo da way/relation",
|
||||
"extractFromWaySubtitle": "Crea nuovo nodo con gli stessi tag, consenti spostamento in nuova posizione",
|
||||
"refineTags": "Affina Tag",
|
||||
@@ -151,6 +152,7 @@
|
||||
"withinTileLimit": "Entro il limite di {} tile",
|
||||
"exceedsTileLimit": "La selezione corrente supera il limite di {} tile",
|
||||
"offlineModeWarning": "Download disabilitati in modalità offline. Disabilita la modalità offline per scaricare nuove aree.",
|
||||
"areaTooBigMessage": "Ingrandisci almeno al livello {} per scaricare aree offline. I download di aree grandi possono rendere l'app non reattiva.",
|
||||
"downloadStarted": "Download avviato! Recupero tile e nodi...",
|
||||
"downloadFailed": "Impossibile avviare il download: {}"
|
||||
},
|
||||
|
||||
@@ -136,6 +136,7 @@
|
||||
"enableSubmittableProfile": "Ative um perfil enviável nas Configurações para editar nós.",
|
||||
"profileViewOnlyWarning": "Este perfil é apenas para visualização do mapa. Por favor, selecione um perfil enviável para editar nós.",
|
||||
"cannotMoveConstrainedNode": "Não é possível mover esta câmera - ela está conectada a outro elemento do mapa (OSM way/relation). Você ainda pode editar suas tags e direção.",
|
||||
"zoomInRequiredMessage": "Amplie para pelo menos o nível {} para adicionar ou editar nós de vigilância. Isto garante um posicionamento preciso para mapeamento exato.",
|
||||
"extractFromWay": "Extrair nó do way/relation",
|
||||
"extractFromWaySubtitle": "Criar novo nó com as mesmas tags, permitir mover para nova localização",
|
||||
"refineTags": "Refinar Tags",
|
||||
@@ -151,6 +152,7 @@
|
||||
"withinTileLimit": "Dentro do limite de {} tiles",
|
||||
"exceedsTileLimit": "A seleção atual excede o limite de {} tiles",
|
||||
"offlineModeWarning": "Downloads desabilitados no modo offline. Desative o modo offline para baixar novas áreas.",
|
||||
"areaTooBigMessage": "Amplie para pelo menos o nível {} para baixar áreas offline. Downloads de áreas grandes podem tornar o aplicativo não responsivo.",
|
||||
"downloadStarted": "Download iniciado! Buscando tiles e nós...",
|
||||
"downloadFailed": "Falha ao iniciar o download: {}"
|
||||
},
|
||||
|
||||
@@ -136,6 +136,7 @@
|
||||
"enableSubmittableProfile": "在设置中启用可提交的配置文件以编辑节点。",
|
||||
"profileViewOnlyWarning": "此配置文件仅用于地图查看。请选择可提交的配置文件来编辑节点。",
|
||||
"cannotMoveConstrainedNode": "无法移动此相机 - 它连接到另一个地图元素(OSM way/relation)。您仍可以编辑其标签和方向。",
|
||||
"zoomInRequiredMessage": "请放大至至少第{}级来添加或编辑监控节点。这确保精确定位以便准确制图。",
|
||||
"extractFromWay": "从way/relation中提取节点",
|
||||
"extractFromWaySubtitle": "创建具有相同标签的新节点,允许移动到新位置",
|
||||
"refineTags": "细化标签",
|
||||
@@ -151,6 +152,7 @@
|
||||
"withinTileLimit": "在 {} 瓦片限制内",
|
||||
"exceedsTileLimit": "当前选择超出 {} 瓦片限制",
|
||||
"offlineModeWarning": "离线模式下禁用下载。禁用离线模式以下载新区域。",
|
||||
"areaTooBigMessage": "请放大至至少第{}级来下载离线区域。下载大区域可能导致应用程序无响应。",
|
||||
"downloadStarted": "下载已开始!正在获取瓦片和节点...",
|
||||
"downloadFailed": "启动下载失败:{}"
|
||||
},
|
||||
|
||||
@@ -103,6 +103,21 @@ class _HomeScreenState extends State<HomeScreen> with TickerProviderStateMixin {
|
||||
|
||||
void _openAddNodeSheet() {
|
||||
final appState = context.read<AppState>();
|
||||
|
||||
// Check minimum zoom level before opening sheet
|
||||
final currentZoom = _mapController.mapController.camera.zoom;
|
||||
if (currentZoom < kMinZoomForNodeEditingSheets) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
content: Text(
|
||||
LocalizationService.instance.t('editNode.zoomInRequiredMessage',
|
||||
params: [kMinZoomForNodeEditingSheets.toString()])
|
||||
),
|
||||
),
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
// Disable follow-me when adding a camera so the map doesn't jump around
|
||||
appState.setFollowMeMode(FollowMeMode.off);
|
||||
|
||||
@@ -532,6 +547,20 @@ class _HomeScreenState extends State<HomeScreen> with TickerProviderStateMixin {
|
||||
child: NodeTagSheet(
|
||||
node: node,
|
||||
onEditPressed: () {
|
||||
// Check minimum zoom level before starting edit session
|
||||
final currentZoom = _mapController.mapController.camera.zoom;
|
||||
if (currentZoom < kMinZoomForNodeEditingSheets) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
content: Text(
|
||||
LocalizationService.instance.t('editNode.zoomInRequiredMessage',
|
||||
params: [kMinZoomForNodeEditingSheets.toString()])
|
||||
),
|
||||
),
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
final appState = context.read<AppState>();
|
||||
appState.startEditSession(node);
|
||||
// This will trigger _openEditNodeSheet via the existing auto-show logic
|
||||
@@ -760,10 +789,26 @@ class _HomeScreenState extends State<HomeScreen> with TickerProviderStateMixin {
|
||||
child: ElevatedButton.icon(
|
||||
icon: Icon(Icons.download_for_offline),
|
||||
label: Text(LocalizationService.instance.download),
|
||||
onPressed: () => showDialog(
|
||||
context: context,
|
||||
builder: (ctx) => DownloadAreaDialog(controller: _mapController.mapController),
|
||||
),
|
||||
onPressed: () {
|
||||
// Check minimum zoom level before opening download dialog
|
||||
final currentZoom = _mapController.mapController.camera.zoom;
|
||||
if (currentZoom < kMinZoomForOfflineDownload) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
content: Text(
|
||||
LocalizationService.instance.t('download.areaTooBigMessage',
|
||||
params: [kMinZoomForOfflineDownload.toString()])
|
||||
),
|
||||
),
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (ctx) => DownloadAreaDialog(controller: _mapController.mapController),
|
||||
);
|
||||
},
|
||||
style: ElevatedButton.styleFrom(
|
||||
minimumSize: Size(0, 48),
|
||||
textStyle: TextStyle(fontSize: 16),
|
||||
|
||||
@@ -597,6 +597,18 @@ class MapViewState extends State<MapView> {
|
||||
widget.onUserGesture();
|
||||
}
|
||||
|
||||
// Enforce minimum zoom level for add/edit node sheets (but not tag sheet)
|
||||
if ((session != null || editSession != null) && pos.zoom < kMinZoomForNodeEditingSheets) {
|
||||
// User tried to zoom out below minimum - snap back to minimum zoom
|
||||
_controller.animateTo(
|
||||
dest: pos.center,
|
||||
zoom: kMinZoomForNodeEditingSheets.toDouble(),
|
||||
duration: const Duration(milliseconds: 200),
|
||||
curve: Curves.easeOut,
|
||||
);
|
||||
return; // Don't process other position updates
|
||||
}
|
||||
|
||||
if (session != null) {
|
||||
appState.updateSession(target: pos.center);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user