diff --git a/src/lib/api.js b/src/lib/api.js index 4c8c38c..812ddd0 100644 --- a/src/lib/api.js +++ b/src/lib/api.js @@ -2,6 +2,31 @@ const errors = { AUTHENTICATION_FAILED: "AUTHENTICATION_FAILED", }; +/** + * Parses a HTTP Link header + * @param {string} header - the HTTP Link header string + */ +function _parseLinkHeader(header) { + // remove whitespace and split + let links = header.replace(/\ /g, "").split(","); + + return links.map(l => { + let parts = l.split(";"); + + // assuming 0th is URL, removing <> + let url = new URL(parts[0].slice(1, -1)); + + // get rel inbetween double-quotes + let rel = parts[1].match(/"(.*?)"/g)[0].slice(1, -1); + + return { + url, rel + } + }) +} + +_parseLinkHeader(`; rel="next", ; rel="prev"`) + /** * GET /api/v1/instance * @param {string} host - The domain of the target server. @@ -258,9 +283,43 @@ export async function getTimeline(host, token, timeline, max_id, local_only, rem const data = await fetch(url, { method: 'GET', headers: { "Authorization": token ? `Bearer ${token}` : null } - }).then(res => res.json()); + }) - return data; + let links = _parseLinkHeader(data.headers.get("Link")); + + return { + data: await data.json(), + prev: links.find(f=>f.rel=="prev"), + next: links.find(f=>f.rel=="next") + }; +} + +/** + * GET /api/v1/favourites + * @param {string} host - The domain of the target server. + * @param {string} token - The application token. + * @param {string} max_id - If provided, only shows posts after this ID. + */ +export async function getFavourites(host, token, max_id) { + let url = `https://${host}/api/v1/favourites`; + + let params = new URLSearchParams(); + if (max_id) params.append("max_id", max_id); + const params_string = params.toString(); + if (params_string) url += '?' + params_string; + + const data = await fetch(url, { + method: 'GET', + headers: { "Authorization": token ? `Bearer ${token}` : null } + }) + + let links = _parseLinkHeader(data.headers.get("Link")); + + return { + data: await data.json(), + prev: links.find(f=>f.rel=="prev"), + next: links.find(f=>f.rel=="next") + }; } /** @@ -559,26 +618,4 @@ export async function getUserPinnedPosts(host, token, user_id) { }).then(res => res.json()); return data; -} - -/** - * GET /api/v1/favourites - * @param {string} host - The domain of the target server. - * @param {string} token - The application token. - * @param {string} max_id - If provided, only shows posts after this ID. - */ -export async function getFavourites(host, token, timeline, max_id) { - let url = `https://${host}/api/v1/favourites`; - - let params = new URLSearchParams(); - if (max_id) params.append("max_id", max_id); - const params_string = params.toString(); - if (params_string) url += '?' + params_string; - - const data = await fetch(url, { - method: 'GET', - headers: { "Authorization": token ? `Bearer ${token}` : null } - }).then(res => res.json()); - - return data; -} +} \ No newline at end of file diff --git a/src/lib/timeline.js b/src/lib/timeline.js index 0f54e91..6b6050f 100644 --- a/src/lib/timeline.js +++ b/src/lib/timeline.js @@ -10,14 +10,14 @@ export const timeline = writable([]); const lang = Lang(); let loading = false; +let last_post = false; export async function getTimeline(timelineType = "home", clean, localOnly = false, remoteOnly = false) { if (loading) return; // no spamming!! loading = true; - let last_post = false; - if (!clean && get(timeline).length > 0) - last_post = get(timeline)[get(timeline).length - 1].id; + // if (!clean && get(timeline).length > 0) + // last_post = get(timeline)[get(timeline).length - 1].id; let timeline_data; switch(timelineType) { @@ -25,7 +25,7 @@ export async function getTimeline(timelineType = "home", clean, localOnly = fals timeline_data = await api.getFavourites( get(server).host, get(app).token, - last_post, + last_post ) break; @@ -47,10 +47,15 @@ export async function getTimeline(timelineType = "home", clean, localOnly = fals return; } - if (clean) timeline.set([]); + if (clean) { + timeline.set([]); + last_post = false; + } else { + last_post = timeline_data.next.url.searchParams.get("max_id") + } - for (let i in timeline_data) { - const post_data = timeline_data[i]; + for (let i in timeline_data.data) { + const post_data = timeline_data.data[i]; const post = await parsePost(post_data, 1); if (!post) { if (post === null || post === undefined) {