diff --git a/src/components/topbar/topbar.tsx b/src/components/topbar/topbar.tsx
index a1e32197..b7c54bd4 100644
--- a/src/components/topbar/topbar.tsx
+++ b/src/components/topbar/topbar.tsx
@@ -46,7 +46,11 @@ const TopBar = () => {
const [selectedSortType, setSelectedSortType] = useState(params.sortType || '/hot');
const getTimeFilterLink = (choice: string) => {
- return isSubplebbit ? `/p/${params.subplebbitAddress}/${selectedSortType}/${choice}` : isAll ? `p/all/${selectedSortType}/${choice}` : `/${selectedSortType}/${choice}`;
+ return isSubplebbit
+ ? `/p/${params.subplebbitAddress}/${selectedSortType}/${choice}`
+ : isAll
+ ? `p/all/${selectedSortType}/${choice}`
+ : `/${selectedSortType}/${choice}`;
};
const getSelectedSortLabel = () => {
diff --git a/src/lib/utils/view-utils.ts b/src/lib/utils/view-utils.ts
index da2d3a6a..37f181b9 100644
--- a/src/lib/utils/view-utils.ts
+++ b/src/lib/utils/view-utils.ts
@@ -42,6 +42,10 @@ export const isHomeView = (pathname: string, params: ParamsType): boolean => {
return pathname === '/' || (sortTypes.includes(pathname) || (timeFilterNames.includes(params.timeFilterName as TimeFilterKey) && !pathname.startsWith('/p/all')));
};
+export const isInboxView = (pathname: string): boolean => {
+ return pathname.startsWith('/inbox');
+}
+
export const isPendingView = (pathname: string, params: ParamsType): boolean => {
return pathname === `/profile/${params.accountCommentIndex}`;
};
diff --git a/src/views/author/author.tsx b/src/views/author/author.tsx
index 154fb011..23d1845d 100644
--- a/src/views/author/author.tsx
+++ b/src/views/author/author.tsx
@@ -1,21 +1,21 @@
-import { useEffect, useRef } from "react";
-import { useNavigate, useParams } from "react-router-dom";
-import { useAuthorComments } from "@plebbit/plebbit-react-hooks"
-import { StateSnapshot, Virtuoso, VirtuosoHandle } from "react-virtuoso";
-import styles from "./author.module.css";
-import AuthorSidebar from "../../components/author-sidebar";
-import Post from "../../components/post";
+import { useEffect, useRef } from 'react';
+import { useNavigate, useParams } from 'react-router-dom';
+import { useAuthorComments } from '@plebbit/plebbit-react-hooks';
+import { StateSnapshot, Virtuoso, VirtuosoHandle } from 'react-virtuoso';
+import styles from './author.module.css';
+import AuthorSidebar from '../../components/author-sidebar';
+import Post from '../../components/post';
const lastVirtuosoStates: { [key: string]: StateSnapshot } = {};
-const Loading = () => 'loading...'
+const Loading = () => 'loading...';
const Author = () => {
const { authorAddress, commentCid, sortType } = useParams();
const navigate = useNavigate();
- const {authorComments, lastCommentCid, hasMore, loadMore} = useAuthorComments({commentCid, authorAddress});
+ const { authorComments, lastCommentCid, hasMore, loadMore } = useAuthorComments({ commentCid, authorAddress });
- const Footer = hasMore ? Loading : undefined
+ const Footer = hasMore ? Loading : undefined;
const virtuosoRef = useRef
(null);
@@ -37,9 +37,9 @@ const Author = () => {
// always redirect to latest author cid
useEffect(() => {
if (authorAddress && lastCommentCid && commentCid && lastCommentCid !== commentCid) {
- navigate(`/u/${authorAddress}/c/${lastCommentCid}`, {replace: true})
+ navigate(`/u/${authorAddress}/c/${lastCommentCid}`, { replace: true });
}
- }, [authorAddress, lastCommentCid, commentCid, navigate])
+ }, [authorAddress, lastCommentCid, commentCid, navigate]);
return (
@@ -51,9 +51,9 @@ const Author = () => {
increaseViewportBy={{ bottom: 1200, top: 600 }}
totalCount={authorComments?.length || 0}
data={authorComments}
- itemContent={(index, post) => post ?
: null}
+ itemContent={(index, post) => (post ?
: null)}
useWindowScroll={true}
- components={{Footer}}
+ components={{ Footer }}
endReached={loadMore}
ref={virtuosoRef}
restoreStateFrom={lastVirtuosoState}
diff --git a/src/views/inbox/inbox.module.css b/src/views/inbox/inbox.module.css
new file mode 100644
index 00000000..e69de29b
diff --git a/src/views/inbox/inbox.tsx b/src/views/inbox/inbox.tsx
new file mode 100644
index 00000000..5a8b0450
--- /dev/null
+++ b/src/views/inbox/inbox.tsx
@@ -0,0 +1,58 @@
+import { useEffect, useRef } from 'react';
+import { StateSnapshot, Virtuoso, VirtuosoHandle } from 'react-virtuoso';
+import { useAccount, useNotifications } from '@plebbit/plebbit-react-hooks';
+import styles from './inbox.module.css';
+import Post from '../../components/post';
+
+const lastVirtuosoStates: { [key: string]: StateSnapshot } = {};
+
+const Inbox = () => {
+ const account = useAccount();
+ const { unreadNotificationCount } = account || {};
+ const { notifications, markAsRead } = useNotifications();
+
+ const virtuosoRef = useRef
(null);
+
+ useEffect(() => {
+ const setLastVirtuosoState = () =>
+ virtuosoRef.current?.getState((snapshot) => {
+ // TODO: not sure if checking for empty snapshot.ranges works for all scenarios
+ if (snapshot?.ranges?.length) {
+ lastVirtuosoStates[unreadNotificationCount] = snapshot;
+ }
+ });
+ window.addEventListener('scroll', setLastVirtuosoState);
+ // clean listener on unmount
+ return () => window.removeEventListener('scroll', setLastVirtuosoState);
+ }, [unreadNotificationCount]);
+
+ const lastVirtuosoState = lastVirtuosoStates?.[unreadNotificationCount];
+
+ if (account && !notifications.length) {
+ return 'empty';
+ }
+
+ return (
+
+
+
(
+
+ )}
+ useWindowScroll={true}
+ ref={virtuosoRef}
+ restoreStateFrom={lastVirtuosoState}
+ initialScrollTop={lastVirtuosoState?.scrollTop}
+ />
+
+ );
+};
+
+export default Inbox;
diff --git a/src/views/inbox/index.ts b/src/views/inbox/index.ts
new file mode 100644
index 00000000..a5910b45
--- /dev/null
+++ b/src/views/inbox/index.ts
@@ -0,0 +1 @@
+export {default} from './inbox';
\ No newline at end of file