mirror of
https://github.com/hzrd149/nostrudel.git
synced 2025-05-31 18:20:48 +02:00
add simple notifications view
This commit is contained in:
parent
4b4c272eae
commit
7f51cd405c
@ -21,6 +21,7 @@ import UserFollowingTab from "./views/user/following";
|
||||
import NoteView from "./views/note";
|
||||
import { LoginStartView } from "./views/login/start";
|
||||
import { LoginNpubView } from "./views/login/npub";
|
||||
import NotificationsView from "./views/notifications";
|
||||
|
||||
const RequireSetup = ({ children }: { children: JSX.Element }) => {
|
||||
let location = useLocation();
|
||||
@ -84,6 +85,10 @@ const router = createBrowserRouter([
|
||||
path: "settings",
|
||||
element: <SettingsView />,
|
||||
},
|
||||
{
|
||||
path: "notifications",
|
||||
element: <NotificationsView />,
|
||||
},
|
||||
{
|
||||
path: "profile",
|
||||
element: <ProfileView />,
|
||||
|
@ -19,14 +19,16 @@ const MobileProfileHeader = () => {
|
||||
const pubkey = useSubject(identity.pubkey);
|
||||
|
||||
return (
|
||||
<Flex justifyContent="space-between" px="2" pt="2">
|
||||
<Flex justifyContent="space-between" padding="2">
|
||||
<UserAvatarLink pubkey={pubkey} size="sm" />
|
||||
<IconButton
|
||||
as={Link}
|
||||
variant="ghost"
|
||||
icon={<NotificationIcon />}
|
||||
aria-label="Notifications"
|
||||
title="Notifications"
|
||||
size="sm"
|
||||
to="/notifications"
|
||||
/>
|
||||
</Flex>
|
||||
);
|
||||
@ -71,6 +73,9 @@ const DesktopSideNav = () => {
|
||||
<Button onClick={() => navigate("/")} leftIcon={<FeedIcon />}>
|
||||
Home
|
||||
</Button>
|
||||
<Button onClick={() => navigate("/notifications")} leftIcon={<NotificationIcon />}>
|
||||
Notifications
|
||||
</Button>
|
||||
<Button onClick={() => navigate("/settings")} leftIcon={<SettingsIcon />}>
|
||||
Settings
|
||||
</Button>
|
||||
|
69
src/views/notifications/index.tsx
Normal file
69
src/views/notifications/index.tsx
Normal file
@ -0,0 +1,69 @@
|
||||
import { Button, Card, CardBody, Flex, Spinner, Text } from "@chakra-ui/react";
|
||||
import moment from "moment";
|
||||
import { memo } from "react";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { NoteContents } from "../../components/note/note-contents";
|
||||
import { UserAvatar } from "../../components/user-avatar";
|
||||
import { UserLink } from "../../components/user-link";
|
||||
import { convertTimestampToDate } from "../../helpers/date";
|
||||
import useSubject from "../../hooks/use-subject";
|
||||
import { useTimelineLoader } from "../../hooks/use-timeline-loader";
|
||||
import identity from "../../services/identity";
|
||||
import settings from "../../services/settings";
|
||||
import { NostrEvent } from "../../types/nostr-event";
|
||||
|
||||
const Kind1Notification = ({ event }: { event: NostrEvent }) => {
|
||||
const navigate = useNavigate();
|
||||
|
||||
return (
|
||||
<Card>
|
||||
<CardBody>
|
||||
<Flex gap="4">
|
||||
<UserAvatar pubkey={event.pubkey} size="sm" />
|
||||
<UserLink pubkey={event.pubkey} />
|
||||
<Text>{moment(convertTimestampToDate(event.created_at)).fromNow()}</Text>
|
||||
<Button onClick={() => navigate(`/n/${event.id}`)} size="sm" ml="auto">
|
||||
View
|
||||
</Button>
|
||||
</Flex>
|
||||
</CardBody>
|
||||
</Card>
|
||||
);
|
||||
};
|
||||
|
||||
const NotificationItem = memo(({ event }: { event: NostrEvent }) => {
|
||||
if (event.kind === 1) {
|
||||
return <Kind1Notification event={event} />;
|
||||
}
|
||||
return <>Unknown event type {event.kind}</>;
|
||||
});
|
||||
|
||||
const NotificationsView = () => {
|
||||
const relays = useSubject(settings.relays);
|
||||
const pubkey = useSubject(identity.pubkey);
|
||||
const { events, loading, loadMore } = useTimelineLoader(
|
||||
"notifications",
|
||||
relays,
|
||||
{
|
||||
"#p": [pubkey],
|
||||
kinds: [1],
|
||||
since: moment().subtract(1, "day").unix(),
|
||||
},
|
||||
{ pageSize: moment.duration(1, "day").asSeconds() }
|
||||
);
|
||||
|
||||
const timeline = events
|
||||
// ignore events made my the user
|
||||
.filter((e) => e.pubkey !== pubkey);
|
||||
|
||||
return (
|
||||
<Flex direction="column" overflowX="hidden" overflowY="auto" gap="2">
|
||||
{timeline.map((event) => (
|
||||
<NotificationItem key={event.id} event={event} />
|
||||
))}
|
||||
{loading ? <Spinner ml="auto" mr="auto" mt="8" mb="8" /> : <Button onClick={() => loadMore()}>Load More</Button>}
|
||||
</Flex>
|
||||
);
|
||||
};
|
||||
|
||||
export default NotificationsView;
|
@ -210,7 +210,7 @@ export const SettingsView = () => {
|
||||
</AccordionPanel>
|
||||
</AccordionItem>
|
||||
</Accordion>
|
||||
<Flex gap="2">
|
||||
<Flex gap="2" padding="4">
|
||||
<Button onClick={() => identity.logout()}>Logout</Button>
|
||||
</Flex>
|
||||
</Flex>
|
||||
|
@ -91,9 +91,11 @@ const UserView = () => {
|
||||
onClick={() => navigate("/settings")}
|
||||
/>
|
||||
)}
|
||||
<Button colorScheme="brand" size="sm">
|
||||
Follow
|
||||
</Button>
|
||||
{!isSelf && (
|
||||
<Button colorScheme="brand" size="sm">
|
||||
Follow
|
||||
</Button>
|
||||
)}
|
||||
</Flex>
|
||||
</Flex>
|
||||
</Flex>
|
||||
|
Loading…
x
Reference in New Issue
Block a user