A spinner after pulling to refresh (#68)
Letting go of a pull removed its note at once and showed nothing else; the sidebar's scanning spinner is hidden on a phone. With no sign the check had started, people pulled again, and again. A "Checking for new items" pill with a spinner now sits under the top bar until the request is sent and two seconds have passed, and a pull meanwhile does nothing. It lives outside #list, which a feed's render rebuilds. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -689,6 +689,12 @@ input:focus,select:focus{outline:0;border-color:var(--accent)}
|
||||
reloads the page, from starting on top of it. */
|
||||
#pulltip{display:flex;align-items:flex-end;justify-content:center;padding-bottom:6px;overflow:hidden;
|
||||
font-size:12px;color:var(--faint)}
|
||||
/* What a pull started, for a couple of seconds after letting go, under the top bar. */
|
||||
#pullspin{position:fixed;left:50%;top:calc(58px + var(--safe-t));transform:translateX(-50%);z-index:55;
|
||||
display:flex;align-items:center;gap:8px;padding:6px 12px;border-radius:999px;font-size:12px;
|
||||
color:var(--dim);background:var(--panel);border:1px solid var(--line);box-shadow:var(--shadow)}
|
||||
#pullspin::before{content:"";width:12px;height:12px;border-radius:50%;
|
||||
border:2px solid var(--line);border-top-color:var(--accent);animation:ipxspin .8s linear infinite}
|
||||
/* The selected item's files, beside the list, as the original's Files pane was. */
|
||||
#files{grid-area:files;overflow-y:auto;padding:8px 12px;border-left:1px solid var(--line);background:var(--panel)}
|
||||
/* Nothing selected, or an item with no files: the list takes the width. */
|
||||
|
||||
@@ -36,13 +36,25 @@ function pullShow(dy: number){
|
||||
tip.textContent = dy >= PULL ? 'Release to check for new items' : 'Pull to check for new items';
|
||||
}
|
||||
|
||||
/// A check started by a pull, while its spinner is up. Letting go showed nothing before (issue
|
||||
/// #68), the sidebar's spinner is hidden on a phone, and people pulled again and again.
|
||||
let refreshing = false;
|
||||
|
||||
function refreshFeed(){
|
||||
const f = S.feeds.find(x => x.id === S.feed);
|
||||
if(!f && S.feed !== ':all') return;
|
||||
if(refreshing) return;
|
||||
refreshing = true;
|
||||
// Outside #list, which a feed's render rebuilds and would take the spinner with it.
|
||||
const spin = document.createElement('div');
|
||||
spin.id = 'pullspin'; spin.setAttribute('role', 'status'); spin.textContent = 'Checking for new items';
|
||||
document.body.append(spin);
|
||||
// New items arrive by the event stream when the scan finishes, as they do for a button press.
|
||||
api('/api/fetch', {method: 'POST', body: JSON.stringify(f ? {feed: f.id, force: true} : {force: true})})
|
||||
const asked = api('/api/fetch', {method: 'POST', body: JSON.stringify(f ? {feed: f.id, force: true} : {force: true})})
|
||||
.catch(e => toast(e.message, true));
|
||||
loadEntries();
|
||||
// Up for two seconds at least, so it is seen even when the server answers at once.
|
||||
Promise.all([asked, new Promise(r => setTimeout(r, 2000))]).then(() => { spin.remove(); refreshing = false; });
|
||||
}
|
||||
|
||||
document.addEventListener('touchstart', ev => {
|
||||
|
||||
Reference in New Issue
Block a user