29 lines
1.4 KiB
JavaScript
29 lines
1.4 KiB
JavaScript
(function(root) {
|
||
'use strict';
|
||
function cardsFor(cards, id) {
|
||
const seen = new Set([id]);
|
||
return (Array.isArray(cards) ? cards : []).filter(card => {
|
||
if (!card?.id || !card.title || seen.has(card.id)) return false;
|
||
seen.add(card.id); return true;
|
||
}).slice(0, 8);
|
||
}
|
||
function createLoader({ fetchRelated, update }) {
|
||
let serial = 0;
|
||
return async function load(meta, { refresh = false } = {}) {
|
||
const request = ++serial, snapshot = { ...meta };
|
||
update({ id: snapshot.id, status: 'loading', cards: [], message: 'Finding related videos…' });
|
||
let state;
|
||
try {
|
||
const result = await fetchRelated(snapshot, { refresh });
|
||
const cards = cardsFor(result?.results, snapshot.id);
|
||
state = result?.ok && cards.length ? { id: snapshot.id, status: 'ready', cards, message: result.message || '' }
|
||
: { id: snapshot.id, status: 'error', cards: [], message: 'Related videos aren’t available right now. Please try again.', detail: result?.detail || result?.error || '' };
|
||
} catch (error) { state = { id: snapshot.id, status: 'error', cards: [], message: 'Related videos aren’t available right now. Please try again.', detail: error.message || '' }; }
|
||
if (request === serial) update(state);
|
||
return state;
|
||
};
|
||
}
|
||
const api = { cardsFor, createLoader };
|
||
if (typeof module !== 'undefined' && module.exports) module.exports = api; else root.RelatedVideos = api;
|
||
})(globalThis);
|