aboutsummaryrefslogtreecommitdiff
path: root/src/routes/+page.svelte
blob: 243acd0b0034345d7e94cba50fce9dc877b071cf (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
<script lang="ts">
  import ArticleHeader from "$lib/ArticleHeader.svelte";
  import { FeedType, indexKind } from "$lib/consts";
  import { ndk } from "$lib/ndk";
  import { NDKEvent, NDKRelayList, NDKRelaySet, NDKSubscriptionCacheUsage, type NDKUser } from "@nostr-dev-kit/ndk";
  import { Button, Dropdown, Radio } from "flowbite-svelte";
  import { ChevronDownOutline } from "flowbite-svelte-icons";

  const getEvents = (): Promise<Set<NDKEvent>> =>
    $ndk.fetchEvents(
      // @ts-ignore
      { kinds: [indexKind] },
    );

  const getEventsFromUserRelays = (userRelays: NDKRelayList): Promise<Set<NDKEvent>> => {
    const relaySet = NDKRelaySet.fromRelayUrls(userRelays!.readRelayUrls, $ndk);

    // TODO: Add more filter parameters to customize the event feed.
    return $ndk.fetchEvents(
      // @ts-ignore
      { kinds: [indexKind] },
      relaySet,
    );
  };

  const getEventsFromUserFollows = (follows: Set<NDKUser>, userRelays: NDKRelayList): Promise<Set<NDKEvent>> => {
    const relaySet = NDKRelaySet.fromRelayUrls(userRelays?.readRelayUrls ?? [], $ndk);
    const pubkeys = Array.from(follows ?? []).map(user => user.pubkey);

    return $ndk.fetchEvents(
      { 
        authors: pubkeys,
        // @ts-ignore
        kinds: [indexKind]
      },
      relaySet,
    );
  };

  const getFeedTypeFriendlyName = (feedType: FeedType): string => {
    switch (feedType) {
    case FeedType.Relays:
      return 'Relays';
    case FeedType.Follows:
      return 'Follows';
    default:
      return '';
    }
  };

  let user: NDKUser | null | undefined;
  let readRelays: NDKRelayList | null | undefined;
  let userFollows: Set<NDKUser> | null | undefined;
  let feedType: FeedType = FeedType.Relays;

  $: {
    user = $ndk.activeUser;
    user?.relayList().then(relays => readRelays = relays);
    user?.follows().then(follows => userFollows = follows);
  }
</script>

<div class='leather flex flex-col flex-grow-0 space-y-4 overflow-y-auto w-max p-2'>
  {#key user}
    {#if user == null || readRelays == null}
      {#await getEvents()}
        <p>Loading...</p>
      {:then events}
        {#each Array.from(events) as event}
          <ArticleHeader {event} />
        {/each}
      {/await}
    {:else}
      <div class='leather w-full flex justify-end'>
        <Button>
          {`Showing articles from: ${getFeedTypeFriendlyName(feedType)}`}<ChevronDownOutline class='w-6 h-6' />
        </Button>
        <Dropdown class='w-fit p-2 space-y-2 text-sm'>
          <li>
            <Radio name='relays' bind:group={feedType} value={FeedType.Relays}>Relays</Radio>
          </li>
          <li>
            <Radio name='follows' bind:group={feedType} value={FeedType.Follows}>Follows</Radio>
          </li>
        </Dropdown>
      </div>
      {#if feedType === FeedType.Relays && readRelays != null}
        {#await getEventsFromUserRelays(readRelays)}
          <p>Loading...</p>
        {:then events}
          {#each Array.from(events) as event}
            <ArticleHeader {event} />
          {/each}
        {/await}
      {:else if feedType === FeedType.Follows && userFollows != null}
        {#await getEventsFromUserFollows(userFollows, readRelays)}
          <p>Loading...</p>
        {:then events}
          {#each Array.from(events) as event}
            <ArticleHeader {event} />
          {/each}
        {/await}
      {/if}
    {/if}
  {/key}
</div>