iOS: the icon's count follows the page's (#421)
Reported: the unread count on the icon only changed when the app was
opened. Two reasons:
- Items read in the page never reached it, since only the player's own
mark-read refreshed the badge.
- The background refresh that should bring new items runs when iOS
chooses, which for this app has been rarely.
The page now sends All Subscriptions' count ({t:"unread", n}) each time
its list is drawn with a new one, so reading, and new items arriving
over the event stream while the app is open, set it at once. While an
episode plays the app is awake with the screen locked, so the player's
tick also re-checks every quarter of an hour.
With the app closed and nothing playing, the count still waits on iOS's
refresh. Push (#433) is what makes that exact.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -13,6 +13,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
|
||||
### Added
|
||||
|
||||
- In the iOS app, the icon's unread count follows the page's: reading and new items change it at once, not the next time the app is opened (#421).
|
||||
- In the iOS app, presses are felt: play, pause, flag, pull to refresh, marking read and errors each give the phone's haptic for it (#430).
|
||||
- A sleep timer in the player: 5 minutes to an hour, then playback fades out and pauses. In the iOS app the phone keeps the time, so it works with the screen locked; the app and Safari also get an AirPlay button. On a phone the title has the player's top line to itself, with the controls either side of play below it (#429).
|
||||
- In the iOS app, Keep on this device keeps the episode on the phone, where the app's own player plays it with no connection; until now the app had no Keep button (#425).
|
||||
|
||||
@@ -108,6 +108,7 @@ function renderFeeds(){
|
||||
for(const img of $$<HTMLImageElement>('img',list)){ const k=img.outerHTML; if(!drawn.has(k)) drawn.set(k,[]); drawn.get(k)!.push(img); }
|
||||
list.innerHTML='';
|
||||
const unreadAll=unreadInAll();
|
||||
hostBadge(unreadAll);
|
||||
const places=document.createElement('div');
|
||||
places.className='places';
|
||||
for(const [id,v] of Object.entries(VIEWS)){
|
||||
|
||||
@@ -25,6 +25,15 @@ const ipxHost: ((m: any) => void) | null = (() => {
|
||||
|
||||
if (ipxHost) installNativePlayback();
|
||||
|
||||
/// All Subscriptions' unread count, for the app's icon (#421), each time the list is drawn with a
|
||||
/// new one: items read in the page and new ones arriving set it at once, where the app's own fetch
|
||||
/// waited for the app to come forward again.
|
||||
let badgeSent=-1;
|
||||
function hostBadge(n: number){
|
||||
// As haptic: the list can be drawn before this file has declared what it uses.
|
||||
try{ if(n!==badgeSent){ badgeSent=n; ipxHost?.({t:'unread', n}); } }catch{}
|
||||
}
|
||||
|
||||
/// A press felt as well as seen, in the app (#430): the phone's haptics, which a page cannot reach.
|
||||
/// `tap` for play, pause and the like, `done` for something finished (marked read), `warn` for an
|
||||
/// error. An app without them ignores the message; a browser has no host to send it to.
|
||||
|
||||
Reference in New Issue
Block a user