add simple notifications view

This commit is contained in:
hzrd149 2023-02-07 17:04:19 -06:00
parent 4b4c272eae
commit 7f51cd405c
5 changed files with 86 additions and 5 deletions

View File

@ -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 />,

View File

@ -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>

View 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;

View File

@ -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>

View File

@ -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>