diff --git a/lib/src/flow_editor_page.dart b/lib/src/flow_editor_page.dart index 0f3f301..b46b4b2 100644 --- a/lib/src/flow_editor_page.dart +++ b/lib/src/flow_editor_page.dart @@ -52,7 +52,14 @@ class _FlowEditorPageState extends State { late final CodeController _code; late final FlowEditorStrings _l; String? _activeName; - String _loadedText = ''; + // Baseline captured AFTER the CodeController has finished + // processing the loaded text (line-ending normalisation, + // trailing-newline handling, fold-marker insertion, …). + // Comparing _code.fullText against this baseline avoids the + // false-positive "discard unsaved changes?" prompts the + // naive _code.text == _loadedText check used to trigger on + // files the controller silently rewrote during load. + String _baseline = ''; late Future> _files; Object? _runError; Map? _runOutputs; @@ -85,7 +92,7 @@ class _FlowEditorPageState extends State { if (mounted) setState(() {}); } - bool get _dirty => _activeName != null && _code.text != _loadedText; + bool get _dirty => _activeName != null && _code.fullText != _baseline; Future> _listFiles() async { final dir = Directory(_defaultFlowsDir()); @@ -115,10 +122,15 @@ class _FlowEditorPageState extends State { if (!f.existsSync()) return; final text = await f.readAsString(); if (!mounted) return; + // Set the controller text first, then snapshot fullText + // as the baseline. Reading fullText after the assignment + // captures whatever line-ending normalisation / fold- + // marker insertion CodeController applied, so the dirty + // check is comparing apples to apples. + _code.text = text; setState(() { _activeName = name; - _loadedText = text; - _code.text = text; + _baseline = _code.fullText; _runOutputs = null; _runError = null; }); @@ -130,10 +142,10 @@ class _FlowEditorPageState extends State { if (keep == false || !mounted) return; } final text = await File(f.path).readAsString(); + _code.text = text; setState(() { _activeName = f.name; - _loadedText = text; - _code.text = text; + _baseline = _code.fullText; _runOutputs = null; _runError = null; }); @@ -168,7 +180,7 @@ class _FlowEditorPageState extends State { await f.writeAsString(_code.text, flush: true); if (!mounted) return; setState(() { - _loadedText = _code.text; + _baseline = _code.fullText; _files = _listFiles(); }); } catch (e) { @@ -215,10 +227,10 @@ outputs: } await f.writeAsString(template, flush: true); if (!mounted) return; + _code.text = template; setState(() { _activeName = name; - _loadedText = template; - _code.text = template; + _baseline = _code.fullText; _files = _listFiles(); }); } catch (e) { diff --git a/pubspec.yaml b/pubspec.yaml index e0f65d0..1e9dc3b 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: fai_studio_flow_editor description: Swappable inline YAML editor for F∆I Studio flows. -version: 0.1.0 +version: 0.1.1 publish_to: 'none' repository: https://git.flemming.ai/fai/studio-flow-editor