Compare commits
3 commits
389f8dcaff
...
4bad86822f
Author | SHA1 | Date | |
---|---|---|---|
4bad86822f | |||
19be3779e3 | |||
cd5dc461f6 |
5 changed files with 116 additions and 62 deletions
|
@ -41,7 +41,7 @@ export function parseAccount(data) {
|
||||||
else
|
else
|
||||||
account.host = get(server).host;
|
account.host = get(server).host;
|
||||||
|
|
||||||
account.fqn = data.fqn || account.username + account.host;
|
account.fqn = data.fqn || account.username + "@" + account.host;
|
||||||
|
|
||||||
account.mention = "@" + account.username;
|
account.mention = "@" + account.username;
|
||||||
if (account.host != get(server).host)
|
if (account.host != get(server).host)
|
||||||
|
|
|
@ -285,13 +285,17 @@ export async function getTimeline(host, token, timeline, max_id, local_only, rem
|
||||||
headers: { "Authorization": token ? `Bearer ${token}` : null }
|
headers: { "Authorization": token ? `Bearer ${token}` : null }
|
||||||
})
|
})
|
||||||
|
|
||||||
let links = _parseLinkHeader(data.headers.get("Link"));
|
let res = {
|
||||||
|
data: await data.json()
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
if(data.headers.has("Link")) {
|
||||||
data: await data.json(),
|
let links = _parseLinkHeader(data.headers.get("Link"));
|
||||||
prev: links.find(f=>f.rel=="prev"),
|
res["prev"] = links.find(f=>f.rel=="prev");
|
||||||
next: links.find(f=>f.rel=="next")
|
res["next"] = links.find(f=>f.rel=="next");
|
||||||
};
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -312,14 +316,18 @@ export async function getFavourites(host, token, max_id) {
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
headers: { "Authorization": token ? `Bearer ${token}` : null }
|
headers: { "Authorization": token ? `Bearer ${token}` : null }
|
||||||
})
|
})
|
||||||
|
|
||||||
|
let res = {
|
||||||
|
data: await data.json()
|
||||||
|
}
|
||||||
|
|
||||||
let links = _parseLinkHeader(data.headers.get("Link"));
|
if(data.headers.has("Link")) {
|
||||||
|
let links = _parseLinkHeader(data.headers.get("Link"));
|
||||||
|
res["prev"] = links.find(f=>f.rel=="prev");
|
||||||
|
res["next"] = links.find(f=>f.rel=="next");
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return res;
|
||||||
data: await data.json(),
|
|
||||||
prev: links.find(f=>f.rel=="prev"),
|
|
||||||
next: links.find(f=>f.rel=="next")
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -10,12 +10,15 @@ export const timeline = writable([]);
|
||||||
const lang = Lang();
|
const lang = Lang();
|
||||||
|
|
||||||
let loading = false;
|
let loading = false;
|
||||||
let last_post = false;
|
let last_post = false; // last post marker, used for fetching next sequence of posts
|
||||||
|
let at_end = false; // at end of timeline, no next param to paginate
|
||||||
|
|
||||||
export async function getTimeline(timelineType = "home", clean, localOnly = false, remoteOnly = false) {
|
export async function getTimeline(timelineType = "home", clean, localOnly = false, remoteOnly = false) {
|
||||||
if (loading) return; // no spamming!!
|
if (loading) return; // no spamming!!
|
||||||
loading = true;
|
loading = true;
|
||||||
|
|
||||||
|
if(at_end) return;
|
||||||
|
|
||||||
if(clean) {
|
if(clean) {
|
||||||
timeline.set([]);
|
timeline.set([]);
|
||||||
last_post = false;
|
last_post = false;
|
||||||
|
@ -49,9 +52,12 @@ export async function getTimeline(timelineType = "home", clean, localOnly = fals
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!clean) {
|
if (!clean && timeline_data.next) {
|
||||||
last_post = timeline_data.next.url.searchParams.get("max_id")
|
last_post = timeline_data.next.url.searchParams.get("max_id")
|
||||||
}
|
} else if(!timeline_data.next) {
|
||||||
|
console.log(timeline_data)
|
||||||
|
at_end = true;
|
||||||
|
}
|
||||||
|
|
||||||
for (let i in timeline_data.data) {
|
for (let i in timeline_data.data) {
|
||||||
const post_data = timeline_data.data[i];
|
const post_data = timeline_data.data[i];
|
||||||
|
@ -71,3 +77,9 @@ export async function getTimeline(timelineType = "home", clean, localOnly = fals
|
||||||
}
|
}
|
||||||
loading = false;
|
loading = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function clearTimeline() {
|
||||||
|
timeline.set([]);
|
||||||
|
last_post = false;
|
||||||
|
at_end = false;
|
||||||
|
}
|
78
src/lib/ui/timeline/Timeline.svelte
Normal file
78
src/lib/ui/timeline/Timeline.svelte
Normal file
|
@ -0,0 +1,78 @@
|
||||||
|
<script>
|
||||||
|
import { page } from '$app/stores';
|
||||||
|
import { account } from '$lib/stores/account.js';
|
||||||
|
import { timeline, getTimeline, clearTimeline } from '$lib/timeline.js';
|
||||||
|
import { app_name } from '$lib/config.js';
|
||||||
|
import Post from '$lib/ui/post/Post.svelte';
|
||||||
|
|
||||||
|
import Lang from '$lib/lang';
|
||||||
|
const lang = Lang();
|
||||||
|
|
||||||
|
// TODO: refactor to enum when moving to TS
|
||||||
|
export let timelineType;
|
||||||
|
|
||||||
|
$: {
|
||||||
|
// awful hack to update timeline fresh
|
||||||
|
// when timelineType is updated
|
||||||
|
//
|
||||||
|
// TODO: migrate to $effect when migrating to svelte 5
|
||||||
|
timelineType = timelineType
|
||||||
|
|
||||||
|
clearTimeline()
|
||||||
|
getCurrentTimeline()
|
||||||
|
}
|
||||||
|
|
||||||
|
function getCurrentTimeline(clean = false) {
|
||||||
|
switch(timelineType) {
|
||||||
|
case "home":
|
||||||
|
getTimeline("home", clean);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "local":
|
||||||
|
getTimeline("public", clean, true)
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "federated":
|
||||||
|
getTimeline("public", clean, false, true)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
account.subscribe(account => {
|
||||||
|
if (account) getCurrentTimeline();
|
||||||
|
});
|
||||||
|
|
||||||
|
document.addEventListener('scroll', () => {
|
||||||
|
if ($account && $page.url.pathname !== "/") return;
|
||||||
|
if (window.innerHeight + window.scrollY >= document.body.offsetHeight - 2048) {
|
||||||
|
getCurrentTimeline();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
<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>
|
||||||
|
|
||||||
|
|
||||||
|
<style>
|
||||||
|
#feed {
|
||||||
|
margin-bottom: 20vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
.loading {
|
||||||
|
width: 100%;
|
||||||
|
height: 80vh;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
font-size: 2em;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -9,6 +9,7 @@
|
||||||
import Button from '$lib/ui/Button.svelte';
|
import Button from '$lib/ui/Button.svelte';
|
||||||
import Post from '$lib/ui/post/Post.svelte';
|
import Post from '$lib/ui/post/Post.svelte';
|
||||||
import PageHeader from '../lib/ui/core/PageHeader.svelte';
|
import PageHeader from '../lib/ui/core/PageHeader.svelte';
|
||||||
|
import Timeline from '../lib/ui/timeline/Timeline.svelte';
|
||||||
|
|
||||||
const lang = Lang();
|
const lang = Lang();
|
||||||
|
|
||||||
|
@ -24,40 +25,7 @@
|
||||||
|
|
||||||
// set in localStorage
|
// set in localStorage
|
||||||
localStorage.setItem(app_name + '_selected_timeline', timelineType);
|
localStorage.setItem(app_name + '_selected_timeline', timelineType);
|
||||||
|
|
||||||
// erase the timeline here so the ui reacts instantly
|
|
||||||
// mae: i could write an awesome undertale reference here
|
|
||||||
timeline.set([]);
|
|
||||||
|
|
||||||
getCurrentTimeline()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function getCurrentTimeline(clean = false) {
|
|
||||||
switch(timelineType) {
|
|
||||||
case "home":
|
|
||||||
getTimeline("home", clean);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case "local":
|
|
||||||
getTimeline("public", clean, true)
|
|
||||||
break;
|
|
||||||
|
|
||||||
case "federated":
|
|
||||||
getTimeline("public", clean, false, true)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
account.subscribe(account => {
|
|
||||||
if (account) getCurrentTimeline();
|
|
||||||
});
|
|
||||||
|
|
||||||
document.addEventListener('scroll', () => {
|
|
||||||
if ($account && $page.url.pathname !== "/") return;
|
|
||||||
if (window.innerHeight + window.scrollY >= document.body.offsetHeight - 2048) {
|
|
||||||
getCurrentTimeline();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#if $account}
|
{#if $account}
|
||||||
|
@ -79,24 +47,12 @@
|
||||||
</Button>
|
</Button>
|
||||||
</PageHeader>
|
</PageHeader>
|
||||||
|
|
||||||
<div id="feed" role="feed">
|
<Timeline timelineType={timelineType}/>
|
||||||
{#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>
|
|
||||||
{:else}
|
{:else}
|
||||||
<LoginForm />
|
<LoginForm />
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
#feed {
|
|
||||||
margin-bottom: 20vh;
|
|
||||||
}
|
|
||||||
|
|
||||||
.loading {
|
.loading {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue