From 9a1903e6ed11439ee722438c88d33e9e6ff417a7 Mon Sep 17 00:00:00 2001 From: Jean-Luc Makiola Date: Mon, 15 Jun 2026 21:16:32 +0200 Subject: [PATCH] fix(edit): stop cursor jumping in event text fields The event form's state pipeline ran .flowOn(io) over the whole combine, including the _form round-trip every keystroke depends on. That async hop handed BasicTextField a lagging value while typing, so Compose kept correcting the cursor to the stale position. Scope flowOn(io) to just the calendar/prefs/settings reads and collect the form -> state -> UI path on the main dispatcher, so keystrokes round-trip synchronously and the cursor stays put. Co-Authored-By: Claude Opus 4.8 (1M context) --- CHANGELOG.md | 7 +++++++ .../jeanlucmakiola/calendula/ui/edit/EventEditViewModel.kt | 3 +-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 13574db..83b3d13 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Fixed +- Typing in the event title, location, and description fields no longer + makes the cursor jump around: the form state's round-trip to the UI was + hopping to a background dispatcher, so the text field saw a lagging value + while typing. Only the calendar/preferences reads stay off the main + thread now; the keystroke path is synchronous again + ## [2.0.0] — 2026-06-11 ### Added diff --git a/app/src/main/java/de/jeanlucmakiola/calendula/ui/edit/EventEditViewModel.kt b/app/src/main/java/de/jeanlucmakiola/calendula/ui/edit/EventEditViewModel.kt index 28040ee..22332a1 100644 --- a/app/src/main/java/de/jeanlucmakiola/calendula/ui/edit/EventEditViewModel.kt +++ b/app/src/main/java/de/jeanlucmakiola/calendula/ui/edit/EventEditViewModel.kt @@ -109,7 +109,7 @@ class EventEditViewModel @Inject constructor( prefs.lastUsedCalendarId, settingsPrefs.defaultFormFields, ::ExternalInputs, - ), + ).flowOn(io), ) { local, external -> val form = local.form ?: return@combine null val resolvedId = form.calendarId @@ -131,7 +131,6 @@ class EventEditViewModel @Inject constructor( resolved.rrule != local.editTarget.original.rrule, ) } - .flowOn(io) .stateIn( scope = viewModelScope, started = SharingStarted.WhileSubscribed(5_000L),