Siri: App Intents with phrases that need no setup: Resume, Pause, Skip forward, Skip back, Set a sleep timer, How many unread. The playback ones are AudioPlaybackIntents, run in the app and allowed to start audio from the background. Playback is now one shared instance (Playback.shared) so Siri and the widget reach it with no page loaded. It remembers the last episode and its place (LastPlayed), so Resume works with the app closed; the page, opened afterwards, does not know about an episode started that way. Widget: small and medium on the home screen, circular and rectangular on the lock screen. It shows the unread count and the last episode, with a Resume or Pause button (PlayPauseIntent, shared with Siri). It draws what the app writes to the App Group group.net.sdf1.ipx. The app asks for a redraw on play, pause, a new episode or a new count, not on every position, since iOS rations redraws. Shared/ builds into both targets, with WIDGET set in the widget's, where the player does not exist. ipx's push now carries content-available, which wakes the closed app for a moment to give the widget the count the icon just got (#433). Tested: unit tests for the snapshot and the remembered place, 19 in all; in the simulator, playing an episode wrote the snapshot to the App Group. Not testable there: Siri, and the widget drawn. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -14,7 +14,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
|
||||
### Added
|
||||
|
||||
- The iOS app's icon count stays right with the app closed: with `[push]` set to an APNs key, ipx sends each registered phone (`POST /api/push/devices`, removed with `DELETE`) its All Subscriptions unread count through Apple's push service, within a minute of a change (#433).
|
||||
- The iOS app's icon count stays right with the app closed: with `[push]` set to an APNs key, ipx sends each registered phone (`POST /api/push/devices`, removed with `DELETE`) its All Subscriptions unread count through Apple's push service, within a minute of a change (#433). The push also wakes the app for a moment, for its widget to show the same count (#428).
|
||||
- A place in an episode saved from DeadAir's shortened version names its file (`deadair` in `POST .../position`), so it is read in that version's clock even when ipx never handed out its playlist, as for a copy kept on the device or after a restart (#412).
|
||||
- `/api/art` also serves the pictures in the text of items iPX has sent, through its artwork cache, so the page can keep them to read offline (#389).
|
||||
- The log has a line for each swipe in the page's reader, saying what came of it and where the reader stood, and a warning when a drag would not scroll the reader, with what lay over it (#384).
|
||||
|
||||
@@ -99,7 +99,10 @@ async fn send(ctx: &Ctx, signer: &mut Signer, d: &push_devices::Model, n: i64) -
|
||||
.header("apns-push-type", "alert")
|
||||
// Not urgent, so iOS may hold it to save the battery.
|
||||
.header("apns-priority", "5")
|
||||
.json(&serde_json::json!({ "aps": { "badge": n } }))
|
||||
// content-available wakes the app for a moment, which the badge alone does not, so its
|
||||
// widget's count follows the icon's (#428). iOS rations those wakes; the badge is set
|
||||
// whether or not one comes.
|
||||
.json(&serde_json::json!({ "aps": { "badge": n, "content-available": 1 } }))
|
||||
.send()
|
||||
.await
|
||||
.context("reaching Apple's push service")?;
|
||||
|
||||
Reference in New Issue
Block a user