|
1 | | -import { JSX } from "react"; |
| 1 | +import React, { JSX, useEffect, useState } from "react"; |
| 2 | +import { NOT_TAGS } from "~/Constants"; |
| 3 | +import useDaemonRPC from "~/DaemonRPC"; |
| 4 | +import LBRY from "~/LBRY"; |
| 5 | +import ClaimPreviewTile from "~/components/ClaimPreviewTile"; |
| 6 | +import CustomSVG from "~/components/CustomSVG"; |
| 7 | +import Error from "~/components/Error"; |
| 8 | +import Loader from "~/components/Loader"; |
2 | 9 |
|
3 | 10 | function Following(): JSX.Element { |
4 | | - return <>TODO Following page</>; |
| 11 | + const daemonRPC: string = useDaemonRPC(); |
| 12 | + |
| 13 | + const [localPreferenceResponse, setLocalPreferenceResponse] = |
| 14 | + useState<object>(undefined); |
| 15 | + const [channelIDs, setChannelIDs] = useState<string[]>([]); |
| 16 | + const [items, setItems] = useState<object[] | string | null>(null); |
| 17 | + const [toggle, setToggle] = useState<string>("new"); |
| 18 | + |
| 19 | + useEffect((): void => { |
| 20 | + LBRY.rpc( |
| 21 | + daemonRPC, |
| 22 | + LBRY.PREFERENCE_GET, |
| 23 | + { key: "local" }, |
| 24 | + null, |
| 25 | + LBRY.isUsingProxy(), |
| 26 | + ).then((json: object): void => { |
| 27 | + setLocalPreferenceResponse(json); |
| 28 | + if (json?.result?.local?.subscriptions) { |
| 29 | + setChannelIDs( |
| 30 | + json?.result?.local?.subscriptions.map( |
| 31 | + (subscription: string): string => |
| 32 | + subscription.substring(subscription.indexOf("#")), |
| 33 | + ), |
| 34 | + ); |
| 35 | + } |
| 36 | + }); |
| 37 | + }, []); |
| 38 | + |
| 39 | + useEffect((): void => { |
| 40 | + const orderBy: string = |
| 41 | + (toggle === "new" ? "release_time" : "") + |
| 42 | + (toggle === "trending" ? "trending_score" : "") + |
| 43 | + (toggle === "top" ? "effective_amount" : ""); |
| 44 | + |
| 45 | + const hourAgo: number = (Date.now() - 3600000) / 1000; |
| 46 | + |
| 47 | + const releaseTime: string = |
| 48 | + (toggle === "new" ? "<" + hourAgo : "") + |
| 49 | + (toggle === "trending" ? "<" + hourAgo : "") + |
| 50 | + (toggle === "top" ? ">" + hourAgo : ""); |
| 51 | + |
| 52 | + // "<1765920600" |
| 53 | + |
| 54 | + const searchOptions: object = { |
| 55 | + page_size: 20, |
| 56 | + page: 1, |
| 57 | + channel_ids: channelIDs, |
| 58 | + claim_type: ["stream", "repost", "channel"], |
| 59 | + no_totals: true, |
| 60 | + not_channel_ids: [], |
| 61 | + not_tags: NOT_TAGS, |
| 62 | + order_by: [orderBy], |
| 63 | + has_source: true, |
| 64 | + release_time: releaseTime, |
| 65 | + include_purchase_receipt: true, |
| 66 | + }; |
| 67 | + |
| 68 | + LBRY.rpc( |
| 69 | + daemonRPC, |
| 70 | + LBRY.CLAIM_SEARCH, |
| 71 | + searchOptions, |
| 72 | + null, |
| 73 | + LBRY.isUsingProxy(), |
| 74 | + ).then((json: object): void => { |
| 75 | + setItems(json.result.items || json.error?.message || "Unknown error"); |
| 76 | + }); |
| 77 | + }, [daemonRPC, channelIDs, toggle]); |
| 78 | + |
| 79 | + return ( |
| 80 | + <> |
| 81 | + <h1> |
| 82 | + <CustomSVG |
| 83 | + style={{ |
| 84 | + fill: "transparent", |
| 85 | + height: "24", |
| 86 | + width: "24", |
| 87 | + verticalAlign: "middle", |
| 88 | + stroke: "white", |
| 89 | + strokeWidth: "2px", |
| 90 | + padding: open ? "0px 8px 0px 12px" : null, |
| 91 | + }} |
| 92 | + icon="heart" |
| 93 | + viewBox="0 0 24 24" |
| 94 | + />{" "} |
| 95 | + <span style={{ verticalAlign: "middle" }}>Following</span> |
| 96 | + </h1> |
| 97 | + {localPreferenceResponse ? ( |
| 98 | + localPreferenceResponse.error ? ( |
| 99 | + <Error message={localPreferenceResponse.error.message} /> |
| 100 | + ) : ( |
| 101 | + <> |
| 102 | + <div style={{ padding: "16px 0" }}> |
| 103 | + <button |
| 104 | + onClick={(): void => { |
| 105 | + if (toggle !== "new") { |
| 106 | + setItems(null); |
| 107 | + } |
| 108 | + setToggle("new"); |
| 109 | + }} |
| 110 | + > |
| 111 | + New |
| 112 | + </button> |
| 113 | + <button |
| 114 | + onClick={(): void => { |
| 115 | + if (toggle !== "trending") { |
| 116 | + setItems(null); |
| 117 | + } |
| 118 | + setToggle("trending"); |
| 119 | + }} |
| 120 | + > |
| 121 | + Trending |
| 122 | + </button> |
| 123 | + <button |
| 124 | + onClick={(): void => { |
| 125 | + if (toggle !== "top") { |
| 126 | + setItems(null); |
| 127 | + } |
| 128 | + setToggle("top"); |
| 129 | + }} |
| 130 | + > |
| 131 | + Top |
| 132 | + </button> |
| 133 | + </div> |
| 134 | + <div style={{ padding: "16px 0", textAlign: "center" }}> |
| 135 | + {items === null ? ( |
| 136 | + <Loader /> |
| 137 | + ) : "string" === typeof items ? ( |
| 138 | + <span style={{ color: "red" }}>{items}</span> |
| 139 | + ) : items.length > 0 ? ( |
| 140 | + items.map((cell: unknown, i: number) => ( |
| 141 | + <ClaimPreviewTile claim={cell} key={i} /> |
| 142 | + )) |
| 143 | + ) : ( |
| 144 | + "No items" |
| 145 | + )} |
| 146 | + </div> |
| 147 | + </> |
| 148 | + ) |
| 149 | + ) : ( |
| 150 | + <Loader /> |
| 151 | + )} |
| 152 | + </> |
| 153 | + ); |
5 | 154 | } |
6 | 155 |
|
7 | 156 | export default Following; |
0 commit comments