mirror of
https://github.com/FoggedLens/deflock-app.git
synced 2026-09-28 03:51:43 +02:00
auto-open tags sheet for submissions (pending testing/feedback)
This commit is contained in:
@@ -3,10 +3,10 @@
|
|||||||
"content": [
|
"content": [
|
||||||
"• Make node tags selectable / copyable",
|
"• Make node tags selectable / copyable",
|
||||||
"• Add status indicator to details sheet for pending nodes",
|
"• Add status indicator to details sheet for pending nodes",
|
||||||
"• Global toggle for offline features"
|
"• Global toggle for offline features",
|
||||||
|
"• Auto-open details sheet for new add/edit/deletes"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|
||||||
"2.10.4": {
|
"2.10.4": {
|
||||||
"content": [
|
"content": [
|
||||||
"• Catch and correct a couple rare map bounds issues",
|
"• Catch and correct a couple rare map bounds issues",
|
||||||
|
|||||||
+28
-2
@@ -64,6 +64,12 @@ class AppState extends ChangeNotifier {
|
|||||||
VoidCallback? _tutorialCompletionCallback; // Callback when tutorial is completed
|
VoidCallback? _tutorialCompletionCallback; // Callback when tutorial is completed
|
||||||
Timer? _messageCheckTimer;
|
Timer? _messageCheckTimer;
|
||||||
|
|
||||||
|
// Node ID to auto-focus (open the details sheet for) after a submit/edit/delete
|
||||||
|
// completes, when kAutoOpenNodeSheetAfterSubmit is enabled. Consumed (read once
|
||||||
|
// and cleared) by HomeScreen after picking it up.
|
||||||
|
int? _pendingFocusNodeId;
|
||||||
|
|
||||||
|
|
||||||
AppState() {
|
AppState() {
|
||||||
instance = this;
|
instance = this;
|
||||||
_authState = AuthState();
|
_authState = AuthState();
|
||||||
@@ -584,24 +590,44 @@ class AppState extends ChangeNotifier {
|
|||||||
void commitSession() {
|
void commitSession() {
|
||||||
final session = _sessionState.commitSession();
|
final session = _sessionState.commitSession();
|
||||||
if (session != null) {
|
if (session != null) {
|
||||||
_uploadQueueState.addFromSession(session, uploadMode: uploadMode);
|
final upload = _uploadQueueState.addFromSession(session, uploadMode: uploadMode);
|
||||||
_startUploader();
|
_startUploader();
|
||||||
|
if (kAutoOpenNodeSheetAfterSubmit && upload.tempNodeId != null) {
|
||||||
|
_pendingFocusNodeId = upload.tempNodeId;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void commitEditSession() {
|
void commitEditSession() {
|
||||||
final session = _sessionState.commitEditSession();
|
final session = _sessionState.commitEditSession();
|
||||||
if (session != null) {
|
if (session != null) {
|
||||||
_uploadQueueState.addFromEditSession(session, uploadMode: uploadMode);
|
final upload = _uploadQueueState.addFromEditSession(session, uploadMode: uploadMode);
|
||||||
_startUploader();
|
_startUploader();
|
||||||
|
if (kAutoOpenNodeSheetAfterSubmit && upload.tempNodeId != null) {
|
||||||
|
_pendingFocusNodeId = upload.tempNodeId;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void deleteNode(OsmNode node, {String? changesetComment}) {
|
void deleteNode(OsmNode node, {String? changesetComment}) {
|
||||||
_uploadQueueState.addFromNodeDeletion(node, uploadMode: uploadMode, changesetComment: changesetComment);
|
_uploadQueueState.addFromNodeDeletion(node, uploadMode: uploadMode, changesetComment: changesetComment);
|
||||||
_startUploader();
|
_startUploader();
|
||||||
|
if (kAutoOpenNodeSheetAfterSubmit) {
|
||||||
|
_pendingFocusNodeId = node.id;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Consume (read once and clear) the node ID pending auto-focus, if any.
|
||||||
|
/// Used by HomeScreen to reopen the node details sheet right after a
|
||||||
|
/// submit/edit/delete completes, when [kAutoOpenNodeSheetAfterSubmit] is
|
||||||
|
/// enabled. Returns null if no focus is pending.
|
||||||
|
int? consumePendingFocusNodeId() {
|
||||||
|
final id = _pendingFocusNodeId;
|
||||||
|
_pendingFocusNodeId = null;
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// ---------- Search Methods ----------
|
// ---------- Search Methods ----------
|
||||||
Future<void> search(String query) async {
|
Future<void> search(String query) async {
|
||||||
await _searchState.search(query);
|
await _searchState.search(query);
|
||||||
|
|||||||
@@ -82,6 +82,9 @@ const bool kEnableNodeEdits = true; // Set to false to temporarily disable node
|
|||||||
// Node extraction features - set to false to hide extract functionality for constrained nodes
|
// Node extraction features - set to false to hide extract functionality for constrained nodes
|
||||||
const bool kEnableNodeExtraction = false; // Set to true to enable extract from way/relation feature (WIP)
|
const bool kEnableNodeExtraction = false; // Set to true to enable extract from way/relation feature (WIP)
|
||||||
|
|
||||||
|
// Auto-open tags sheet after add/edit/delete, so the user can watch upload status update live.
|
||||||
|
const bool kAutoOpenNodeSheetAfterSubmit = true; // Set to true to enable auto-focus behavior
|
||||||
|
|
||||||
// Profile FOV features - set to false to restrict profiles to 360° FOV only
|
// Profile FOV features - set to false to restrict profiles to 360° FOV only
|
||||||
const bool kEnableNon360FOVs = false; // Set to true to allow custom FOV values in profiles
|
const bool kEnableNon360FOVs = false; // Set to true to allow custom FOV values in profiles
|
||||||
|
|
||||||
|
|||||||
@@ -8,6 +8,8 @@ import '../app_state.dart';
|
|||||||
import '../dev_config.dart';
|
import '../dev_config.dart';
|
||||||
import '../widgets/map_view.dart';
|
import '../widgets/map_view.dart';
|
||||||
import '../services/localization_service.dart';
|
import '../services/localization_service.dart';
|
||||||
|
import '../services/map_data_provider.dart';
|
||||||
|
|
||||||
|
|
||||||
import '../widgets/node_tag_sheet.dart';
|
import '../widgets/node_tag_sheet.dart';
|
||||||
import '../widgets/download_area_dialog.dart';
|
import '../widgets/download_area_dialog.dart';
|
||||||
@@ -455,6 +457,22 @@ class _HomeScreenState extends State<HomeScreen> with TickerProviderStateMixin {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Auto-focus a node's details sheet right after it was submitted/edited/deleted,
|
||||||
|
// behind kAutoOpenNodeSheetAfterSubmit (pending A/B testing/team feedback).
|
||||||
|
if (kAutoOpenNodeSheetAfterSubmit) {
|
||||||
|
final focusNodeId = appState.consumePendingFocusNodeId();
|
||||||
|
if (focusNodeId != null && !_sheetCoordinator.hasActiveNodeSheet) {
|
||||||
|
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||||
|
if (!mounted) return;
|
||||||
|
final node = MapDataProvider().getNodeById(focusNodeId);
|
||||||
|
if (node != null) {
|
||||||
|
openNodeTagSheet(node);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Pass the active sheet height directly to the map
|
// Pass the active sheet height directly to the map
|
||||||
final activeSheetHeight = _sheetCoordinator.activeSheetHeight;
|
final activeSheetHeight = _sheetCoordinator.activeSheetHeight;
|
||||||
|
|
||||||
|
|||||||
@@ -121,7 +121,7 @@ class UploadQueueState extends ChangeNotifier {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Add a completed session to the upload queue
|
// Add a completed session to the upload queue
|
||||||
void addFromSession(AddNodeSession session, {required UploadMode uploadMode}) {
|
PendingUpload addFromSession(AddNodeSession session, {required UploadMode uploadMode}) {
|
||||||
final upload = PendingUpload(
|
final upload = PendingUpload(
|
||||||
coord: session.target!,
|
coord: session.target!,
|
||||||
direction: _formatDirectionsForSubmission(session.directions, session.profile),
|
direction: _formatDirectionsForSubmission(session.directions, session.profile),
|
||||||
@@ -159,10 +159,11 @@ class UploadQueueState extends ChangeNotifier {
|
|||||||
NodeProviderWithCache.instance.notifyListeners();
|
NodeProviderWithCache.instance.notifyListeners();
|
||||||
|
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
|
return upload;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add a completed edit session to the upload queue
|
// Add a completed edit session to the upload queue
|
||||||
void addFromEditSession(EditNodeSession session, {required UploadMode uploadMode}) {
|
PendingUpload addFromEditSession(EditNodeSession session, {required UploadMode uploadMode}) {
|
||||||
// Determine operation type and coordinates
|
// Determine operation type and coordinates
|
||||||
final UploadOperation operation;
|
final UploadOperation operation;
|
||||||
final LatLng coordToUse;
|
final LatLng coordToUse;
|
||||||
@@ -250,10 +251,11 @@ class UploadQueueState extends ChangeNotifier {
|
|||||||
NodeProviderWithCache.instance.notifyListeners();
|
NodeProviderWithCache.instance.notifyListeners();
|
||||||
|
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
|
return upload;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add a node deletion to the upload queue
|
// Add a node deletion to the upload queue
|
||||||
void addFromNodeDeletion(OsmNode node, {required UploadMode uploadMode, String? changesetComment}) {
|
PendingUpload addFromNodeDeletion(OsmNode node, {required UploadMode uploadMode, String? changesetComment}) {
|
||||||
final upload = PendingUpload(
|
final upload = PendingUpload(
|
||||||
coord: node.coord,
|
coord: node.coord,
|
||||||
direction: node.directionDeg.isNotEmpty ? node.directionDeg.first : 0, // Direction not used for deletions but required for API
|
direction: node.directionDeg.isNotEmpty ? node.directionDeg.first : 0, // Direction not used for deletions but required for API
|
||||||
@@ -282,6 +284,7 @@ class UploadQueueState extends ChangeNotifier {
|
|||||||
NodeProviderWithCache.instance.notifyListeners();
|
NodeProviderWithCache.instance.notifyListeners();
|
||||||
|
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
|
return upload;
|
||||||
}
|
}
|
||||||
|
|
||||||
void clearQueue() {
|
void clearQueue() {
|
||||||
|
|||||||
Reference in New Issue
Block a user