Better handoff from tags to edit sheet

This commit is contained in:
stopflock
2025-10-01 13:27:17 -05:00
parent 96b82ef416
commit 1aeae18ebc
3 changed files with 77 additions and 29 deletions

View File

@@ -34,6 +34,9 @@ class _HomeScreenState extends State<HomeScreen> with TickerProviderStateMixin {
double _addSheetHeight = 0.0;
double _editSheetHeight = 0.0;
double _tagSheetHeight = 0.0;
// Flag to prevent map bounce when transitioning from tag sheet to edit sheet
bool _transitioningToEdit = false;
@override
void initState() {
@@ -113,6 +116,9 @@ class _HomeScreenState extends State<HomeScreen> with TickerProviderStateMixin {
// Disable follow-me when editing a camera so the map doesn't jump around
appState.setFollowMeMode(FollowMeMode.off);
// Set transition flag to prevent map bounce
_transitioningToEdit = true;
// Close any existing tag sheet first
if (_tagSheetHeight > 0) {
Navigator.of(context).pop();
@@ -120,21 +126,32 @@ class _HomeScreenState extends State<HomeScreen> with TickerProviderStateMixin {
final session = appState.editSession!; // should be non-null when this is called
final controller = _scaffoldKey.currentState!.showBottomSheet(
(ctx) => MeasuredSheet(
onHeightChanged: (height) {
setState(() {
_editSheetHeight = height;
});
},
child: EditNodeSheet(session: session),
),
);
// Reset height when sheet is dismissed
controller.closed.then((_) {
setState(() {
_editSheetHeight = 0.0;
// Small delay to let tag sheet close smoothly
Future.delayed(const Duration(milliseconds: 150), () {
if (!mounted) return;
final controller = _scaffoldKey.currentState!.showBottomSheet(
(ctx) => MeasuredSheet(
onHeightChanged: (height) {
setState(() {
_editSheetHeight = height;
// Clear transition flag and reset tag sheet height once edit sheet starts sizing
if (height > 0 && _transitioningToEdit) {
_transitioningToEdit = false;
_tagSheetHeight = 0.0; // Now safe to reset
}
});
},
child: EditNodeSheet(session: session),
),
);
// Reset height when sheet is dismissed
controller.closed.then((_) {
setState(() {
_editSheetHeight = 0.0;
_transitioningToEdit = false;
});
});
});
}
@@ -147,15 +164,25 @@ class _HomeScreenState extends State<HomeScreen> with TickerProviderStateMixin {
_tagSheetHeight = height;
});
},
child: NodeTagSheet(node: node),
child: NodeTagSheet(
node: node,
onEditPressed: () {
final appState = context.read<AppState>();
appState.startEditSession(node);
// This will trigger _openEditNodeSheet via the existing auto-show logic
},
),
),
);
// Reset height when sheet is dismissed
// Reset height when sheet is dismissed (unless transitioning to edit)
controller.closed.then((_) {
setState(() {
_tagSheetHeight = 0.0;
});
if (!_transitioningToEdit) {
setState(() {
_tagSheetHeight = 0.0;
});
}
// If transitioning to edit, keep the height until edit sheet takes over
});
}
@@ -174,7 +201,9 @@ class _HomeScreenState extends State<HomeScreen> with TickerProviderStateMixin {
// Pass the active sheet height directly to the map
final activeSheetHeight = _addSheetHeight > 0
? _addSheetHeight
: (_editSheetHeight > 0 ? _editSheetHeight : _tagSheetHeight);
: (_editSheetHeight > 0
? _editSheetHeight
: _tagSheetHeight);
return MultiProvider(
providers: [

View File

@@ -69,7 +69,12 @@ class MapOverlays extends StatelessWidget {
),
child: Builder(
builder: (context) {
final zoom = mapController.camera.zoom;
double zoom = 15.0; // fallback
try {
zoom = mapController.camera.zoom;
} catch (_) {
// Map controller not ready yet
}
return Text(
'Zoom: ${zoom.toStringAsFixed(2)}',
style: const TextStyle(
@@ -118,8 +123,12 @@ class MapOverlays extends StatelessWidget {
mini: true,
heroTag: "zoom_in",
onPressed: () {
final zoom = mapController.camera.zoom;
mapController.move(mapController.camera.center, zoom + 1);
try {
final zoom = mapController.camera.zoom;
mapController.move(mapController.camera.center, zoom + 1);
} catch (_) {
// Map controller not ready yet
}
},
child: const Icon(Icons.add),
),
@@ -129,8 +138,12 @@ class MapOverlays extends StatelessWidget {
mini: true,
heroTag: "zoom_out",
onPressed: () {
final zoom = mapController.camera.zoom;
mapController.move(mapController.camera.center, zoom - 1);
try {
final zoom = mapController.camera.zoom;
mapController.move(mapController.camera.center, zoom - 1);
} catch (_) {
// Map controller not ready yet
}
},
child: const Icon(Icons.remove),
),

View File

@@ -6,8 +6,9 @@ import '../services/localization_service.dart';
class NodeTagSheet extends StatelessWidget {
final OsmNode node;
final VoidCallback? onEditPressed;
const NodeTagSheet({super.key, required this.node});
const NodeTagSheet({super.key, required this.node, this.onEditPressed});
@override
Widget build(BuildContext context) {
@@ -26,8 +27,13 @@ class NodeTagSheet extends StatelessWidget {
node.tags['_pending_deletion'] != 'true');
void _openEditSheet() {
Navigator.pop(context); // Close this sheet first
appState.startEditSession(node); // HomeScreen will auto-show the edit sheet
if (onEditPressed != null) {
onEditPressed!(); // Use callback if provided
} else {
// Fallback behavior
Navigator.pop(context); // Close this sheet first
appState.startEditSession(node); // HomeScreen will auto-show the edit sheet
}
}
void _deleteNode() async {