Check the playlist inbox when the app returns to the foreground and every two minutes while open

Sent playlists were only picked up on a cold start, so an installed PWA
resumed from the background never showed them.
This commit is contained in:
Jonathan Sykes
2026-09-18 09:28:01 +08:00
parent e4ac04cb5c
commit 64f45a102d

View File

@@ -562,7 +562,7 @@ function showSharedPlaylistModal(name, url, code) {
msg.textContent = '\u26a0 ' + ((j && j.error) || 'Could not send');
} else {
msg.className = 'share-send-msg ok';
msg.textContent = `Sent to \u201c${to}\u201d \u2014 they'll see it next time they open YT Player.`;
msg.textContent = `Sent to \u201c${to}\u201d \u2014 they'll get it the next time YT Player is open on their device.`;
input.value = '';
}
} catch {
@@ -727,10 +727,43 @@ async function adoptSharedPlaylistByCode(code, { fromName = '' } = {}) {
// Playlists other users sent to this device's linked profile. Offered one at a
// time on launch; each is cleared from the server inbox once answered, whether
// the user kept it or not, so it is never offered twice.
//
// Launch alone is not enough: an installed PWA is usually resumed from the
// background rather than relaunched, so it also re-checks when it returns to
// the foreground and on a timer while visible (see startPlaylistInboxWatch).
let inboxCheckRunning = false;
let inboxLastCheck = 0;
async function checkPlaylistInbox() {
if (!WEB) return;
if (!WEB || inboxCheckRunning) return;
const me = data.profile && data.profile.name;
if (!me) return; // deliveries are addressed to a profile, not a device
inboxCheckRunning = true;
inboxLastCheck = Date.now();
try {
await drainPlaylistInbox(me);
} finally {
inboxCheckRunning = false;
}
}
const INBOX_POLL_MS = 2 * 60 * 1000;
const INBOX_MIN_GAP_MS = 20 * 1000;
function startPlaylistInboxWatch() {
if (!WEB) return;
const maybeCheck = () => {
if (document.visibilityState !== 'visible') return;
if (Date.now() - inboxLastCheck < INBOX_MIN_GAP_MS) return;
// Never pop the prompt over a dialog the user is already in.
const modal = $('modal');
if (modal && !modal.classList.contains('hidden')) return;
checkPlaylistInbox();
};
document.addEventListener('visibilitychange', maybeCheck);
window.addEventListener('focus', maybeCheck);
setInterval(maybeCheck, INBOX_POLL_MS);
}
async function drainPlaylistInbox(me) {
let items = [];
try {
@@ -5356,6 +5389,7 @@ async function boot() {
// After the profile is settled — a delivery is addressed to the profile, so
// this must run once we know which one (if any) this device is linked to.
await checkPlaylistInbox();
startPlaylistInboxWatch();
applyAppearance();
updateProfileStatus();
updateLoopRepeatButtons();