Skip to content

Edit and delete meals remotely from the Treatments view - #756

Open
bjorkert wants to merge 16 commits into
devfrom
feature/remote-meal-edit-delete
Open

bjorkert wants to merge 16 commits into
devfrom
feature/remote-meal-edit-delete

Conversation

@bjorkert

@bjorkert bjorkert commented Sep 25, 2026 •

Copy link
Copy Markdown
Member

Adds Edit and Delete for carb entries in the Treatments detail view, for Trio (via Trio Remote Control) and Loop (via Loop APNS). Companion Trio PR: nightscout/Trio#1579. Loop needs the remote_carb_edit customization: loopandlearn/customization#87.

Thanks to @aug0211 for #742, which shaped what this needed to cover. This takes the same idea with a smaller protocol.

Trio

  • The handle sent to Trio is the treatment's Nightscout id, for a meal root or any of its FPU entries. FPU rows show which meal they belong to and link to the root; editing from an FPU row uses the root's values.
  • Actions appear only when Trio Remote Control is active, the device is Trio, and the phone's Trio lists delete_meal/edit_meal in its Nightscout profile. Older Trio builds get a footer saying a newer version is needed.
  • Window: 24 h back, 12 h ahead. Edit is a replace; the entry reappears with a new id after refresh.
  • Payload: command_type edit_meal/delete_meal, meal_id, command_id (also the APNs collapse id), and for edit explicit carbs, fat, protein, scheduled_time.

Loop

  • Handle is the treatment's syncIdentifier. Delete sends carbs-delete; edit sends carbs-edit with carbs-edit-entry, carbs-edit-absorption-time, carbs-edit-start-time (always) and carbs-edit-food-type (when set). OTP, sent-at and expiration as for carbs today.
  • Window: 23 h back, 1 h ahead.
  • Actions appear only when Loop advertises the commands in devicestatus (loop.testingDetails.remoteCommands), which the customization does every loop cycle. Otherwise a footer says the customization is needed.

Acks

One RemoteCommandTracker keyed by meal id or syncIdentifier: pending → done, 60 s timeout, then the list refreshes. Trio acks match on command_id, Loop acks on sync_identifier. Both paths require LoopFollow's own APNS credentials so the app can confirm the result.

Other

  • Treatments list keeps id, fpuID, fat, protein and note for Trio entries and syncIdentifier for Loop entries.
  • Meal macro inputs extracted from MealView and reused by the edit sheet; prefilled values stay editable above the guardrail maxima.
  • Debug builds honor LOOPFOLLOW_APNS_BASE_URL for a local APNs stand-in.

Verified in the simulator against a mock Nightscout and a fake APNs endpoint, with acks delivered via simctl push: delete and edit for Trio and Loop, not_found, timeout, the FPU-child edit path, and gating by profile, device and remote type.

Screenshots

Trio

Meal detail Edit Delete Awaiting confirmation FPU entry
trio-detail trio-edit trio-delete-confirm trio-pending trio-fpu-detail

Loop

Carb detail Edit
loop-detail loop-edit

RemoteCommandTracker keeps one pending/done state per key (Trio meal id or
Loop sync identifier) with a 60 s timeout, and resolves it from the AID
app's return push through two thin adapters: TRC by command_id, Loop by
sync_identifier. Loop carb delete/edit require LoopFollow's return
credentials, like Trio, since the push is the only confirmation.

The detail view reads busy / failure message from the tracker and dismisses
on a success transition it observes itself, so a terminal state left from
an earlier visit never dismisses a freshly opened view.
An FPU child row offers Edit only when its root meal is loaded; the edit
sheet is then prefilled with the root's macros and time and addresses the
root's id. Delete stays available for every child and targets the whole
meal. The view model builds the fpuID → root lookup once per regroup.
A Nightscout carb document from Trio is an FPU child exactly when its
fpuID equals its id; a document without fpuID is a root meal.
Carbs, bolus, carb delete and carb edit share commandHeader for the otp,
remote-address, notes, entered-by, sent-at, expiration and alert fields.
The builders are static and take the send time, so tests pin the exact
key set and values of each payload.

A carb edit always carries carbs-edit-entry, carbs-edit-absorption-time
and carbs-edit-start-time; carbs-edit-food-type is sent only when set.
LabeledValueRow renders the label/value rows in the treatment detail
sections and both edit sheets. A Trio meal without carbs is listed as
"Meal" with its fat and protein grams as subtitle. When Trio Remote
Control is active but the Trio build's profile does not advertise the
meal commands, the Meal section footer says a newer Trio version is
needed.
A patched Loop lists carbs-delete and carbs-edit under
loop.testingDetails.remoteCommands in every devicestatus upload.
DeviceStatusLoop stores that list in loopRemoteCommands, clearing it
when the key is absent, and the treatment detail offers the Loop carb
remote actions only when both commands are advertised. With Loop APNS
active but the commands missing, the carb entry section explains that
the remote carb edit customization is needed.
* Add ability to double-click carbs to enter Treatments screen

* Keep the carb detail sheet across remounts and share carb treatment construction (#758)

* Share carb Treatment construction and root-meal lookup

Treatment.carb builds a carb entry for both the treatments list and the
chart's detail sheet, with one id fallback for entries without a
Nightscout _id. Treatment.rootMealsByFPUID and rootMeal(in:) back the
FPU-child root lookup in both places.

* Refresh treatments when a remote meal command completes

The chart's carb marks follow a remote meal edit or delete from any
screen by running the treatments task as soon as the command resolves.

* Keep the carb detail sheet in the chart shell

BGChartView owns the selected carb and its sheet, outside the subtree
that is remounted on foregrounding, so an open sheet survives a trip to
Notification Center or the background. Double-tap hit-tests carb marks
only, so a nearby bolus cannot shadow the carb it sits next to.

---------

Co-authored-by: Jonas Björkert <jonas@bjorkert.se>
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.

2 participants