Feature/feature drafts - #4652
Conversation
Coverage Report for CI Build 32107333826Coverage decreased (-0.5%) to 58.633%Details
Uncovered ChangesNo uncovered changes found. Coverage Regressions531 previously-covered lines in 8 files lost coverage.
Coverage Stats
💛 - Coveralls |
📦 Build Artifacts Ready
|
Withalion
left a comment
There was a problem hiding this comment.
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
| ShowSwitchWorkspaceAction, | ||
| ShowSyncFailedDialog | ||
| ShowSyncFailedDialog, | ||
| OpenDraftAction |
There was a problem hiding this comment.
| OpenDraftAction | |
| ShowDraftAction |
let's keep the naming convention
|
|
||
| secondaryButton.text: qsTr( "Do not discard" ) | ||
|
|
||
| onPrimaryButtonClicked: { |
There was a problem hiding this comment.
| onPrimaryButtonClicked: { | |
| onPrimaryButtonClicked: () => { |
| close() | ||
| } | ||
|
|
||
| onSecondaryButtonClicked: { |
There was a problem hiding this comment.
| onSecondaryButtonClicked: { | |
| onSecondaryButtonClicked: () => { |
| signal discardClicked() | ||
|
|
||
| imageSource: __style.neutralMMSymbolImage | ||
| title: featureTitle !== "" |
There was a problem hiding this comment.
| title: featureTitle !== "" | |
| title: featureTitle |
| setDraft( false ); | ||
|
|
||
| if ( wkt.isEmpty() ) | ||
| return QgsGeometry(); |
There was a problem hiding this comment.
| return QgsGeometry(); | |
| return {}; |
| #ifndef FEATUREDRAFTSTORAGE_H | ||
| #define FEATUREDRAFTSTORAGE_H | ||
|
|
||
| #include <QString> |
There was a problem hiding this comment.
| #include <QString> |
| #include <QSettings> | ||
| #include <QJsonDocument> | ||
|
|
||
| const QString FeatureDraftStorage::QSETTINGS_DRAFTS_GROUP_NAME = QStringLiteral( "featureDrafts" ); |
There was a problem hiding this comment.
declaring the literal should be enough here, you don't have to declare it in the class as well
|
|
||
| if ( raw.isEmpty() ) | ||
| { | ||
| return QJsonObject(); |
There was a problem hiding this comment.
| return QJsonObject(); | |
| return {}; |
There was a problem hiding this comment.
as probably mentioned elsewhere the data of draft should be stored during runtime as a structure and this class should do the conversion between structure and QSettings friendly format. Other classes don't need to know how it's stored
Withalion
left a comment
There was a problem hiding this comment.
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
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
FeatureDraftStorage/FeatureDraftController(app/drafts/) persist an in-progress edit (geometry + attributes) as a JSON blob viaQSettings, debounced by ~1s so it isn't written on every keystroke/vertex.AttributeControllerandRecordingMapToolwrite a draft whenever attributes or geometry are edited, and clear it once the feature is saved, deleted, or the edit is cancelled.ActiveProjectexposes the draft controller to QML.Behaviour
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.