diff --git a/web/boneyard.config.json b/web/boneyard.config.json
index c317709c6..2aa04a428 100644
--- a/web/boneyard.config.json
+++ b/web/boneyard.config.json
@@ -1,5 +1,10 @@
{
- "breakpoints": [375, 768, 1024, 1440],
+ "breakpoints": [
+ 375,
+ 768,
+ 1024,
+ 1440
+ ],
"out": "./src/lib/bones",
"wait": 100,
"animate": "pulse",
@@ -109,6 +114,9 @@
"repo-treeview--skeleton-fixture": {
"route": "/iframe.html?id=repo-treeview--skeleton-fixture&viewMode=story"
},
+ "timeline-timeline--skeleton-fixture": {
+ "route": "/iframe.html?id=timeline-timeline--skeleton-fixture&viewMode=story"
+ },
"settings-settingspanel--content-skeleton-fixture": {
"route": "/iframe.html?id=settings-settingspanel--content-skeleton-fixture&viewMode=story"
},
diff --git a/web/src/lib/bones/timeline-timeline--skeleton-fixture.bones.json b/web/src/lib/bones/timeline-timeline--skeleton-fixture.bones.json
new file mode 100644
index 000000000..e9a042731
--- /dev/null
+++ b/web/src/lib/bones/timeline-timeline--skeleton-fixture.bones.json
@@ -0,0 +1,200 @@
+{
+ "breakpoints": {
+ "375": {
+ "name": "timeline-timeline--skeleton-fixture",
+ "viewportWidth": 343,
+ "width": 343,
+ "height": 866,
+ "bones": [
+ [0, 0, 100, 184, 4, true, 15, true],
+ [0.2915, 1, 99.4169, 49, 0, true, 4, false],
+ [7.2886, 13, 29.8925, 24, 4],
+ [39.5135, 17, 24.4124, 17, 4],
+ [66.2582, 17, 16.4677, 17, 4],
+ [4.9563, 70, 38.9668, 21, 4],
+ [4.9563, 97, 87.2267, 15, 4],
+ [4.9563, 117, 20.2259, 15, 4],
+ [4.9563, 147, 9.4479, 20, 4],
+ [9.3294, 184, 0.5831, 16, 0],
+ [0, 200, 100, 213, 4, true, 15, true],
+ [0.2915, 201, 99.4169, 78, 0, true, 4, false],
+ [7.2886, 213, 31.1224, 24, 4],
+ [40.7434, 217, 13.7527, 17, 4],
+ [56.8285, 217, 32.1201, 17, 4],
+ [7.2886, 247, 16.4677, 17, 4],
+ [4.9563, 299, 38.9668, 21, 4],
+ [4.9563, 326, 87.2267, 15, 4],
+ [4.9563, 346, 20.2259, 15, 4],
+ [4.9563, 376, 9.4479, 20, 4],
+ [9.3294, 413, 0.5831, 16, 0],
+ [0, 429, 100, 208, 4, true, 15, true],
+ [0.2915, 430, 99.4169, 78, 0, true, 4, false],
+ [7.2886, 442, 31.1224, 24, 4],
+ [40.7434, 446, 16.5497, 17, 4],
+ [59.6255, 442, 27.633, 24, 4],
+ [7.2886, 476, 16.4677, 17, 4],
+ [4.9563, 524, 27.9883, 96, "50%"],
+ [37.6093, 545, 19.6747, 17, 4],
+ [37.6093, 572, 62.3907, 21, 4],
+ [9.3294, 637, 0.5831, 16, 0],
+ [0, 653, 100, 213, 4, true, 15, true],
+ [0.2915, 654, 99.4169, 78, 0, true, 4, false],
+ [7.2886, 666, 29.8925, 24, 4],
+ [39.5135, 670, 12.4681, 17, 4],
+ [54.314, 670, 32.1201, 17, 4],
+ [88.7664, 670, 3.7445, 17, 4],
+ [7.2886, 700, 18.955, 17, 4],
+ [28.576, 700, 16.4677, 17, 4],
+ [4.9563, 752, 49.4397, 21, 4],
+ [4.9563, 779, 87.2267, 15, 4],
+ [4.9563, 799, 20.2259, 15, 4],
+ [4.9563, 829, 9.4479, 20, 4]
+ ]
+ },
+ "768": {
+ "name": "timeline-timeline--skeleton-fixture",
+ "viewportWidth": 736,
+ "width": 736,
+ "height": 764,
+ "bones": [
+ [0, 0, 100, 179, 4, true, 15, true],
+ [0.1359, 1, 99.7283, 49, 0, true, 4, false],
+ [3.3967, 13, 13.9309, 24, 4],
+ [18.4146, 17, 11.377, 17, 4],
+ [30.8785, 17, 7.6745, 17, 4],
+ [2.3098, 70, 18.1598, 21, 4],
+ [2.3098, 97, 50.5116, 15, 4],
+ [2.3098, 142, 4.403, 20, 4],
+ [4.3478, 179, 0.2717, 16, 0],
+ [0, 195, 100, 179, 4, true, 15, true],
+ [0.1359, 196, 99.7283, 49, 0, true, 4, false],
+ [3.3967, 208, 14.5041, 24, 4],
+ [18.9878, 212, 6.4092, 17, 4],
+ [26.484, 212, 14.969, 17, 4],
+ [42.5399, 212, 7.6745, 17, 4],
+ [2.3098, 265, 18.1598, 21, 4],
+ [2.3098, 292, 50.5116, 15, 4],
+ [2.3098, 337, 4.403, 20, 4],
+ [4.3478, 374, 0.2717, 16, 0],
+ [0, 390, 100, 179, 4, true, 15, true],
+ [0.1359, 391, 99.7283, 49, 0, true, 4, false],
+ [3.3967, 403, 14.5041, 24, 4],
+ [18.9878, 407, 7.7127, 17, 4],
+ [27.7874, 403, 12.8779, 24, 4],
+ [41.7523, 407, 7.6745, 17, 4],
+ [2.3098, 456, 13.0435, 96, "50%"],
+ [17.5272, 477, 9.1691, 17, 4],
+ [17.5272, 504, 29.6641, 21, 4],
+ [4.3478, 569, 0.2717, 16, 0],
+ [0, 585, 100, 179, 4, true, 15, true],
+ [0.1359, 586, 99.7283, 49, 0, true, 4, false],
+ [3.3967, 598, 13.9309, 24, 4],
+ [18.4146, 602, 5.8105, 17, 4],
+ [25.3121, 602, 14.969, 17, 4],
+ [41.368, 602, 1.7451, 17, 4],
+ [44.2001, 602, 8.8336, 17, 4],
+ [54.1207, 602, 7.6745, 17, 4],
+ [2.3098, 655, 23.0405, 21, 4],
+ [2.3098, 682, 50.5116, 15, 4],
+ [2.3098, 727, 4.403, 20, 4]
+ ]
+ },
+ "1024": {
+ "name": "timeline-timeline--skeleton-fixture",
+ "viewportWidth": 992,
+ "width": 992,
+ "height": 764,
+ "bones": [
+ [0, 0, 100, 179, 4, true, 15, true],
+ [0.1008, 1, 99.7984, 49, 0, true, 4, false],
+ [2.5202, 13, 10.3358, 24, 4],
+ [13.6624, 17, 8.441, 17, 4],
+ [22.9098, 17, 5.694, 17, 4],
+ [1.7137, 70, 13.4734, 21, 4],
+ [1.7137, 97, 37.4764, 15, 4],
+ [1.7137, 142, 3.2668, 20, 4],
+ [3.2258, 179, 0.2016, 16, 0],
+ [0, 195, 100, 179, 4, true, 15, true],
+ [0.1008, 196, 99.7984, 49, 0, true, 4, false],
+ [2.5202, 208, 10.7611, 24, 4],
+ [14.0877, 212, 4.7552, 17, 4],
+ [19.6494, 212, 11.106, 17, 4],
+ [31.5619, 212, 5.694, 17, 4],
+ [1.7137, 265, 13.4734, 21, 4],
+ [1.7137, 292, 37.4764, 15, 4],
+ [1.7137, 337, 3.2668, 20, 4],
+ [3.2258, 374, 0.2016, 16, 0],
+ [0, 390, 100, 179, 4, true, 15, true],
+ [0.1008, 391, 99.7984, 49, 0, true, 4, false],
+ [2.5202, 403, 10.7611, 24, 4],
+ [14.0877, 407, 5.7223, 17, 4],
+ [20.6165, 403, 9.5546, 24, 4],
+ [30.9775, 407, 5.694, 17, 4],
+ [1.7137, 456, 9.6774, 96, "50%"],
+ [13.004, 477, 6.8029, 17, 4],
+ [13.004, 504, 22.0089, 21, 4],
+ [3.2258, 569, 0.2016, 16, 0],
+ [0, 585, 100, 179, 4, true, 15, true],
+ [0.1008, 586, 99.7984, 49, 0, true, 4, false],
+ [2.5202, 598, 10.3358, 24, 4],
+ [13.6624, 602, 4.3111, 17, 4],
+ [18.7799, 602, 11.106, 17, 4],
+ [30.6924, 602, 1.2947, 17, 4],
+ [32.7936, 602, 6.554, 17, 4],
+ [40.154, 602, 5.694, 17, 4],
+ [1.7137, 655, 17.0946, 21, 4],
+ [1.7137, 682, 37.4764, 15, 4],
+ [1.7137, 727, 3.2668, 20, 4]
+ ]
+ },
+ "1440": {
+ "name": "timeline-timeline--skeleton-fixture",
+ "viewportWidth": 1408,
+ "width": 1408,
+ "height": 764,
+ "bones": [
+ [0, 0, 100, 179, 4, true, 15, true],
+ [0.071, 1, 99.858, 49, 0, true, 4, false],
+ [1.7756, 13, 7.282, 24, 4],
+ [9.6258, 17, 5.947, 17, 4],
+ [16.141, 17, 4.0117, 17, 4],
+ [1.2074, 70, 9.4926, 21, 4],
+ [1.2074, 97, 26.4038, 15, 4],
+ [1.2074, 142, 2.3016, 20, 4],
+ [2.2727, 179, 0.142, 16, 0],
+ [0, 195, 100, 179, 4, true, 15, true],
+ [0.071, 196, 99.858, 49, 0, true, 4, false],
+ [1.7756, 208, 7.5817, 24, 4],
+ [9.9254, 212, 3.3503, 17, 4],
+ [13.8439, 212, 7.8247, 17, 4],
+ [22.2368, 212, 4.0117, 17, 4],
+ [1.2074, 265, 9.4926, 21, 4],
+ [1.2074, 292, 26.4038, 15, 4],
+ [1.2074, 337, 2.3016, 20, 4],
+ [2.2727, 374, 0.142, 16, 0],
+ [0, 390, 100, 179, 4, true, 15, true],
+ [0.071, 391, 99.858, 49, 0, true, 4, false],
+ [1.7756, 403, 7.5817, 24, 4],
+ [9.9254, 407, 4.0316, 17, 4],
+ [14.5253, 403, 6.7316, 24, 4],
+ [21.8251, 407, 4.0117, 17, 4],
+ [1.2074, 456, 6.8182, 96, "50%"],
+ [9.1619, 477, 4.7929, 17, 4],
+ [9.1619, 504, 15.5063, 21, 4],
+ [2.2727, 569, 0.142, 16, 0],
+ [0, 585, 100, 179, 4, true, 15, true],
+ [0.071, 586, 99.858, 49, 0, true, 4, false],
+ [1.7756, 598, 7.282, 24, 4],
+ [9.6258, 602, 3.0373, 17, 4],
+ [13.2313, 602, 7.8247, 17, 4],
+ [21.6242, 602, 0.9122, 17, 4],
+ [23.1046, 602, 4.6176, 17, 4],
+ [28.2903, 602, 4.0117, 17, 4],
+ [1.2074, 655, 12.0439, 21, 4],
+ [1.2074, 682, 26.4038, 15, 4],
+ [1.2074, 727, 2.3016, 20, 4]
+ ]
+ }
+ },
+ "_hash": "f77e78fb2a1899c94148d26c3b3750a9"
+}
diff --git a/web/src/lib/components/profile/FollowCard.svelte b/web/src/lib/components/profile/FollowCard.svelte
index 1c983d44a..717408570 100644
--- a/web/src/lib/components/profile/FollowCard.svelte
+++ b/web/src/lib/components/profile/FollowCard.svelte
@@ -8,6 +8,7 @@
border = false,
shadow = false,
background = false,
+ followButton = true,
onFollow
}: {
person: PersonData;
@@ -15,9 +16,10 @@
border?: CardVariants["border"];
shadow?: CardVariants["shadow"];
background?: CardVariants["background"];
+ followButton?: boolean;
} = $props();
-
+
diff --git a/web/src/lib/components/profile/FollowCardContent.svelte b/web/src/lib/components/profile/FollowCardContent.svelte
index 8a26f584c..1569a83dd 100644
--- a/web/src/lib/components/profile/FollowCardContent.svelte
+++ b/web/src/lib/components/profile/FollowCardContent.svelte
@@ -8,8 +8,15 @@
import Separator from "$lib/components/ui/Separator.svelte";
import { formatCount } from "$lib/format";
- let { person, onFollow }: { person: PersonData; onFollow?: (change: FollowChange) => void } =
- $props();
+ let {
+ person,
+ onFollow,
+ followButton = true
+ }: {
+ person: PersonData;
+ onFollow?: (change: FollowChange) => void;
+ followButton?: boolean;
+ } = $props();
const followerCount = createOptimisticCount({
key: () => person.did,
@@ -68,7 +75,7 @@
- {#if !person.isSelf}
+ {#if !person.isSelf && followButton}
+
+
diff --git a/web/src/lib/components/timeline/Timeline.svelte b/web/src/lib/components/timeline/Timeline.svelte
index 8c5a8373e..a49542e06 100644
--- a/web/src/lib/components/timeline/Timeline.svelte
+++ b/web/src/lib/components/timeline/Timeline.svelte
@@ -7,8 +7,13 @@
let {
feed,
- emptyMessage = "Nothing here yet."
- }: { feed: ShTangledFeedGetTimeline.$output["feed"]; emptyMessage?: string } = $props();
+ emptyMessage = "Nothing here yet.",
+ signedIn = false
+ }: {
+ feed: ShTangledFeedGetTimeline.$output["feed"];
+ emptyMessage?: string;
+ signedIn?: boolean;
+ } = $props();
{#if feed.length > 0}
@@ -24,11 +29,11 @@
>
{/if}
{#if event.$type === "sh.tangled.feed.getTimeline#repoEvent"}
-
+
{:else if event.$type === "sh.tangled.feed.getTimeline#starEvent"}
-
+
{:else if event.$type === "sh.tangled.feed.getTimeline#followEvent"}
-
+
{/if}
{/each}
diff --git a/web/src/lib/components/timeline/TimelineFollowEvent.svelte b/web/src/lib/components/timeline/TimelineFollowEvent.svelte
index e95dd9491..3e01187d5 100644
--- a/web/src/lib/components/timeline/TimelineFollowEvent.svelte
+++ b/web/src/lib/components/timeline/TimelineFollowEvent.svelte
@@ -7,7 +7,11 @@
import { toPerson } from "./mappers";
import type { FollowEvent } from "$lib/api/lexicons/types/sh/tangled/feed/getTimeline";
- let { event, eventAt }: { event: FollowEvent; eventAt: string } = $props();
+ let {
+ event,
+ eventAt,
+ signedIn = false
+ }: { event: FollowEvent; eventAt: string; signedIn?: boolean } = $props();
@@ -22,5 +26,11 @@
{relativeTime(eventAt)}
{/snippet}
-
+
diff --git a/web/src/lib/components/timeline/TimelineRepoEvent.svelte b/web/src/lib/components/timeline/TimelineRepoEvent.svelte
index fddf78daa..6fc278228 100644
--- a/web/src/lib/components/timeline/TimelineRepoEvent.svelte
+++ b/web/src/lib/components/timeline/TimelineRepoEvent.svelte
@@ -7,7 +7,11 @@
import { toRepoCard, repoHref } from "./mappers";
import type { RepoEvent } from "$lib/api/lexicons/types/sh/tangled/feed/getTimeline";
- let { event, eventAt }: { event: RepoEvent; eventAt: string } = $props();
+ let {
+ event,
+ eventAt,
+ signedIn = false
+ }: { event: RepoEvent; eventAt: string; signedIn?: boolean } = $props();
@@ -32,6 +36,7 @@
+ import timelineTimelineSkeletonFixture from "$lib/bones/timeline-timeline--skeleton-fixture.bones.json";
+ import Bones from "$lib/components/ui/Bones.svelte";
+
+
+
diff --git a/web/src/lib/components/timeline/TimelineStarEvent.svelte b/web/src/lib/components/timeline/TimelineStarEvent.svelte
index a660f687a..a42701800 100644
--- a/web/src/lib/components/timeline/TimelineStarEvent.svelte
+++ b/web/src/lib/components/timeline/TimelineStarEvent.svelte
@@ -7,7 +7,11 @@
import { toRepoCard, repoHref } from "./mappers";
import type { StarEvent } from "$lib/api/lexicons/types/sh/tangled/feed/getTimeline";
- let { event, eventAt }: { event: StarEvent; eventAt: string } = $props();
+ let {
+ event,
+ eventAt,
+ signedIn = false
+ }: { event: StarEvent; eventAt: string; signedIn?: boolean } = $props();
@@ -24,6 +28,7 @@
-
+ {#if loading}
+
+ {:else}
+
+ {/if}
diff --git a/web/src/lib/components/timeline/load.ts b/web/src/lib/components/timeline/load.ts
index 72cae5ebc..8cca25b58 100644
--- a/web/src/lib/components/timeline/load.ts
+++ b/web/src/lib/components/timeline/load.ts
@@ -1,5 +1,4 @@
import { jsonGet } from "$lib/api/_request";
-import { toHttpError } from "$lib/api/load";
import { getTrending } from "$lib/api/profile";
import { toRepoCard } from "./mappers";
import type { BobbinContext } from "$lib/api/client";
@@ -9,30 +8,17 @@ const PAGE_LIMIT = 50;
export interface LoadTimelineOptions {
ctx: BobbinContext;
- viewer: string | undefined;
- url: URL;
+ followingOnly: boolean;
}
// shared by /timeline and the signed-in homescreen at /
-export const loadTimeline = async ({ ctx, viewer, url }: LoadTimelineOptions) => {
- const followingOnly = url.searchParams.get("following") === "true" && viewer !== undefined;
-
- try {
- const [{ feed }, trending] = await Promise.all([
- jsonGet(ctx, "sh.tangled.feed.getTimeline", {
- viewer,
- followingOnly,
- limit: PAGE_LIMIT
- }),
- getTrending(ctx).catch(() => ({ people: [], repos: [] }))
- ]);
- return {
- feed,
- trending: trending.repos.map(toRepoCard),
+export const loadTimeline = async ({ ctx, followingOnly }: LoadTimelineOptions) => {
+ const [{ feed }, trending] = await Promise.all([
+ jsonGet(ctx, "sh.tangled.feed.getTimeline", {
followingOnly,
- signedIn: viewer !== undefined
- };
- } catch (cause) {
- toHttpError(cause, "Could not load timeline");
- }
+ limit: PAGE_LIMIT
+ }),
+ getTrending(ctx).catch(() => ({ people: [], repos: [] }))
+ ]);
+ return { feed, trending: trending.repos.map(toRepoCard), followingOnly };
};
diff --git a/web/src/lib/components/timeline/timelineFeed.svelte.ts b/web/src/lib/components/timeline/timelineFeed.svelte.ts
new file mode 100644
index 000000000..59279e84f
--- /dev/null
+++ b/web/src/lib/components/timeline/timelineFeed.svelte.ts
@@ -0,0 +1,71 @@
+import { createBobbinClient } from "$lib/api/client";
+import { getAuth } from "$lib/auth.svelte";
+import { loadTimeline } from "./load";
+import type * as ShTangledFeedGetTimeline from "$lib/api/lexicons/types/sh/tangled/feed/getTimeline";
+import type { RepoCardData } from "$lib/components/profile/types";
+
+export interface TimelineFeedOptions {
+ followingOnly: () => boolean;
+ /** set to `() => false` to skip fetching entirely (e.g. marketing page branch of `/`) */
+ enabled?: () => boolean;
+}
+
+export const createTimelineFeed = (opts: TimelineFeedOptions) => {
+ const auth = getAuth();
+
+ let feed = $state([]);
+ let trending = $state([]);
+ let loading = $state(true);
+ let failed = $state(false);
+
+ const signedIn = $derived(Boolean(auth.currentDid));
+
+ $effect(() => {
+ const isEnabled = opts.enabled ? opts.enabled() : true;
+ if (!isEnabled || auth.resolving) return;
+
+ const agent = auth.agent ?? undefined;
+ const wantFollowing = opts.followingOnly() && Boolean(auth.currentDid);
+
+ loading = true;
+ failed = false;
+ let cancelled = false;
+
+ const ctx = createBobbinClient({ serviceUrl: auth.bobbinUrl, agent });
+ loadTimeline({ ctx, followingOnly: wantFollowing })
+ .then((result) => {
+ if (cancelled) return;
+ feed = result.feed;
+ trending = result.trending;
+ loading = false;
+ })
+ .catch(() => {
+ if (!cancelled) {
+ loading = false;
+ failed = true;
+ }
+ });
+
+ return () => {
+ cancelled = true;
+ };
+ });
+
+ return {
+ get feed() {
+ return feed;
+ },
+ get trending() {
+ return trending;
+ },
+ get loading() {
+ return loading;
+ },
+ get failed() {
+ return failed;
+ },
+ get signedIn() {
+ return signedIn;
+ }
+ };
+};
diff --git a/web/src/lib/oauth-client-metadata.json b/web/src/lib/oauth-client-metadata.json
index 9df36d2fe..0d1dcf66a 100644
--- a/web/src/lib/oauth-client-metadata.json
+++ b/web/src/lib/oauth-client-metadata.json
@@ -3,7 +3,7 @@
"client_name": "Tangled",
"client_uri": "https://tangled.org",
"redirect_uris": ["https://tangled.org/oauth/callback"],
- "scope": "atproto repo:sh.tangled.actor.profile repo:org.tangled.feed.subscription repo:sh.tangled.feed.comment repo:sh.tangled.feed.reaction repo:sh.tangled.feed.star repo:sh.tangled.graph.follow repo:sh.tangled.graph.vouch repo:sh.tangled.knot repo:sh.tangled.knot.member repo:sh.tangled.label.definition repo:sh.tangled.label.op repo:sh.tangled.publicKey repo:sh.tangled.repo repo:sh.tangled.repo.artifact repo:sh.tangled.repo.collaborator repo:sh.tangled.repo.issue repo:sh.tangled.repo.issue.comment repo:sh.tangled.repo.issue.state repo:sh.tangled.repo.pull repo:sh.tangled.repo.pull.comment repo:sh.tangled.repo.pull.status repo:sh.tangled.spindle repo:sh.tangled.spindle.member repo:sh.tangled.string blob:*/* rpc:sh.tangled.graph.listNetworkVouches?aud=* rpc:sh.tangled.knot.addMember?aud=* rpc:sh.tangled.knot.removeMember?aud=* rpc:sh.tangled.ci.triggerPipeline?aud=* rpc:sh.tangled.ci.cancelPipeline?aud=* rpc:sh.tangled.repo.addCollaborator?aud=* rpc:sh.tangled.repo.addSecret?aud=* rpc:sh.tangled.repo.create?aud=* rpc:sh.tangled.repo.delete?aud=* rpc:sh.tangled.repo.deleteBranch?aud=* rpc:sh.tangled.repo.forkStatus?aud=* rpc:sh.tangled.repo.forkSync?aud=* rpc:sh.tangled.repo.hiddenRef?aud=* rpc:sh.tangled.repo.listSecrets?aud=* rpc:sh.tangled.repo.merge?aud=* rpc:sh.tangled.repo.mergeCheck?aud=* rpc:sh.tangled.repo.removeCollaborator?aud=* rpc:sh.tangled.repo.removeSecret?aud=* rpc:sh.tangled.repo.setDefaultBranch?aud=* rpc:org.tangled.temp.notification.getPreferences?aud=* rpc:org.tangled.temp.notification.updatePreferences?aud=* rpc:org.tangled.temp.notification.getUnreadCount?aud=* rpc:org.tangled.temp.notification.listNotifications?aud=* rpc:org.tangled.temp.notification.markAllRead?aud=* rpc:org.tangled.temp.notification.markEntityRead?aud=* rpc:org.tangled.temp.notification.updateSeen?aud=* rpc:org.tangled.temp.account.listEmails?aud=* rpc:org.tangled.temp.account.deleteEmail?aud=* rpc:org.tangled.temp.account.setPrimaryEmail?aud=* rpc:org.tangled.temp.account.addEmail?aud=* rpc:org.tangled.temp.account.verifyEmail?aud=* rpc:org.tangled.temp.site.getDomainClaim?aud=* rpc:org.tangled.temp.site.claimDomain?aud=* rpc:org.tangled.temp.site.releaseDomain?aud=* rpc:org.tangled.temp.search.searchCode?aud=* rpc:sh.tangled.git.keepCommit?aud=* rpc:sh.tangled.git.mergeCommit?aud=* rpc:com.atproto.moderation.createReport?aud=*",
+ "scope": "atproto repo:sh.tangled.actor.profile repo:org.tangled.feed.subscription repo:sh.tangled.feed.comment repo:sh.tangled.feed.reaction repo:sh.tangled.feed.star repo:sh.tangled.graph.follow repo:sh.tangled.graph.vouch repo:sh.tangled.knot repo:sh.tangled.knot.member repo:sh.tangled.label.definition repo:sh.tangled.label.op repo:sh.tangled.publicKey repo:sh.tangled.repo repo:sh.tangled.repo.artifact repo:sh.tangled.repo.collaborator repo:sh.tangled.repo.issue repo:sh.tangled.repo.issue.comment repo:sh.tangled.repo.issue.state repo:sh.tangled.repo.pull repo:sh.tangled.repo.pull.comment repo:sh.tangled.repo.pull.status repo:sh.tangled.spindle repo:sh.tangled.spindle.member repo:sh.tangled.string blob:*/* rpc:sh.tangled.graph.listNetworkVouches?aud=* rpc:sh.tangled.knot.addMember?aud=* rpc:sh.tangled.knot.removeMember?aud=* rpc:sh.tangled.ci.triggerPipeline?aud=* rpc:sh.tangled.ci.cancelPipeline?aud=* rpc:sh.tangled.repo.addCollaborator?aud=* rpc:sh.tangled.repo.addSecret?aud=* rpc:sh.tangled.repo.create?aud=* rpc:sh.tangled.repo.delete?aud=* rpc:sh.tangled.repo.deleteBranch?aud=* rpc:sh.tangled.repo.forkStatus?aud=* rpc:sh.tangled.repo.forkSync?aud=* rpc:sh.tangled.repo.hiddenRef?aud=* rpc:sh.tangled.repo.listSecrets?aud=* rpc:sh.tangled.repo.merge?aud=* rpc:sh.tangled.repo.mergeCheck?aud=* rpc:sh.tangled.repo.removeCollaborator?aud=* rpc:sh.tangled.repo.removeSecret?aud=* rpc:sh.tangled.repo.setDefaultBranch?aud=* rpc:org.tangled.temp.notification.getPreferences?aud=* rpc:org.tangled.temp.notification.updatePreferences?aud=* rpc:org.tangled.temp.notification.getUnreadCount?aud=* rpc:org.tangled.temp.notification.listNotifications?aud=* rpc:org.tangled.temp.notification.markAllRead?aud=* rpc:org.tangled.temp.notification.markEntityRead?aud=* rpc:org.tangled.temp.notification.updateSeen?aud=* rpc:org.tangled.temp.account.listEmails?aud=* rpc:org.tangled.temp.account.deleteEmail?aud=* rpc:org.tangled.temp.account.setPrimaryEmail?aud=* rpc:org.tangled.temp.account.addEmail?aud=* rpc:org.tangled.temp.account.verifyEmail?aud=* rpc:org.tangled.temp.site.getDomainClaim?aud=* rpc:org.tangled.temp.site.claimDomain?aud=* rpc:org.tangled.temp.site.releaseDomain?aud=* rpc:org.tangled.temp.search.searchCode?aud=* rpc:sh.tangled.git.keepCommit?aud=* rpc:sh.tangled.git.mergeCommit?aud=* rpc:sh.tangled.actor.getTrending?aud=* rpc:sh.tangled.feed.getTimeline?aud=* rpc:com.atproto.moderation.createReport?aud=*",
"grant_types": ["authorization_code", "refresh_token"],
"response_types": ["code"],
"token_endpoint_auth_method": "none",
diff --git a/web/src/routes/+page.svelte b/web/src/routes/+page.svelte
index 85426bf3b..e631e0df3 100644
--- a/web/src/routes/+page.svelte
+++ b/web/src/routes/+page.svelte
@@ -2,11 +2,14 @@
import { getAuth } from "$lib/auth.svelte";
import MarketingHome from "$lib/components/home/MarketingHome.svelte";
import TimelineView from "$lib/components/timeline/TimelineView.svelte";
- import type { PageData } from "./$types";
-
- let { data }: { data: PageData } = $props();
+ import { createTimelineFeed } from "$lib/components/timeline/timelineFeed.svelte";
const auth = getAuth();
+ const signedIn = $derived(Boolean(auth.currentUser));
+ const feedState = createTimelineFeed({
+ followingOnly: () => false,
+ enabled: () => signedIn
+ });
@@ -14,8 +17,15 @@
-{#if auth.currentUser && data.timeline}
-
+{#if signedIn}
+
{:else}
{/if}
diff --git a/web/src/routes/+page.ts b/web/src/routes/+page.ts
index dc06756bd..7a1c58061 100644
--- a/web/src/routes/+page.ts
+++ b/web/src/routes/+page.ts
@@ -3,14 +3,13 @@ import { redirect } from "@sveltejs/kit";
import { createBobbinClient } from "$lib/api/client";
import { httpStatusFor, toHttpError } from "$lib/api/load";
import { getProfile } from "$lib/api/records";
-import { loadTimeline } from "$lib/components/timeline/load";
import type { PageLoad } from "./$types";
export const load: PageLoad = async (event) => {
const parent = await event.parent();
const viewer = parent.auth?.did;
// signed out gets the marketing page, which needs no data
- if (!viewer) return { timeline: null };
+ if (!viewer) return {};
const ctx = createBobbinClient({
serviceUrl: parent.publicConfig.bobbinUrl,
@@ -28,5 +27,5 @@ export const load: PageLoad = async (event) => {
}
}
- return { timeline: await loadTimeline({ ctx, viewer, url: event.url }) };
+ return {};
};
diff --git a/web/src/routes/[handle]/[repo]/+layout.ts b/web/src/routes/[handle]/[repo]/+layout.ts
index 84015a83e..9a3abfe2e 100644
--- a/web/src/routes/[handle]/[repo]/+layout.ts
+++ b/web/src/routes/[handle]/[repo]/+layout.ts
@@ -110,19 +110,19 @@ export const load: LayoutLoad = async (event) => {
: Promise.resolve(null),
issues: repoDid
? count(ctx, "sh.tangled.repo.countIssues", repoDid, { state: "open" }).catch(
- () => null
- )
+ () => null
+ )
: Promise.resolve(null),
pulls: repoDid
? count(ctx, "sh.tangled.repo.countPulls", repoDid, { status: "open" }).catch(
- () => null
- )
+ () => null
+ )
: Promise.resolve(null),
forks: repoDid
? count(ctx, "sh.tangled.repo.countForks", repoDid).catch(() => null)
: Promise.resolve(null)
}).then((stats): RepoCounts => ({
- stars: stats.stars?.count ?? 0,
+ stars: stats.stars?.distinctAuthors ?? 0,
issues: stats.issues?.count ?? 0,
pulls: stats.pulls?.count ?? 0,
forks: stats.forks?.count ?? 0
diff --git a/web/src/routes/timeline/+page.svelte b/web/src/routes/timeline/+page.svelte
index c3580eab5..7298263f7 100644
--- a/web/src/routes/timeline/+page.svelte
+++ b/web/src/routes/timeline/+page.svelte
@@ -1,8 +1,10 @@
@@ -10,9 +12,10 @@
diff --git a/web/src/routes/timeline/+page.ts b/web/src/routes/timeline/+page.ts
deleted file mode 100644
index 0a1afd441..000000000
--- a/web/src/routes/timeline/+page.ts
+++ /dev/null
@@ -1,13 +0,0 @@
-import { createBobbinClient } from "$lib/api/client";
-import { loadTimeline } from "$lib/components/timeline/load";
-import type { PageLoad } from "./$types";
-
-export const load: PageLoad = async (event) => {
- const parent = await event.parent();
- const ctx = createBobbinClient({
- serviceUrl: parent.publicConfig.bobbinUrl,
- fetch: event.fetch
- });
-
- return loadTimeline({ ctx, viewer: parent.auth?.did, url: event.url });
-};