diff --git a/public/manifest.json b/public/manifest.json
index 1f2f141f..5992131b 100644
--- a/public/manifest.json
+++ b/public/manifest.json
@@ -1,6 +1,6 @@
{
- "short_name": "React App",
- "name": "Create React App Sample",
+ "short_name": "Seedit",
+ "name": "Seedit",
"icons": [
{
"src": "favicon.ico",
diff --git a/src/app.tsx b/src/app.tsx
index 01b0530b..f5c50150 100644
--- a/src/app.tsx
+++ b/src/app.tsx
@@ -15,7 +15,7 @@ import Profile from './views/profile';
import Settings from './views/settings';
import SubmitPage from './views/submit-page';
import Subplebbit from './views/subplebbit';
-import SubplebbitSettings from './views/subplebbit/subplebbit-settings';
+import SubplebbitSettings from './views/subplebbit-settings';
import Subplebbits from './views/subplebbits';
import AccountBar from './components/account-bar/';
import ChallengeModal from './components/challenge-modal';
diff --git a/src/components/header/header.tsx b/src/components/header/header.tsx
index e7ed9227..054dd64e 100644
--- a/src/components/header/header.tsx
+++ b/src/components/header/header.tsx
@@ -136,6 +136,7 @@ const AuthorHeaderTabs = () => {
!isInProfileCommentsView &&
!isInProfileSubmittedView &&
!isInAuthorCommentsView &&
+ !isInProfileHiddenView &&
!isInAuthorSubmittedView
? styles.selected
: styles.choice;
diff --git a/src/components/newer-posts-button/newer-posts-button.module.css b/src/components/newer-posts-button/newer-posts-button.module.css
index 62e7581a..3d33852b 100644
--- a/src/components/newer-posts-button/newer-posts-button.module.css
+++ b/src/components/newer-posts-button/newer-posts-button.module.css
@@ -1,43 +1,21 @@
.newerPostsButton {
position: fixed;
left: 10%;
- border-radius: 25px;
- background-color: green;
- color: white;
z-index: 5;
transition: top 0.3s ease-in-out;
- font-size: 13px;
}
.resetButton {
- display: inline-block;
+ display: inline-block;
cursor: pointer;
- font-weight: 700;
- padding: 5px 10px;
}
-.resetButton:hover {
- opacity: 0.8;
-}
.hide {
display: none;
}
.hideButton {
- display: inline-block;
cursor: pointer;
- background-image: url("/public/assets/buttons/close-x-button.png");
- background-size: cover;
- height: 12px;
- width: 12px;
- transform: translateY(1px);
-}
-
-.hideButtonWrapper {
- padding-right: 10px;
-}
-
-.hideButton:hover {
- opacity: 0.8;
+ padding: 0px 3px;
}
\ No newline at end of file
diff --git a/src/components/newer-posts-button/newer-posts-button.tsx b/src/components/newer-posts-button/newer-posts-button.tsx
index 922ee958..e6001a42 100644
--- a/src/components/newer-posts-button/newer-posts-button.tsx
+++ b/src/components/newer-posts-button/newer-posts-button.tsx
@@ -38,11 +38,13 @@ const NewerPostsButton = ({ reset, subplebbitAddressesWithNewerPosts }: NewerPos
return (
-
- Newer Posts
-
+
- setHideButton(true)} />
+
);
diff --git a/src/components/post/post.module.css b/src/components/post/post.module.css
index e3cbd42d..6d15ab6e 100644
--- a/src/components/post/post.module.css
+++ b/src/components/post/post.module.css
@@ -122,9 +122,7 @@
display: inline-block;
overflow: hidden;
white-space: nowrap;
- text-overflow: ellipsis;
vertical-align: middle;
- max-width: 19em;
text-decoration: none;
}
diff --git a/src/components/post/post.tsx b/src/components/post/post.tsx
index 97e43645..bbe59732 100644
--- a/src/components/post/post.tsx
+++ b/src/components/post/post.tsx
@@ -208,7 +208,7 @@ const Post = ({ index, post = {} }: PostProps) => {
(
- {linkUrl}
+ {linkUrl.length > 25 ? linkUrl.slice(0, 25) + '...' : linkUrl}
)
diff --git a/src/components/sidebar/sidebar.module.css b/src/components/sidebar/sidebar.module.css
index 925f9efe..04124a8a 100644
--- a/src/components/sidebar/sidebar.module.css
+++ b/src/components/sidebar/sidebar.module.css
@@ -58,13 +58,13 @@ a {
.descriptionTitle {
padding-top: 5px;
- color: var(--text-markdown);
+ color: var(--text);
}
.description {
padding: 5px 0;
word-wrap: break-word;
- color: var(--text-markdown);
+ color: var(--text);
line-height: 15px;
}
@@ -183,7 +183,7 @@ a {
.rules {
padding-bottom: 5px;
padding-top: 7px;
- color: var(--text-markdown);
+ color: var(--text);
line-height: 15px;
word-wrap: break-word;
}
diff --git a/src/views/profile/profile.tsx b/src/views/profile/profile.tsx
index fd926274..246e5c92 100644
--- a/src/views/profile/profile.tsx
+++ b/src/views/profile/profile.tsx
@@ -67,27 +67,74 @@ const SortDropdown = ({ onSortChange }: SortDropdownProps) => {
);
};
+const pageSize = 10;
+
const Profile = () => {
const { t } = useTranslation();
const account = useAccount();
const location = useLocation();
const params = useParams();
- let { accountComments } = useAccountComments();
- accountComments = [...accountComments].reverse();
- const { accountVotes } = useAccountVotes();
+ const isMobile = useWindowWidth() < 640;
+
+ const [activeTab, setActiveTab] = useState('overview');
+ const [currentPage, setCurrentPage] = useState(1);
+
const isInProfileUpvotedView = isProfileUpvotedView(location.pathname);
const isInProfileDownvotedView = isProfileDownvotedView(location.pathname);
const isInProfileHiddenView = isProfileHiddenView(location.pathname);
const isInCommentsView = isProfileCommentsView(location.pathname);
const isInSubmittedView = isProfileSubmittedView(location.pathname);
- const isMobile = useWindowWidth() < 640;
- // get comments for upvoted/downvoted/comments/submitted pages
+ useEffect(() => {
+ if (isInProfileUpvotedView) setActiveTab('upvoted');
+ else if (isInProfileDownvotedView) setActiveTab('downvoted');
+ else if (isInProfileHiddenView) setActiveTab('hidden');
+ else if (isInCommentsView) setActiveTab('comments');
+ else if (isInSubmittedView) setActiveTab('submitted');
+ else setActiveTab('overview');
+
+ setCurrentPage(1); // Reset page when changing tabs
+ }, [isInProfileUpvotedView, isInProfileDownvotedView, isInProfileHiddenView, isInCommentsView, isInSubmittedView]);
+
+ const { accountComments } = useAccountComments();
+ const { accountVotes } = useAccountVotes();
+
const postComments = useMemo(() => accountComments?.filter((comment) => !comment.parentCid) || [], [accountComments]);
const replyComments = useMemo(() => accountComments?.filter((comment) => comment.parentCid) || [], [accountComments]);
- const upvotedCommentCids = useMemo(() => accountVotes?.filter((vote) => vote.vote === 1).map((vote) => vote.commentCid) || [], [accountVotes]);
- const downvotedCommentCids = useMemo(() => accountVotes?.filter((vote) => vote.vote === -1).map((vote) => vote.commentCid) || [], [accountVotes]);
- const hiddenCommentCids = useMemo(() => Object.keys(account?.blockedCids ?? {}), [account?.blockedCids]);
+
+ const upvotedCommentCids = useMemo(() => {
+ const allUpvotedCids = accountVotes?.filter((vote) => vote.vote === 1).map((vote) => vote.commentCid) || [];
+ return allUpvotedCids.slice(0, currentPage * pageSize);
+ }, [accountVotes, currentPage]);
+
+ const downvotedCommentCids = useMemo(() => {
+ const allDownvotedCids = accountVotes?.filter((vote) => vote.vote === -1).map((vote) => vote.commentCid) || [];
+ return allDownvotedCids.slice(0, currentPage * pageSize);
+ }, [accountVotes, currentPage]);
+
+ const hiddenCommentCids = useMemo(() => {
+ const allHiddenCids = Object.keys(account?.blockedCids ?? {});
+ return allHiddenCids.slice(0, currentPage * pageSize);
+ }, [account?.blockedCids, currentPage]);
+
+ const { hasMoreUpvoted, hasMoreDownvoted, hasMoreHidden } = useMemo(() => {
+ const allUpvotedCids = accountVotes?.filter((vote) => vote.vote === 1).map((vote) => vote.commentCid) || [];
+ const allDownvotedCids = accountVotes?.filter((vote) => vote.vote === -1).map((vote) => vote.commentCid) || [];
+ const allHiddenCids = Object.keys(account?.blockedCids ?? {});
+
+ return {
+ hasMoreUpvoted: currentPage * pageSize < allUpvotedCids.length,
+ hasMoreDownvoted: currentPage * pageSize < allDownvotedCids.length,
+ hasMoreHidden: currentPage * pageSize < allHiddenCids.length,
+ };
+ }, [accountVotes, account?.blockedCids, currentPage]);
+
+ const hasMore = useMemo(() => {
+ if (isInProfileUpvotedView) return hasMoreUpvoted;
+ if (isInProfileDownvotedView) return hasMoreDownvoted;
+ if (isInProfileHiddenView) return hasMoreHidden;
+ return false;
+ }, [hasMoreUpvoted, hasMoreDownvoted, hasMoreHidden, isInProfileUpvotedView, isInProfileDownvotedView, isInProfileHiddenView]);
const { comments: upvotedComments } = useComments({ commentCids: upvotedCommentCids });
const { comments: downvotedComments } = useComments({ commentCids: downvotedCommentCids });
@@ -96,45 +143,51 @@ const Profile = () => {
const [sortType, setSortType] = useState('new');
const handleSortChange = (newSortType: string) => {
setSortType(newSortType);
+ setCurrentPage(1);
};
const comments = useMemo(() => {
- if (isInProfileUpvotedView) {
- return upvotedComments;
- } else if (isInProfileDownvotedView) {
- return downvotedComments;
- } else if (isInCommentsView) {
- return replyComments;
- } else if (isInSubmittedView) {
- return postComments;
- } else if (isInProfileHiddenView) {
- return hiddenComments;
- } else {
- return accountComments;
+ let selectedComments;
+ switch (activeTab) {
+ case 'upvoted':
+ selectedComments = upvotedComments;
+ break;
+ case 'downvoted':
+ selectedComments = downvotedComments;
+ break;
+ case 'hidden':
+ selectedComments = hiddenComments;
+ break;
+ case 'comments':
+ selectedComments = replyComments;
+ break;
+ case 'submitted':
+ selectedComments = postComments;
+ break;
+ case 'overview':
+ default:
+ selectedComments = [...postComments, ...replyComments];
}
- }, [
- isInProfileUpvotedView,
- isInProfileDownvotedView,
- isInProfileHiddenView,
- isInCommentsView,
- isInSubmittedView,
- upvotedComments,
- downvotedComments,
- replyComments,
- postComments,
- hiddenComments,
- accountComments,
- ]);
- const virtuosoData = useMemo(() => {
- let sortedData = [...comments];
- if (sortType === 'new') {
- sortedData.sort((a, b) => b!.timestamp - a!.timestamp);
- } else {
- sortedData.sort((a, b) => a!.timestamp - b!.timestamp);
- }
- return sortedData;
- }, [sortType, comments]);
+ // Sort comments
+ selectedComments.sort((a, b) => (sortType === 'new' ? b!.timestamp - a!.timestamp : a!.timestamp - b!.timestamp));
+
+ return selectedComments;
+ }, [activeTab, upvotedComments, downvotedComments, hiddenComments, replyComments, postComments, sortType]);
+
+ const loadMore = useCallback(() => {
+ console.log('LoadMore called, current page:', currentPage);
+ setCurrentPage((prevPage) => {
+ const newPage = prevPage + 1;
+ console.log('Setting new page:', newPage);
+ return newPage;
+ });
+ }, [currentPage]);
+
+ const profileTitle = account?.author?.displayName ? `${account?.author?.displayName} (u/${account?.author?.shortAddress})` : `u/${account?.author?.shortAddress}`;
+ useEffect(() => {
+ document.title = profileTitle + ' - Seedit';
+ }, [t, profileTitle]);
// save last virtuoso state on each scroll
const virtuosoRef = useRef(null);
@@ -150,28 +203,23 @@ const Profile = () => {
return () => window.removeEventListener('scroll', setLastVirtuosoState);
}, [account?.shortAddress, params.sortType]);
- const profileTitle = account?.author?.displayName ? `${account?.author?.displayName} (u/${account?.author?.shortAddress})` : `u/${account?.author?.shortAddress}`;
- useEffect(() => {
- document.title = profileTitle + ' - Seedit';
- }, [t, profileTitle]);
-
return (
- {account && !accountComments.length ? (
- t('no_posts')
+ {account && comments.length === 0 ? (
+
{t('no_posts')}
) : (
{
- const isReply = post?.parentCid;
- return !isReply ? : ;
- }}
+ data={comments}
+ totalCount={comments.length}
+ itemContent={(index, post) =>
+ post?.parentCid ? :
+ }
+ endReached={hasMore ? loadMore : undefined}
useWindowScroll={true}
ref={virtuosoRef}
restoreStateFrom={lastVirtuosoState}
diff --git a/src/views/settings/account-settings/account-settings.tsx b/src/views/settings/account-settings/account-settings.tsx
index e29eadfc..45e85850 100644
--- a/src/views/settings/account-settings/account-settings.tsx
+++ b/src/views/settings/account-settings/account-settings.tsx
@@ -102,6 +102,7 @@ const AccountSettings = () => {
await importAccount(fileContent);
setSwitchToLastAccount(true);
alert(`Imported ${newAccount.account?.name}`);
+ window.location.reload();
};
reader.readAsText(file);
} catch (error) {
diff --git a/src/views/subplebbit/subplebbit-settings/index.ts b/src/views/subplebbit-settings/index.ts
similarity index 100%
rename from src/views/subplebbit/subplebbit-settings/index.ts
rename to src/views/subplebbit-settings/index.ts
diff --git a/src/views/subplebbit/subplebbit-settings/subplebbit-settings.module.css b/src/views/subplebbit-settings/subplebbit-settings.module.css
similarity index 100%
rename from src/views/subplebbit/subplebbit-settings/subplebbit-settings.module.css
rename to src/views/subplebbit-settings/subplebbit-settings.module.css
diff --git a/src/views/subplebbit/subplebbit-settings/subplebbit-settings.tsx b/src/views/subplebbit-settings/subplebbit-settings.tsx
similarity index 97%
rename from src/views/subplebbit/subplebbit-settings/subplebbit-settings.tsx
rename to src/views/subplebbit-settings/subplebbit-settings.tsx
index a258f2ae..cd1a5010 100644
--- a/src/views/subplebbit/subplebbit-settings/subplebbit-settings.tsx
+++ b/src/views/subplebbit-settings/subplebbit-settings.tsx
@@ -9,17 +9,17 @@ import {
useSubplebbit,
usePublishSubplebbitEdit,
} from '@plebbit/plebbit-react-hooks';
-import { Roles } from '../../../lib/utils/user-utils';
+import { Roles } from '../../lib/utils/user-utils';
import { useTranslation } from 'react-i18next';
import { create } from 'zustand';
import styles from './subplebbit-settings.module.css';
-import { isValidURL } from '../../../lib/utils/url-utils';
-import { isCreateSubplebbitView, isSubplebbitSettingsView } from '../../../lib/utils/view-utils';
-import useChallengesOptions from '../../../hooks/use-challenges-options';
-import useChallengeSettings from '../../../hooks/use-challenge-settings';
-import LoadingEllipsis from '../../../components/loading-ellipsis';
-import Markdown from '../../../components/markdown';
-import Sidebar from '../../../components/sidebar';
+import { isValidURL } from '../../lib/utils/url-utils';
+import { isCreateSubplebbitView, isSubplebbitSettingsView } from '../../lib/utils/view-utils';
+import useChallengesOptions from '../../hooks/use-challenges-options';
+import useChallengeSettings from '../../hooks/use-challenge-settings';
+import LoadingEllipsis from '../../components/loading-ellipsis';
+import Markdown from '../../components/markdown';
+import Sidebar from '../../components/sidebar';
import _ from 'lodash';
type SubplebbitSettingsState = {
@@ -315,7 +315,7 @@ const Moderators = ({ isReadOnly = false }: { isReadOnly?: boolean }) => {
)}
{roles &&
- Object.entries(roles).map(([address, role], index) => (
+ Object.entries(roles)?.map(([address, role], index) => (
{t('moderator')} #{index + 1}
{!isReadOnly &&
(isReadOnly ? {} : handleDeleteModerator(address))} />}
@@ -399,7 +399,7 @@ const ChallengeSettings = ({ challenge, index, isReadOnly, setSubplebbitSettings
const handleOptionChange = (optionName: string, newValue: string) => {
const updatedOptions = { ...options, [optionName]: newValue };
- const updatedChallenges = settings.challenges.map((ch: any, idx: number) => (idx === index ? { ...ch, options: updatedOptions } : ch));
+ const updatedChallenges = settings.challenges?.map((ch: any, idx: number) => (idx === index ? { ...ch, options: updatedOptions } : ch));
setSubplebbitSettingsStore({ settings: { ...settings, challenges: updatedChallenges } });
};
@@ -431,9 +431,9 @@ const ChallengeSettings = ({ challenge, index, isReadOnly, setSubplebbitSettings
};
const handleExcludeChange = (excludeIndex: number, type: keyof Exclude | 'not post' | 'not reply' | 'not vote', value: any) => {
- const updatedChallenges = settings.challenges.map((ch: any, idx: number) => {
+ const updatedChallenges = settings.challenges?.map((ch: any, idx: number) => {
if (idx === index) {
- const updatedExclude = ch.exclude.map((ex: any, exIdx: number) => {
+ const updatedExclude = ch.exclude?.map((ex: any, exIdx: number) => {
if (exIdx === excludeIndex) {
let newEx = { ...ex };
@@ -483,7 +483,7 @@ const ChallengeSettings = ({ challenge, index, isReadOnly, setSubplebbitSettings
const handleExcludeAddress = (excludeIndex: number, value: string) => {
const addresses = value
.split(',')
- .map((addr) => addr.trim())
+ ?.map((addr) => addr.trim())
.filter((addr) => addr !== '');
handleExcludeChange(excludeIndex, 'address', addresses);
};
@@ -498,7 +498,7 @@ const ChallengeSettings = ({ challenge, index, isReadOnly, setSubplebbitSettings
) : (
{challengeSettings?.description}
)}
- {challengeSettings?.optionInputs.map((setting: OptionInput) => (
+ {challengeSettings?.optionInputs?.map((setting: OptionInput) => (
{setting?.label}
@@ -594,7 +594,7 @@ const ChallengeSettings = ({ challenge, index, isReadOnly, setSubplebbitSettings
User's role
Is any of the following:
- {rolesToExclude.map((role) =>
+ {rolesToExclude?.map((role) =>
isReadOnly && !exclude?.role?.includes(role) ? null : (
{isReadOnly ? (
@@ -619,7 +619,7 @@ const ChallengeSettings = ({ challenge, index, isReadOnly, setSubplebbitSettings
User's action
Is all of the following:
- {actionsToExclude.map((action) =>
+ {actionsToExclude?.map((action) =>
isReadOnly && !exclude?.[action] ? null : (
{isReadOnly ? (
@@ -638,7 +638,7 @@ const ChallengeSettings = ({ challenge, index, isReadOnly, setSubplebbitSettings
),
)}
- {nonActionsToExclude.map((nonAction) =>
+ {nonActionsToExclude?.map((nonAction) =>
isReadOnly && exclude?.[nonAction.replace('not ', '')] !== null ? null : (
{isReadOnly ? (
@@ -717,7 +717,7 @@ const Challenges = ({ isReadOnly, readOnlyChallenges }: { isReadOnly: boolean; r
const { t } = useTranslation();
const { settings, setSubplebbitSettingsStore } = useSubplebbitSettingsStore();
const challenges = settings?.challenges || readOnlyChallenges || [];
- const [showSettings, setShowSettings] = useState
(challenges.map(() => false));
+ const [showSettings, setShowSettings] = useState(challenges?.map(() => false));
const challengeOptions = useChallengesOptions();
const location = useLocation();
@@ -764,7 +764,7 @@ const Challenges = ({ isReadOnly, readOnlyChallenges }: { isReadOnly: boolean; r
)}
{challenges.length === 0 && !isInCreateSubplebbitView && {t('warning_spam')}}
- {challenges.map((challenge: any, index: number) => (
+ {challenges?.map((challenge: any, index: number) => (
Challenge #{index + 1}
{!isReadOnly && (isReadOnly ? {} : handleDeleteChallenge(index))} />}
@@ -773,7 +773,7 @@ const Challenges = ({ isReadOnly, readOnlyChallenges }: { isReadOnly: boolean; r
{challenge?.name}
) : (