Skip to content

Feature/feature drafts - #4652

Open
xkello wants to merge 6 commits into
masterfrom
feature/feature-drafts
Open

xkello wants to merge 6 commits into
masterfrom
feature/feature-drafts

Conversation

@xkello

@xkello xkello commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

Description

Adds automatic recovery of in-progress feature edits. If the app closes unexpectedly while you're editing a feature - a crash, an incoming call, a dead battery - your unsaved geometry and attribute changes are no longer lost. On the next launch you're offered the chance to resume exactly where you left off, or discard the changes.

Fixes: #4585

What changed

  • New FeatureDraftStorage / FeatureDraftController (app/drafts/) persist an in-progress edit (geometry + attributes) as a JSON blob via QSettings, debounced by ~1s so it isn't written on every keystroke/vertex.
  • AttributeController and RecordingMapTool write a draft whenever attributes or geometry are edited, and clear it once the feature is saved, deleted, or the edit is cancelled.
  • Before a draft is offered, it's validated: not older than 10 days, the layer/schema still matches, and (for edits) the feature still exists.
  • A new notification, plus resume/discard drawers, let the user act on a pending draft.
  • New banners on the Layers list and Features list screens surface a draft on the affected layer, reusing the existing "active filters" banner styling.
  • ActiveProject exposes the draft controller to QML.

Behaviour

  • Editing a feature's attributes or geometry saves a draft in the background about a second after the last change.
  • If the app is closed and reopened with a pending draft, a notification appears: "You have unsaved changes. Tap here to open them."
  • Tapping it - or trying to start a new "Add"/"Edit" while a draft exists - opens a drawer offering to Resume or Discard.
  • Resuming puts you back exactly where you left off: mid geometry capture, or on the form with the in-progress attributes.
  • Saving, deleting, or cancelling an edit normally clears its draft; a draft is silently discarded instead of offered if its layer was removed, its schema changed, its feature no longer exists, or it's over 10 days old.
Screen_Recording_20260818-082140_One.UI.Home.mp4
Screen_Recording_20260818-082018_One.UI.Home.mp4
Screen_Recording_20260818-082039.mp4

TLDR @Withalion

Feature edits are now drafted automatically so a crash, call, or dead battery doesn't cost you your unsaved work - surfaced via a notification and resume/discard drawers.

@xkello
xkello requested a review from Withalion August 18, 2026 06:34
@github-actions

github-actions Bot commented Aug 18, 2026 •

Copy link
Copy Markdown

Coverage Report for CI Build 37486743244

Coverage increased (+0.1%) to 59.659%

Details

  • Coverage increased (+0.1%) from the base build.
  • Patch coverage: No coverable lines changed in this PR.
  • 625 coverage regressions across 8 files.

Uncovered Changes

No uncovered changes found.

Coverage Regressions

625 previously-covered lines in 8 files lost coverage.

File Lines Losing Coverage Coverage
mm/app/maptools/recordingmaptool.cpp 224 68.99%
mm/app/attributes/attributecontroller.cpp 200 73.99%
mm/app/main.cpp 99 36.29%
mm/app/activeproject.cpp 73 70.61%
mm/app/notificationmodel.cpp 21 48.45%
mm/app/maptools/recordingmaptool.h 4 50.0%
mm/app/notificationmodel.h 3 50.0%
mm/app/layerfeaturesmodel.cpp 1 81.77%

Coverage Stats

Coverage Status
Relevant Lines: 16031
Covered Lines: 9564
Line Coverage: 59.66%
Coverage Strength: 92.64 hits per line

💛 - Coveralls

@github-actions

Copy link
Copy Markdown

📦 Build Artifacts Ready

OS Status Build Info Workflow run
macOS Build ❌ Build failed or not found. #7166
linux Build 📬 Mergin Maps 71921 x86_64 Expires: 16/11/2026 #7192
win64 Build 📬 Mergin Maps 63681 win64 Expires: 16/11/2026 #6368
Android Build 📬 Mergin Maps 847751 APK [arm64-v8a] Expires: 16/11/2026 #8477
📬 Mergin Maps 847751 APK [arm64-v8a] Google Play Store #8477
Android Build 📬 Mergin Maps 847711 APK [armeabi-v7a] Expires: 16/11/2026 #8477
📬 Mergin Maps 847711 APK [armeabi-v7a] Google Play Store #8477
iOS Build 📬 Build number: 26.08.941811 #9418

@Withalion Withalion left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great job, it looks very promising! There are some trivial things, a bit more refactoring is needed, but mainly unit tests.

UI/UX

  • It would be nice to navigate to the geometry you will be recording further after you open the draft
  • After user is done recording geometry and doesn't fill out anything in the form yet, application crashes. We should open the form right away and not the geometry recording
  • When a draft is available and an existing feature is clicked to edit the warning drawer opens and closes right away
  • When a draft is available and "add" button is clicked, the drawer opens correctly, but discarding draft doesn't start recording mode, but stays in "view" mode of map

Comment thread app/notificationmodel.h Outdated
Comment thread app/qml/dialogs/MMDiscardDraftDialog.qml
Comment thread app/qml/dialogs/MMDiscardDraftDialog.qml Outdated
Comment thread app/qml/dialogs/MMDiscardDraftDialog.qml Outdated
Comment thread app/qml/dialogs/MMResumeDraftDialog.qml Outdated
Comment thread app/drafts/featuredraftcontroller.cpp Outdated
Comment thread app/drafts/featuredraftstorage.h Outdated
Comment thread app/drafts/featuredraftstorage.cpp Outdated
Comment thread app/drafts/featuredraftstorage.cpp Outdated
Comment thread app/drafts/featuredraftstorage.h

@Withalion Withalion left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great job, it looks very promising! There are some trivial things, a bit more refactoring is needed, but mainly unit tests.

UI/UX

  • It would be nice to navigate to the geometry you will be recording further after you open the draft
  • After user is done recording geometry and doesn't fill out anything in the form yet, application crashes. We should open the form right away and not the geometry recording
  • When a draft is available and an existing feature is clicked to edit the warning drawer opens and closes right away
  • When a draft is available and "add" button is clicked, the drawer opens correctly, but discarding draft doesn't start recording mode, but stays in "view" mode of map

@xkello
xkello force-pushed the feature/feature-drafts branch from b242e2a to d02dcfb Compare September 23, 2026 16:00
@xkello
xkello requested a review from Withalion September 23, 2026 16:05
@github-actions

Copy link
Copy Markdown

📦 Build Artifacts Ready

OS Status Build Info Workflow run
macOS Build 📬 Mergin Maps 73291 dmg Expires: 22/12/2026 #7329
linux Build 📬 Mergin Maps 73551 x86_64 Expires: 22/12/2026 #7355
win64 Build 📬 Mergin Maps 65311 win64 Expires: 22/12/2026 #6531
Android Build 📬 Mergin Maps 864151 APK [arm64-v8a] Expires: 22/12/2026 #8641
📬 QR code Google Play Store #8641
Android Build 📬 Mergin Maps 864111 APK [armeabi-v7a] Expires: 22/12/2026 #8641
📬 QR code Google Play Store #8641
iOS Build 📬 Build number: 26.09.958111 #9581

@tomasMizera tomasMizera left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice! :)

When testing, let's try it out on some low-end devices to see if the 1 second interval is not causing too much slowness in UI. If so, we might need to move the saving part to another thread.

In general, this is going in a very good direction, I believe we will have this ready for testing soon.

Comment thread app/attributes/attributecontroller.cpp Outdated
Comment thread app/attributes/attributecontroller.cpp Outdated
Comment thread app/attributes/attributecontroller.cpp Outdated
Comment on lines +48 to +51
connect( this, &RecordingMapTool::recordedGeometryChanged, this, [ this ]()
{
mDraftSaveTimer->start();
} );

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The signal sounds good to me too for now.

Comment thread app/maptools/recordingmaptool.cpp
Comment thread app/attributes/attributecontroller.h Outdated
Comment thread app/drafts/featuredraftcontroller.cpp Outdated

void FeatureDraftController::checkForDraft()
{
const QString projectId = QgsProject::instance()->homePath();

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This one's not resolved and I am +1 to use project IDs instead of homepath.

Comment thread app/drafts/featuredraftcontroller.cpp Outdated
Comment thread app/drafts/featuredraftcontroller.cpp Outdated
Comment thread app/qml/form/MMFormController.qml
@github-actions

github-actions Bot commented Oct 4, 2026

Copy link
Copy Markdown

📦 Build Artifacts Ready

OS Status Build Info Workflow run
macOS Build 📬 Mergin Maps 73811 dmg Expires: 02/01/2027 #7381
linux Build 📬 Mergin Maps 74071 x86_64 Expires: 02/01/2027 #7407
win64 Build 📬 Mergin Maps 65831 win64 Expires: 02/01/2027 #6583
Android Build 📬 Mergin Maps 869351 APK [arm64-v8a] Expires: 02/01/2027 #8693
📬 QR code Google Play Store #8693
Android Build 📬 Mergin Maps 869311 APK [armeabi-v7a] Expires: 02/01/2027 #8693
📬 QR code Google Play Store #8693
iOS Build 📬 Build number: 26.10.963311 #9633

@xkello

xkello commented Oct 6, 2026

Copy link
Copy Markdown
Contributor Author

@Withalion everything should be resolved.

@github-actions

github-actions Bot commented Oct 6, 2026

Copy link
Copy Markdown

📦 Build Artifacts Ready

OS Status Build Info Workflow run
macOS Build ❌ Build failed or not found. #7386
linux Build 📬 Mergin Maps 74121 x86_64 Expires: 04/01/2027 #7412
win64 Build 📬 Mergin Maps 65881 win64 Expires: 04/01/2027 #6588
Android Build 📬 Mergin Maps 869811 APK [armeabi-v7a] Expires: 04/01/2027 #8698
📬 QR code Google Play Store #8698
Android Build 📬 Mergin Maps 869851 APK [arm64-v8a] Expires: 04/01/2027 #8698
📬 QR code Google Play Store #8698
iOS Build 📬 Build number: 26.10.963811 #9638

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Resume unsaved feature edits after unexpected app closure

4 participants