mirror of
https://github.com/hzrd149/nostrudel.git
synced 2025-10-03 16:09:52 +02:00
sort feeds by most recent
This commit is contained in:
19
src/hooks/use-recent-ids.tsx
Normal file
19
src/hooks/use-recent-ids.tsx
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
import { useLocalStorage } from "react-use";
|
||||||
|
import { useCallback } from "react";
|
||||||
|
|
||||||
|
export default function useRecentIds(key: string, maxLength?: number) {
|
||||||
|
const [recent = [], setRecent] = useLocalStorage<string[]>("recent-" + key, []);
|
||||||
|
|
||||||
|
const useThing = useCallback(
|
||||||
|
(app: string) => {
|
||||||
|
setRecent((arr = []) => {
|
||||||
|
const newArr = [app].concat(...arr.filter((a) => a !== app));
|
||||||
|
if (maxLength) return newArr.slice(0, maxLength);
|
||||||
|
else return newArr;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
[setRecent],
|
||||||
|
);
|
||||||
|
|
||||||
|
return { recent, useThing };
|
||||||
|
}
|
@@ -21,6 +21,7 @@ import HoverLinkOverlay from "../../../components/hover-link-overlay";
|
|||||||
import { getEventCoordinate, getEventUID } from "../../../helpers/nostr/events";
|
import { getEventCoordinate, getEventUID } from "../../../helpers/nostr/events";
|
||||||
import Plus from "../../../components/icons/plus";
|
import Plus from "../../../components/icons/plus";
|
||||||
import useUserContactList from "../../../hooks/use-user-contact-list";
|
import useUserContactList from "../../../hooks/use-user-contact-list";
|
||||||
|
import useRecentIds from "../../../hooks/use-recent-ids";
|
||||||
|
|
||||||
function Feed({ list, ...props }: { list: NostrEvent } & Omit<CardProps, "children">) {
|
function Feed({ list, ...props }: { list: NostrEvent } & Omit<CardProps, "children">) {
|
||||||
const people = getPubkeysFromList(list);
|
const people = getPubkeysFromList(list);
|
||||||
@@ -32,7 +33,7 @@ function Feed({ list, ...props }: { list: NostrEvent } & Omit<CardProps, "childr
|
|||||||
</CardHeader>
|
</CardHeader>
|
||||||
<CardBody px="4" pt="0" pb="4" overflow="hidden" display="flex" gap="2" alignItems="center">
|
<CardBody px="4" pt="0" pb="4" overflow="hidden" display="flex" gap="2" alignItems="center">
|
||||||
<AvatarGroup>
|
<AvatarGroup>
|
||||||
{people.slice(0, 6).map((person) => (
|
{people.slice(0, 5).map((person) => (
|
||||||
<UserAvatar key={person.pubkey} pubkey={person.pubkey} />
|
<UserAvatar key={person.pubkey} pubkey={person.pubkey} />
|
||||||
))}
|
))}
|
||||||
</AvatarGroup>
|
</AvatarGroup>
|
||||||
@@ -45,9 +46,22 @@ function Feed({ list, ...props }: { list: NostrEvent } & Omit<CardProps, "childr
|
|||||||
|
|
||||||
export default function FeedsCard() {
|
export default function FeedsCard() {
|
||||||
const account = useCurrentAccount();
|
const account = useCurrentAccount();
|
||||||
const contacts = useUserContactList();
|
const contacts = useUserContactList(account?.pubkey);
|
||||||
const lists = useUserLists(account?.pubkey).filter((list) => list.kind === PEOPLE_LIST_KIND);
|
const lists = useUserLists(account?.pubkey).filter((list) => list.kind === PEOPLE_LIST_KIND);
|
||||||
|
|
||||||
|
const { recent: recentFeeds, useThing: useFeed } = useRecentIds("feeds", 4);
|
||||||
|
|
||||||
|
const sortedFeeds = Array.from(lists).sort((a, b) => {
|
||||||
|
const ai = recentFeeds.indexOf(getEventUID(a));
|
||||||
|
const bi = recentFeeds.indexOf(getEventUID(b));
|
||||||
|
const date = Math.sign(b.created_at - a.created_at);
|
||||||
|
|
||||||
|
if (ai === -1 && bi === -1) return date;
|
||||||
|
else if (bi === -1) return -1;
|
||||||
|
else if (ai === -1) return 1;
|
||||||
|
else return ai - bi;
|
||||||
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Card as={LinkBox} variant="outline">
|
<Card as={LinkBox} variant="outline">
|
||||||
<CardHeader display="flex" justifyContent="space-between">
|
<CardHeader display="flex" justifyContent="space-between">
|
||||||
@@ -62,13 +76,17 @@ export default function FeedsCard() {
|
|||||||
size="sm"
|
size="sm"
|
||||||
/>
|
/>
|
||||||
</CardHeader>
|
</CardHeader>
|
||||||
<CardBody overflowX="auto" overflowY="hidden" pt="0">
|
<CardBody overflowX="auto" overflowY="hidden" pt="0" display="flex" gap="4">
|
||||||
<Flex gap="4">
|
{contacts && <Feed list={contacts} w="17rem" flexShrink={0} />}
|
||||||
{contacts && <Feed list={contacts} w="xs" flexShrink={0} />}
|
{sortedFeeds.slice(0, 10).map((list) => (
|
||||||
{lists.slice(0, 10).map((list) => (
|
<Feed
|
||||||
<Feed key={getEventUID(list)} list={list} w="xs" flexShrink={0} />
|
key={getEventUID(list)}
|
||||||
))}
|
list={list}
|
||||||
</Flex>
|
w="17rem"
|
||||||
|
flexShrink={0}
|
||||||
|
onClick={() => useFeed(getEventUID(list))}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
</CardBody>
|
</CardBody>
|
||||||
</Card>
|
</Card>
|
||||||
);
|
);
|
||||||
|
@@ -4,7 +4,7 @@ import { Heading, Input, SimpleGrid, Tab, TabList, TabPanel, TabPanels, Tabs } f
|
|||||||
import VerticalPageLayout from "../../components/vertical-page-layout";
|
import VerticalPageLayout from "../../components/vertical-page-layout";
|
||||||
import AppCard, { App } from "./component/app-card";
|
import AppCard, { App } from "./component/app-card";
|
||||||
import useRouteSearchValue from "../../hooks/use-route-search-value";
|
import useRouteSearchValue from "../../hooks/use-route-search-value";
|
||||||
import useRecentApps from "./use-recent-apps";
|
import useRecentIds from "../../hooks/use-recent-ids";
|
||||||
import { allApps, externalTools, internalTools } from "./apps";
|
import { allApps, externalTools, internalTools } from "./apps";
|
||||||
import { useBreakpointValue } from "../../providers/global/breakpoint-provider";
|
import { useBreakpointValue } from "../../providers/global/breakpoint-provider";
|
||||||
|
|
||||||
@@ -13,7 +13,7 @@ const tabs = ["all", "tools", "3rd-party-tools"];
|
|||||||
export default function OtherStuffView() {
|
export default function OtherStuffView() {
|
||||||
const [search, setSearch] = useState("");
|
const [search, setSearch] = useState("");
|
||||||
const tab = useRouteSearchValue("tab", "all");
|
const tab = useRouteSearchValue("tab", "all");
|
||||||
const { recentApps, useApp } = useRecentApps();
|
const { recent: recentApps, useThing: useApp } = useRecentIds("apps");
|
||||||
const autoFocusSearch = useBreakpointValue({ base: false, lg: true });
|
const autoFocusSearch = useBreakpointValue({ base: false, lg: true });
|
||||||
|
|
||||||
const sortByRecent = (a: App, b: App) => recentApps.indexOf(b.id) - recentApps.indexOf(a.id);
|
const sortByRecent = (a: App, b: App) => recentApps.indexOf(b.id) - recentApps.indexOf(a.id);
|
||||||
|
@@ -1,17 +0,0 @@
|
|||||||
import { useLocalStorage } from "react-use";
|
|
||||||
import { useCallback } from "react";
|
|
||||||
|
|
||||||
export default function useRecentApps() {
|
|
||||||
const [recentApps = [], setRecentApps] = useLocalStorage<string[]>("recent-apps", []);
|
|
||||||
|
|
||||||
const useApp = useCallback(
|
|
||||||
(app: string) => {
|
|
||||||
setRecentApps((arr = []) => {
|
|
||||||
return [app].concat(...arr.filter((a) => a !== app));
|
|
||||||
});
|
|
||||||
},
|
|
||||||
[setRecentApps],
|
|
||||||
);
|
|
||||||
|
|
||||||
return { recentApps, useApp };
|
|
||||||
}
|
|
@@ -12,7 +12,7 @@ export default function TextToSpeechResult({ result }: { result: NostrEvent }) {
|
|||||||
<UserLink pubkey={result.pubkey} fontWeight="bold" />
|
<UserLink pubkey={result.pubkey} fontWeight="bold" />
|
||||||
<Text>Finished job</Text>
|
<Text>Finished job</Text>
|
||||||
</Flex>
|
</Flex>
|
||||||
<Text>{result.content}</Text>
|
<audio src={result.content} controls />
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user