feat: partial favourites

This commit is contained in:
mae taylor 2025-07-15 15:37:03 +01:00
parent c51a0b1e5d
commit 99def58c8b
Signed by: mae
GPG key ID: 3C80D76BA7A3B9BD
3 changed files with 81 additions and 8 deletions

View file

@ -242,6 +242,8 @@ export async function rejectFollowRequest(host, token, account_id) {
* @param {string} token - The application token. * @param {string} token - The application token.
* @param {string} timeline - The name of the timeline to pull (default "home"). * @param {string} timeline - The name of the timeline to pull (default "home").
* @param {string} max_id - If provided, only shows posts after this ID. * @param {string} max_id - If provided, only shows posts after this ID.
* @param {boolean} local_only - If provided, only shows posts from the local instance
* @param {boolean} remote_only - If provided, only shows posts from other instances
*/ */
export async function getTimeline(host, token, timeline, max_id, local_only, remote_only) { export async function getTimeline(host, token, timeline, max_id, local_only, remote_only) {
let url = `https://${host}/api/v1/timelines/${timeline || "home"}`; let url = `https://${host}/api/v1/timelines/${timeline || "home"}`;
@ -558,3 +560,25 @@ export async function getUserPinnedPosts(host, token, user_id) {
return data; 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;
}

View file

@ -19,14 +19,27 @@ export async function getTimeline(timelineType = "home", clean, localOnly = fals
if (!clean && get(timeline).length > 0) if (!clean && get(timeline).length > 0)
last_post = get(timeline)[get(timeline).length - 1].id; last_post = get(timeline)[get(timeline).length - 1].id;
const timeline_data = await api.getTimeline( let timeline_data;
get(server).host, switch(timelineType) {
get(app).token, case "favourites":
timelineType, timeline_data = await api.getFavourites(
last_post, get(server).host,
localOnly, get(app).token,
remoteOnly last_post,
); )
break;
default:
timeline_data = await api.getTimeline(
get(server).host,
get(app).token,
timelineType,
last_post,
localOnly,
remoteOnly
);
break;
}
if (!timeline_data) { if (!timeline_data) {
console.error(lang.string('logs.timeline_fetch_failed')); console.error(lang.string('logs.timeline_fetch_failed'));

View file

@ -0,0 +1,36 @@
<script>
import { page } from '$app/stores';
import { account } from '@cf/store/account.js';
import { timeline, getTimeline } from '$lib/timeline.js';
import Button from '@cf/ui/Button.svelte';
import Post from '@cf/ui/post/Post.svelte';
import PageHeader from '@cf/ui/core/PageHeader.svelte';
import Lang from '$lib/lang';
const lang = Lang();
if (!$account) goto("/");
getTimeline("favourites");
document.addEventListener('scroll', () => {
if ($account && $page.url.pathname !== "/favourites") return;
if (window.innerHeight + window.scrollY >= document.body.offsetHeight - 2048) {
getTimeline("favourites");
}
});
</script>
<PageHeader title={lang.string(`navigation.favourites`)}/>
<div id="feed" role="feed">
{#if $timeline.length <= 0}
<div class="loading throb">
<span>{lang.string('timeline.fetching')}</span>
</div>
{/if}
{#each $timeline as post}
<Post post_data={post} />
{/each}
</div>