Mark episodes read when finished, not when started
play() set read=1 the instant playback began. The default view is the Unread tab, so pressing play removed the episode from the list being looked at, which reads as the episode going missing. All four affected rows had position=0: started, never listened to. Read is now set on 'ended' or past 90% of the duration. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RPyeapneuXrCdojsaiXGbe
This commit is contained in:
@@ -495,7 +495,20 @@ async function epAction(a,e,el){
|
||||
|
||||
/* ---------------- player ---------------- */
|
||||
const audio=$('#audio');
|
||||
const player={guid:null,feed:null,entry:null,saveAt:0};
|
||||
const player={guid:null,feed:null,entry:null,saveAt:0,marked:false};
|
||||
|
||||
// Marked read when an episode has actually been listened to -- at the end, or past 90%.
|
||||
// NOT on play: doing that made the episode vanish from the default Unread list the instant
|
||||
// you pressed play, which looks exactly like it went missing.
|
||||
function markPlayed(){
|
||||
if(!player.guid||player.marked) return;
|
||||
player.marked=true;
|
||||
const e=player.entry;
|
||||
if(!e||e.read) return;
|
||||
e.read=true;
|
||||
api(`/api/entries/${encodeURIComponent(e.feed_id)}/${encodeURIComponent(e.guid)}/flags`,
|
||||
{method:'POST',body:JSON.stringify({read:true})}).then(()=>loadFeeds(true)).catch(()=>{});
|
||||
}
|
||||
|
||||
function play(e){
|
||||
const enc=e.enclosures.find(x=>x.path);
|
||||
@@ -512,10 +525,7 @@ function play(e){
|
||||
$('#pfeed').textContent=f?(f.title||f.id):'';
|
||||
$('#player').classList.add('on');
|
||||
mediaSession(e,f);
|
||||
// Playing it is the clearest signal it has been listened to; retention deletes
|
||||
// read episodes before unread ones.
|
||||
if(!e.read){ e.read=true; api(`/api/entries/${encodeURIComponent(e.feed_id)}/${encodeURIComponent(e.guid)}/flags`,
|
||||
{method:'POST',body:JSON.stringify({read:true})}).then(()=>loadFeeds(true)); }
|
||||
player.marked=false;
|
||||
}
|
||||
audio.play().catch(err=>toast('Playback failed: '+err.message,true));
|
||||
renderEntries();
|
||||
@@ -537,6 +547,7 @@ audio.addEventListener('timeupdate',()=>{
|
||||
if(d) $('#seek').value=String(Math.round(audio.currentTime/d*1000));
|
||||
// Persist roughly every 10s so a reload resumes where you were.
|
||||
if(player.guid && audio.currentTime-player.saveAt>10){ savePos(); }
|
||||
if(d && audio.currentTime/d >= 0.9) markPlayed();
|
||||
});
|
||||
function savePos(){
|
||||
if(!player.guid) return;
|
||||
@@ -547,7 +558,7 @@ function savePos(){
|
||||
new Blob([JSON.stringify({secs:Math.floor(audio.currentTime)})],{type:'application/json'}));
|
||||
}
|
||||
audio.addEventListener('pause',savePos);
|
||||
audio.addEventListener('ended',()=>{savePos();$('#pplay').textContent='▶'});
|
||||
audio.addEventListener('ended',()=>{savePos();markPlayed();$('#pplay').textContent='▶'});
|
||||
audio.addEventListener('play',()=>$('#pplay').textContent='❚❚');
|
||||
audio.addEventListener('pause',()=>$('#pplay').textContent='▶');
|
||||
window.addEventListener('beforeunload',savePos);
|
||||
|
||||
Reference in New Issue
Block a user