require profile selection

This commit is contained in:
stopflock committed 2025-10-24 13:49:48 -05:00
1 parent c7f4164f12
commit 2a7004e5a2
13 files changed
+103 -41

No files matched your search

+4 -4
View File
@@ -1,7 +1,10 @@
{ {
"1.2.8": {
"content": "• UX: Profile selection is now a required step to prevent accidental submission of default profile.\n• NEW: Note in welcome message about not submitting data you cannot vouch for personally (no street view etc)\n• NEW: Added default operator profiles for the most common private operators nationwide (Lowe's, Home Depot, et al)"
},
"1.2.7": { "1.2.7": {
"content": "• NEW: Compass indicator shows map orientation; tap to spin north-up\n• Smart area caching: Loads 3x larger areas and refreshes data every 60 seconds for much faster browsing\n• Enhanced tile loading: Increased retry attempts with faster delays - tiles load much more reliably\n• Better network status: Simplified loading indicator logic\n• Instant node display: Surveillance devices now appear immediately when data finishes loading\n• Node limit alerts: Get notified when some nodes are not drawn" "content": "• NEW: Compass indicator shows map orientation; tap to spin north-up\n• Smart area caching: Loads 3x larger areas and refreshes data every 60 seconds for much faster browsing\n• Enhanced tile loading: Increased retry attempts with faster delays - tiles load much more reliably\n• Better network status: Simplified loading indicator logic\n• Instant node display: Surveillance devices now appear immediately when data finishes loading\n• Node limit alerts: Get notified when some nodes are not drawn"
}, },
"1.2.4": { "1.2.4": {
"content": "• New welcome popup for first-time users with essential privacy information\n• Automatic changelog display when app updates (like this one!)\n• Added Release Notes viewer in Settings > About\n• Enhanced user onboarding and transparency about data handling\n• Improved documentation for contributors" "content": "• New welcome popup for first-time users with essential privacy information\n• Automatic changelog display when app updates (like this one!)\n• Added Release Notes viewer in Settings > About\n• Enhanced user onboarding and transparency about data handling\n• Improved documentation for contributors"
}, },
@@ -11,9 +14,6 @@
"1.2.2": { "1.2.2": {
"content": "• New surveillance device profiles added\n• Improved tile loading performance\n• Fixed issue with GPS accuracy\n• Updated translations" "content": "• New surveillance device profiles added\n• Improved tile loading performance\n• Fixed issue with GPS accuracy\n• Updated translations"
}, },
"1.2.1": {
"content": ""
},
"1.2.0": { "1.2.0": {
"content": "• Major UI improvements\n• Added proximity alerts\n• Enhanced offline capabilities\n• New suspected locations feature" "content": "• Major UI improvements\n• Added proximity alerts\n• Enhanced offline capabilities\n• New suspected locations feature"
} }
+4
View File
@@ -72,6 +72,8 @@
}, },
"addNode": { "addNode": {
"profile": "Profil", "profile": "Profil",
"selectProfile": "Profil auswählen...",
"profileRequired": "Bitte wählen Sie ein Profil aus, um fortzufahren.",
"direction": "Richtung {}°", "direction": "Richtung {}°",
"profileNoDirectionInfo": "Dieses Profil benötigt keine Richtung.", "profileNoDirectionInfo": "Dieses Profil benötigt keine Richtung.",
"mustBeLoggedIn": "Sie müssen angemeldet sein, um neue Knoten zu übertragen. Bitte melden Sie sich über die Einstellungen an.", "mustBeLoggedIn": "Sie müssen angemeldet sein, um neue Knoten zu übertragen. Bitte melden Sie sich über die Einstellungen an.",
@@ -83,6 +85,8 @@
"editNode": { "editNode": {
"title": "Knoten #{} Bearbeiten", "title": "Knoten #{} Bearbeiten",
"profile": "Profil", "profile": "Profil",
"selectProfile": "Profil auswählen...",
"profileRequired": "Bitte wählen Sie ein Profil aus, um fortzufahren.",
"direction": "Richtung {}°", "direction": "Richtung {}°",
"profileNoDirectionInfo": "Dieses Profil benötigt keine Richtung.", "profileNoDirectionInfo": "Dieses Profil benötigt keine Richtung.",
"mustBeLoggedIn": "Sie müssen angemeldet sein, um Knoten zu bearbeiten. Bitte melden Sie sich über die Einstellungen an.", "mustBeLoggedIn": "Sie müssen angemeldet sein, um Knoten zu bearbeiten. Bitte melden Sie sich über die Einstellungen an.",
+4
View File
@@ -89,6 +89,8 @@
}, },
"addNode": { "addNode": {
"profile": "Profile", "profile": "Profile",
"selectProfile": "Select a profile...",
"profileRequired": "Please select a profile to continue.",
"direction": "Direction {}°", "direction": "Direction {}°",
"profileNoDirectionInfo": "This profile does not require a direction.", "profileNoDirectionInfo": "This profile does not require a direction.",
"mustBeLoggedIn": "You must be logged in to submit new nodes. Please log in via Settings.", "mustBeLoggedIn": "You must be logged in to submit new nodes. Please log in via Settings.",
@@ -100,6 +102,8 @@
"editNode": { "editNode": {
"title": "Edit Node #{}", "title": "Edit Node #{}",
"profile": "Profile", "profile": "Profile",
"selectProfile": "Select a profile...",
"profileRequired": "Please select a profile to continue.",
"direction": "Direction {}°", "direction": "Direction {}°",
"profileNoDirectionInfo": "This profile does not require a direction.", "profileNoDirectionInfo": "This profile does not require a direction.",
"mustBeLoggedIn": "You must be logged in to edit nodes. Please log in via Settings.", "mustBeLoggedIn": "You must be logged in to edit nodes. Please log in via Settings.",
+4
View File
@@ -89,6 +89,8 @@
}, },
"addNode": { "addNode": {
"profile": "Perfil", "profile": "Perfil",
"selectProfile": "Seleccionar un perfil...",
"profileRequired": "Por favor, seleccione un perfil para continuar.",
"direction": "Dirección {}°", "direction": "Dirección {}°",
"profileNoDirectionInfo": "Este perfil no requiere una dirección.", "profileNoDirectionInfo": "Este perfil no requiere una dirección.",
"mustBeLoggedIn": "Debe estar conectado para enviar nuevos nodos. Por favor, inicie sesión a través de Configuración.", "mustBeLoggedIn": "Debe estar conectado para enviar nuevos nodos. Por favor, inicie sesión a través de Configuración.",
@@ -100,6 +102,8 @@
"editNode": { "editNode": {
"title": "Editar Nodo #{}", "title": "Editar Nodo #{}",
"profile": "Perfil", "profile": "Perfil",
"selectProfile": "Seleccionar un perfil...",
"profileRequired": "Por favor, seleccione un perfil para continuar.",
"direction": "Dirección {}°", "direction": "Dirección {}°",
"profileNoDirectionInfo": "Este perfil no requiere una dirección.", "profileNoDirectionInfo": "Este perfil no requiere una dirección.",
"mustBeLoggedIn": "Debe estar conectado para editar nodos. Por favor, inicie sesión a través de Configuración.", "mustBeLoggedIn": "Debe estar conectado para editar nodos. Por favor, inicie sesión a través de Configuración.",
+4
View File
@@ -89,6 +89,8 @@
}, },
"addNode": { "addNode": {
"profile": "Profil", "profile": "Profil",
"selectProfile": "Sélectionner un profil...",
"profileRequired": "Veuillez sélectionner un profil pour continuer.",
"direction": "Direction {}°", "direction": "Direction {}°",
"profileNoDirectionInfo": "Ce profil ne nécessite pas de direction.", "profileNoDirectionInfo": "Ce profil ne nécessite pas de direction.",
"mustBeLoggedIn": "Vous devez être connecté pour soumettre de nouveaux nœuds. Veuillez vous connecter via les Paramètres.", "mustBeLoggedIn": "Vous devez être connecté pour soumettre de nouveaux nœuds. Veuillez vous connecter via les Paramètres.",
@@ -100,6 +102,8 @@
"editNode": { "editNode": {
"title": "Modifier Nœud #{}", "title": "Modifier Nœud #{}",
"profile": "Profil", "profile": "Profil",
"selectProfile": "Sélectionner un profil...",
"profileRequired": "Veuillez sélectionner un profil pour continuer.",
"direction": "Direction {}°", "direction": "Direction {}°",
"profileNoDirectionInfo": "Ce profil ne nécessite pas de direction.", "profileNoDirectionInfo": "Ce profil ne nécessite pas de direction.",
"mustBeLoggedIn": "Vous devez être connecté pour modifier les nœuds. Veuillez vous connecter via les Paramètres.", "mustBeLoggedIn": "Vous devez être connecté pour modifier les nœuds. Veuillez vous connecter via les Paramètres.",
+4
View File
@@ -89,6 +89,8 @@
}, },
"addNode": { "addNode": {
"profile": "Profilo", "profile": "Profilo",
"selectProfile": "Seleziona un profilo...",
"profileRequired": "Per favore seleziona un profilo per continuare.",
"direction": "Direzione {}°", "direction": "Direzione {}°",
"profileNoDirectionInfo": "Questo profilo non richiede una direzione.", "profileNoDirectionInfo": "Questo profilo non richiede una direzione.",
"mustBeLoggedIn": "Devi essere loggato per inviare nuovi nodi. Per favore accedi tramite Impostazioni.", "mustBeLoggedIn": "Devi essere loggato per inviare nuovi nodi. Per favore accedi tramite Impostazioni.",
@@ -100,6 +102,8 @@
"editNode": { "editNode": {
"title": "Modifica Nodo #{}", "title": "Modifica Nodo #{}",
"profile": "Profilo", "profile": "Profilo",
"selectProfile": "Seleziona un profilo...",
"profileRequired": "Per favore seleziona un profilo per continuare.",
"direction": "Direzione {}°", "direction": "Direzione {}°",
"profileNoDirectionInfo": "Questo profilo non richiede una direzione.", "profileNoDirectionInfo": "Questo profilo non richiede una direzione.",
"mustBeLoggedIn": "Devi essere loggato per modificare i nodi. Per favore accedi tramite Impostazioni.", "mustBeLoggedIn": "Devi essere loggato per modificare i nodi. Per favore accedi tramite Impostazioni.",
+4
View File
@@ -89,6 +89,8 @@
}, },
"addNode": { "addNode": {
"profile": "Perfil", "profile": "Perfil",
"selectProfile": "Selecionar um perfil...",
"profileRequired": "Por favor, selecione um perfil para continuar.",
"direction": "Direção {}°", "direction": "Direção {}°",
"profileNoDirectionInfo": "Este perfil não requer uma direção.", "profileNoDirectionInfo": "Este perfil não requer uma direção.",
"mustBeLoggedIn": "Você deve estar logado para enviar novos nós. Por favor, faça login via Configurações.", "mustBeLoggedIn": "Você deve estar logado para enviar novos nós. Por favor, faça login via Configurações.",
@@ -100,6 +102,8 @@
"editNode": { "editNode": {
"title": "Editar Nó #{}", "title": "Editar Nó #{}",
"profile": "Perfil", "profile": "Perfil",
"selectProfile": "Selecionar um perfil...",
"profileRequired": "Por favor, selecione um perfil para continuar.",
"direction": "Direção {}°", "direction": "Direção {}°",
"profileNoDirectionInfo": "Este perfil não requer uma direção.", "profileNoDirectionInfo": "Este perfil não requer uma direção.",
"mustBeLoggedIn": "Você deve estar logado para editar nós. Por favor, faça login via Configurações.", "mustBeLoggedIn": "Você deve estar logado para editar nós. Por favor, faça login via Configurações.",
+4
View File
@@ -89,6 +89,8 @@
}, },
"addNode": { "addNode": {
"profile": "配置文件", "profile": "配置文件",
"selectProfile": "选择配置文件...",
"profileRequired": "请选择配置文件以继续。",
"direction": "方向 {}°", "direction": "方向 {}°",
"profileNoDirectionInfo": "此配置文件不需要方向。", "profileNoDirectionInfo": "此配置文件不需要方向。",
"mustBeLoggedIn": "您必须登录才能提交新节点。请通过设置登录。", "mustBeLoggedIn": "您必须登录才能提交新节点。请通过设置登录。",
@@ -100,6 +102,8 @@
"editNode": { "editNode": {
"title": "编辑节点 #{}", "title": "编辑节点 #{}",
"profile": "配置文件", "profile": "配置文件",
"selectProfile": "选择配置文件...",
"profileRequired": "请选择配置文件以继续。",
"direction": "方向 {}°", "direction": "方向 {}°",
"profileNoDirectionInfo": "此配置文件不需要方向。", "profileNoDirectionInfo": "此配置文件不需要方向。",
"mustBeLoggedIn": "您必须登录才能编辑节点。请通过设置登录。", "mustBeLoggedIn": "您必须登录才能编辑节点。请通过设置登录。",
+11 -15
View File
@@ -7,8 +7,8 @@ import '../models/osm_node.dart';
// ------------------ AddNodeSession ------------------ // ------------------ AddNodeSession ------------------
class AddNodeSession { class AddNodeSession {
AddNodeSession({required this.profile, this.directionDegrees = 0}); AddNodeSession({this.profile, this.directionDegrees = 0});
NodeProfile profile; NodeProfile? profile;
OperatorProfile? operatorProfile; OperatorProfile? operatorProfile;
double directionDegrees; double directionDegrees;
LatLng? target; LatLng? target;
@@ -18,13 +18,13 @@ class AddNodeSession {
class EditNodeSession { class EditNodeSession {
EditNodeSession({ EditNodeSession({
required this.originalNode, required this.originalNode,
required this.profile, this.profile,
required this.directionDegrees, required this.directionDegrees,
required this.target, required this.target,
}); });
final OsmNode originalNode; // The original node being edited final OsmNode originalNode; // The original node being edited
NodeProfile profile; NodeProfile? profile;
OperatorProfile? operatorProfile; OperatorProfile? operatorProfile;
double directionDegrees; double directionDegrees;
LatLng target; // Current position (can be dragged) LatLng target; // Current position (can be dragged)
@@ -39,11 +39,8 @@ class SessionState extends ChangeNotifier {
EditNodeSession? get editSession => _editSession; EditNodeSession? get editSession => _editSession;
void startAddSession(List<NodeProfile> enabledProfiles) { void startAddSession(List<NodeProfile> enabledProfiles) {
final submittableProfiles = enabledProfiles.where((p) => p.isSubmittable).toList(); // Start with no profile selected - force user to choose
final defaultProfile = submittableProfiles.isNotEmpty _session = AddNodeSession();
? submittableProfiles.first
: enabledProfiles.first; // Fallback to any enabled profile
_session = AddNodeSession(profile: defaultProfile);
_editSession = null; // Clear any edit session _editSession = null; // Clear any edit session
notifyListeners(); notifyListeners();
} }
@@ -52,11 +49,9 @@ class SessionState extends ChangeNotifier {
final submittableProfiles = enabledProfiles.where((p) => p.isSubmittable).toList(); final submittableProfiles = enabledProfiles.where((p) => p.isSubmittable).toList();
// Try to find a matching profile based on the node's tags // Try to find a matching profile based on the node's tags
NodeProfile matchingProfile = submittableProfiles.isNotEmpty NodeProfile? matchingProfile;
? submittableProfiles.first
: enabledProfiles.first;
// Attempt to find a better match by comparing tags // Attempt to find a match by comparing tags
for (final profile in submittableProfiles) { for (final profile in submittableProfiles) {
if (_profileMatchesTags(profile, node.tags)) { if (_profileMatchesTags(profile, node.tags)) {
matchingProfile = profile; matchingProfile = profile;
@@ -64,6 +59,7 @@ class SessionState extends ChangeNotifier {
} }
} }
// Start with no profile selected if no match found - force user to choose
_editSession = EditNodeSession( _editSession = EditNodeSession(
originalNode: node, originalNode: node,
profile: matchingProfile, profile: matchingProfile,
@@ -151,7 +147,7 @@ class SessionState extends ChangeNotifier {
} }
AddNodeSession? commitSession() { AddNodeSession? commitSession() {
if (_session?.target == null) return null; if (_session?.target == null || _session?.profile == null) return null;
final session = _session!; final session = _session!;
_session = null; _session = null;
@@ -160,7 +156,7 @@ class SessionState extends ChangeNotifier {
} }
EditNodeSession? commitEditSession() { EditNodeSession? commitEditSession() {
if (_editSession == null) return null; if (_editSession?.profile == null) return null;
final session = _editSession!; final session = _editSession!;
_editSession = null; _editSession = null;
+2 -2
View File
@@ -30,7 +30,7 @@ class UploadQueueState extends ChangeNotifier {
final upload = PendingUpload( final upload = PendingUpload(
coord: session.target!, coord: session.target!,
direction: session.directionDegrees, direction: session.directionDegrees,
profile: session.profile, profile: session.profile!, // Safe to use ! because commitSession() checks for null
operatorProfile: session.operatorProfile, operatorProfile: session.operatorProfile,
uploadMode: uploadMode, uploadMode: uploadMode,
operation: UploadOperation.create, operation: UploadOperation.create,
@@ -64,7 +64,7 @@ class UploadQueueState extends ChangeNotifier {
final upload = PendingUpload( final upload = PendingUpload(
coord: session.target, coord: session.target,
direction: session.directionDegrees, direction: session.directionDegrees,
profile: session.profile, profile: session.profile!, // Safe to use ! because commitEditSession() checks for null
operatorProfile: session.operatorProfile, operatorProfile: session.operatorProfile,
uploadMode: uploadMode, uploadMode: uploadMode,
operation: UploadOperation.modify, operation: UploadOperation.modify,
+28 -9
View File
@@ -34,7 +34,10 @@ class AddNodeSheet extends StatelessWidget {
} }
final submittableProfiles = appState.enabledProfiles.where((p) => p.isSubmittable).toList(); final submittableProfiles = appState.enabledProfiles.where((p) => p.isSubmittable).toList();
final allowSubmit = appState.isLoggedIn && submittableProfiles.isNotEmpty && session.profile.isSubmittable; final allowSubmit = appState.isLoggedIn &&
submittableProfiles.isNotEmpty &&
session.profile != null &&
session.profile!.isSubmittable;
void _openRefineTags() async { void _openRefineTags() async {
final result = await Navigator.push<OperatorProfile?>( final result = await Navigator.push<OperatorProfile?>(
@@ -66,13 +69,13 @@ class AddNodeSheet extends StatelessWidget {
const SizedBox(height: 16), const SizedBox(height: 16),
ListTile( ListTile(
title: Text(locService.t('addNode.profile')), title: Text(locService.t('addNode.profile')),
trailing: DropdownButton<NodeProfile>( trailing: DropdownButton<NodeProfile?>(
value: session.profile, value: session.profile,
hint: Text(locService.t('addNode.selectProfile')),
items: submittableProfiles items: submittableProfiles
.map((p) => DropdownMenuItem(value: p, child: Text(p.name))) .map((p) => DropdownMenuItem(value: p, child: Text(p.name)))
.toList(), .toList(),
onChanged: (p) => onChanged: (p) => appState.updateSession(profile: p),
appState.updateSession(profile: p ?? session.profile),
), ),
), ),
ListTile( ListTile(
@@ -83,12 +86,12 @@ class AddNodeSheet extends StatelessWidget {
divisions: 359, divisions: 359,
value: session.directionDegrees, value: session.directionDegrees,
label: session.directionDegrees.round().toString(), label: session.directionDegrees.round().toString(),
onChanged: session.profile.requiresDirection onChanged: (session.profile != null && session.profile!.requiresDirection)
? (v) => appState.updateSession(directionDeg: v) ? (v) => appState.updateSession(directionDeg: v)
: null, // Disables slider when requiresDirection is false : null, // Disabled when no profile selected or profile doesn't require direction
), ),
), ),
if (!session.profile.requiresDirection) if (session.profile != null && !session.profile!.requiresDirection)
Padding( Padding(
padding: const EdgeInsets.fromLTRB(16, 0, 16, 12), padding: const EdgeInsets.fromLTRB(16, 0, 16, 12),
child: Row( child: Row(
@@ -136,7 +139,23 @@ class AddNodeSheet extends StatelessWidget {
], ],
), ),
) )
else if (!session.profile.isSubmittable) else if (session.profile == null)
Padding(
padding: const EdgeInsets.fromLTRB(16, 0, 16, 12),
child: Row(
children: [
const Icon(Icons.info_outline, color: Colors.orange, size: 20),
const SizedBox(width: 6),
Expanded(
child: Text(
locService.t('addNode.profileRequired'),
style: const TextStyle(color: Colors.orange, fontSize: 13),
),
),
],
),
)
else if (!session.profile!.isSubmittable)
Padding( Padding(
padding: const EdgeInsets.fromLTRB(16, 0, 16, 12), padding: const EdgeInsets.fromLTRB(16, 0, 16, 12),
child: Row( child: Row(
@@ -158,7 +177,7 @@ class AddNodeSheet extends StatelessWidget {
child: SizedBox( child: SizedBox(
width: double.infinity, width: double.infinity,
child: OutlinedButton.icon( child: OutlinedButton.icon(
onPressed: _openRefineTags, onPressed: session.profile != null ? _openRefineTags : null, // Disabled when no profile selected
icon: const Icon(Icons.tune), icon: const Icon(Icons.tune),
label: Text(session.operatorProfile != null label: Text(session.operatorProfile != null
? locService.t('addNode.refineTagsWithProfile', params: [session.operatorProfile!.name]) ? locService.t('addNode.refineTagsWithProfile', params: [session.operatorProfile!.name])
+28 -9
View File
@@ -36,7 +36,10 @@ class EditNodeSheet extends StatelessWidget {
final submittableProfiles = appState.enabledProfiles.where((p) => p.isSubmittable).toList(); final submittableProfiles = appState.enabledProfiles.where((p) => p.isSubmittable).toList();
final isSandboxMode = appState.uploadMode == UploadMode.sandbox; final isSandboxMode = appState.uploadMode == UploadMode.sandbox;
final allowSubmit = appState.isLoggedIn && submittableProfiles.isNotEmpty && session.profile.isSubmittable; final allowSubmit = appState.isLoggedIn &&
submittableProfiles.isNotEmpty &&
session.profile != null &&
session.profile!.isSubmittable;
void _openRefineTags() async { void _openRefineTags() async {
final result = await Navigator.push<OperatorProfile?>( final result = await Navigator.push<OperatorProfile?>(
@@ -73,13 +76,13 @@ class EditNodeSheet extends StatelessWidget {
const SizedBox(height: 16), const SizedBox(height: 16),
ListTile( ListTile(
title: Text(locService.t('editNode.profile')), title: Text(locService.t('editNode.profile')),
trailing: DropdownButton<NodeProfile>( trailing: DropdownButton<NodeProfile?>(
value: session.profile, value: session.profile,
hint: Text(locService.t('editNode.selectProfile')),
items: submittableProfiles items: submittableProfiles
.map((p) => DropdownMenuItem(value: p, child: Text(p.name))) .map((p) => DropdownMenuItem(value: p, child: Text(p.name)))
.toList(), .toList(),
onChanged: (p) => onChanged: (p) => appState.updateEditSession(profile: p),
appState.updateEditSession(profile: p ?? session.profile),
), ),
), ),
ListTile( ListTile(
@@ -90,12 +93,12 @@ class EditNodeSheet extends StatelessWidget {
divisions: 359, divisions: 359,
value: session.directionDegrees, value: session.directionDegrees,
label: session.directionDegrees.round().toString(), label: session.directionDegrees.round().toString(),
onChanged: session.profile.requiresDirection onChanged: (session.profile != null && session.profile!.requiresDirection)
? (v) => appState.updateEditSession(directionDeg: v) ? (v) => appState.updateEditSession(directionDeg: v)
: null, // Disables slider when requiresDirection is false : null, // Disabled when no profile selected or profile doesn't require direction
), ),
), ),
if (!session.profile.requiresDirection) if (session.profile != null && !session.profile!.requiresDirection)
Padding( Padding(
padding: const EdgeInsets.fromLTRB(16, 0, 16, 12), padding: const EdgeInsets.fromLTRB(16, 0, 16, 12),
child: Row( child: Row(
@@ -143,7 +146,23 @@ class EditNodeSheet extends StatelessWidget {
], ],
), ),
) )
else if (!session.profile.isSubmittable) else if (session.profile == null)
Padding(
padding: const EdgeInsets.fromLTRB(16, 0, 16, 12),
child: Row(
children: [
const Icon(Icons.info_outline, color: Colors.orange, size: 20),
const SizedBox(width: 6),
Expanded(
child: Text(
locService.t('editNode.profileRequired'),
style: const TextStyle(color: Colors.orange, fontSize: 13),
),
),
],
),
)
else if (!session.profile!.isSubmittable)
Padding( Padding(
padding: const EdgeInsets.fromLTRB(16, 0, 16, 12), padding: const EdgeInsets.fromLTRB(16, 0, 16, 12),
child: Row( child: Row(
@@ -165,7 +184,7 @@ class EditNodeSheet extends StatelessWidget {
child: SizedBox( child: SizedBox(
width: double.infinity, width: double.infinity,
child: OutlinedButton.icon( child: OutlinedButton.icon(
onPressed: _openRefineTags, onPressed: session.profile != null ? _openRefineTags : null, // Disabled when no profile selected
icon: const Icon(Icons.tune), icon: const Icon(Icons.tune),
label: Text(session.operatorProfile != null label: Text(session.operatorProfile != null
? locService.t('editNode.refineTagsWithProfile', params: [session.operatorProfile!.name]) ? locService.t('editNode.refineTagsWithProfile', params: [session.operatorProfile!.name])
+2 -2
View File
@@ -19,7 +19,7 @@ class DirectionConesBuilder {
final overlays = <Polygon>[]; final overlays = <Polygon>[];
// Add session cone if in add-camera mode and profile requires direction // Add session cone if in add-camera mode and profile requires direction
if (session != null && session.target != null && session.profile.requiresDirection) { if (session != null && session.target != null && session.profile?.requiresDirection == true) {
overlays.add(_buildCone( overlays.add(_buildCone(
session.target!, session.target!,
session.directionDegrees, session.directionDegrees,
@@ -30,7 +30,7 @@ class DirectionConesBuilder {
} }
// Add edit session cone if in edit-camera mode and profile requires direction // Add edit session cone if in edit-camera mode and profile requires direction
if (editSession != null && editSession.profile.requiresDirection) { if (editSession != null && editSession.profile?.requiresDirection == true) {
overlays.add(_buildCone( overlays.add(_buildCone(
editSession.target, editSession.target,
editSession.directionDegrees, editSession.directionDegrees,