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:
@@ -562,7 +562,7 @@ function showSharedPlaylistModal(name, url, code) {
|
|||||||
msg.textContent = '\u26a0 ' + ((j && j.error) || 'Could not send');
|
msg.textContent = '\u26a0 ' + ((j && j.error) || 'Could not send');
|
||||||
} else {
|
} else {
|
||||||
msg.className = 'share-send-msg ok';
|
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 = '';
|
input.value = '';
|
||||||
}
|
}
|
||||||
} catch {
|
} catch {
|
||||||
@@ -727,10 +727,43 @@ async function adoptSharedPlaylistByCode(code, { fromName = '' } = {}) {
|
|||||||
// Playlists other users sent to this device's linked profile. Offered one at a
|
// 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
|
// 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.
|
// 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() {
|
async function checkPlaylistInbox() {
|
||||||
if (!WEB) return;
|
if (!WEB || inboxCheckRunning) return;
|
||||||
const me = data.profile && data.profile.name;
|
const me = data.profile && data.profile.name;
|
||||||
if (!me) return; // deliveries are addressed to a profile, not a device
|
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 = [];
|
let items = [];
|
||||||
try {
|
try {
|
||||||
@@ -5356,6 +5389,7 @@ async function boot() {
|
|||||||
// After the profile is settled — a delivery is addressed to the profile, so
|
// 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.
|
// this must run once we know which one (if any) this device is linked to.
|
||||||
await checkPlaylistInbox();
|
await checkPlaylistInbox();
|
||||||
|
startPlaylistInboxWatch();
|
||||||
applyAppearance();
|
applyAppearance();
|
||||||
updateProfileStatus();
|
updateProfileStatus();
|
||||||
updateLoopRepeatButtons();
|
updateLoopRepeatButtons();
|
||||||
|
|||||||
Reference in New Issue
Block a user