mirror of
https://github.com/plebbit/seedit.git
synced 2026-02-08 13:00:57 -05:00
@@ -9,7 +9,7 @@
|
||||
"dependencies": {
|
||||
"@capacitor/app": "6.0.1",
|
||||
"@floating-ui/react": "0.26.1",
|
||||
"@plebbit/plebbit-react-hooks": "https://github.com/plebbit/plebbit-react-hooks.git#e6890d342c18045228720ce5a7bed1a349099667",
|
||||
"@plebbit/plebbit-react-hooks": "https://github.com/plebbit/plebbit-react-hooks.git#6d35eb3b4dc84f8fdcbb46d95e3b1d78f1750b5f",
|
||||
"@testing-library/jest-dom": "5.14.1",
|
||||
"@testing-library/react": "13.0.0",
|
||||
"@testing-library/user-event": "13.2.1",
|
||||
|
||||
@@ -25,65 +25,6 @@
|
||||
work correctly both with client-side routing and a non-root public URL.
|
||||
Learn how to configure a non-root public URL by running `npm run build`.
|
||||
-->
|
||||
|
||||
<!-- Preload assets -->
|
||||
<link rel="preload" href="%PUBLIC_URL%/assets/buttons/all_feed_subscribe.png" as="image" type="image/png" />
|
||||
<link rel="preload" href="%PUBLIC_URL%/assets/buttons/all_feed_subscribe_hover.png" as="image" type="image/png" />
|
||||
<link rel="preload" href="%PUBLIC_URL%/assets/buttons/all_feed_subscribed.png" as="image" type="image/png" />
|
||||
<link rel="preload" href="%PUBLIC_URL%/assets/buttons/arrow-up.png" as="image" type="image/png" />
|
||||
<link rel="preload" href="%PUBLIC_URL%/assets/buttons/arrow-upvoted.png" as="image" type="image/png" />
|
||||
<link rel="preload" href="%PUBLIC_URL%/assets/buttons/arrow-down.png" as="image" type="image/png" />
|
||||
<link rel="preload" href="%PUBLIC_URL%/assets/buttons/arrow-downvoted.png" as="image" type="image/png" />
|
||||
<link rel="preload" href="%PUBLIC_URL%/assets/buttons/button-background-green.png" as="image" type="image/png" />
|
||||
<link rel="preload" href="%PUBLIC_URL%/assets/buttons/button-background-red.png" as="image" type="image/png" />
|
||||
<link rel="preload" href="%PUBLIC_URL%/assets/buttons/button-background-dark.png" as="image" type="image/png" />
|
||||
<link rel="preload" href="%PUBLIC_URL%/assets/buttons/button-large-disabled-dark.png" as="image" type="image/png" />
|
||||
<link rel="preload" href="%PUBLIC_URL%/assets/buttons/button-large-disabled.png" as="image" type="image/png" />
|
||||
<link rel="preload" href="%PUBLIC_URL%/assets/buttons/button-large-hover-dark.png" as="image" type="image/png" />
|
||||
<link rel="preload" href="%PUBLIC_URL%/assets/buttons/button-large-hover.png" as="image" type="image/png" />
|
||||
<link rel="preload" href="%PUBLIC_URL%/assets/buttons/button-large-nub-dark.png" as="image" type="image/png" />
|
||||
<link rel="preload" href="%PUBLIC_URL%/assets/buttons/button-large-nub-disabled-dark.png" as="image" type="image/png" />
|
||||
<link rel="preload" href="%PUBLIC_URL%/assets/buttons/button-large-nub-disabled.png" as="image" type="image/png" />
|
||||
<link rel="preload" href="%PUBLIC_URL%/assets/buttons/button-large-nub-hover-dark.png" as="image" type="image/png" />
|
||||
<link rel="preload" href="%PUBLIC_URL%/assets/buttons/button-large-nub-hover.png" as="image" type="image/png" />
|
||||
<link rel="preload" href="%PUBLIC_URL%/assets/buttons/button-large-nub.png" as="image" type="image/png" />
|
||||
<link rel="preload" href="%PUBLIC_URL%/assets/buttons/button-large.png" as="image" type="image/png" />
|
||||
<link rel="preload" href="%PUBLIC_URL%/assets/buttons/close-button.png" as="image" type="image/png" />
|
||||
<link rel="preload" href="%PUBLIC_URL%/assets/buttons/close-button-dark.png" as="image" type="image/png" />
|
||||
<link rel="preload" href="%PUBLIC_URL%/assets/buttons/close-button-hover.png" as="image" type="image/png" />
|
||||
<link rel="preload" href="%PUBLIC_URL%/assets/buttons/close-x-button-large-hover.png" as="image" type="image/png" />
|
||||
<link rel="preload" href="%PUBLIC_URL%/assets/buttons/close-x-button-large.png" as="image" type="image/png" />
|
||||
<link rel="preload" href="%PUBLIC_URL%/assets/buttons/close-x-button.png" as="image" type="image/png" />
|
||||
<link rel="preload" href="%PUBLIC_URL%/assets/buttons/continue-this-thread-arrow-dark.png" as="image" type="image/png" />
|
||||
<link rel="preload" href="%PUBLIC_URL%/assets/buttons/continue-this-thread-arrow.png" as="image" type="image/png" />
|
||||
<link rel="preload" href="%PUBLIC_URL%/assets/buttons/delete-button.png" as="image" type="image/png" />
|
||||
<link rel="preload" href="%PUBLIC_URL%/assets/buttons/droparrowblue.gif" as="image" type="image/gif" />
|
||||
<link rel="preload" href="%PUBLIC_URL%/assets/buttons/droparrowgray.gif" as="image" type="image/gif" />
|
||||
<link rel="preload" href="%PUBLIC_URL%/assets/buttons/play-button-dark.png" as="image" type="image/png" />
|
||||
<link rel="preload" href="%PUBLIC_URL%/assets/buttons/play-button-hover.png" as="image" type="image/png" />
|
||||
<link rel="preload" href="%PUBLIC_URL%/assets/buttons/play-button.png" as="image" type="image/png" />
|
||||
<link rel="preload" href="%PUBLIC_URL%/assets/buttons/text-button-dark.png" as="image" type="image/png" />
|
||||
<link rel="preload" href="%PUBLIC_URL%/assets/buttons/text-button-hover.png" as="image" type="image/png" />
|
||||
<link rel="preload" href="%PUBLIC_URL%/assets/buttons/text-button.png" as="image" type="image/png" />
|
||||
<link rel="preload" href="%PUBLIC_URL%/assets/community_settings.png" as="image" type="image/png" />
|
||||
<link rel="preload" href="%PUBLIC_URL%/assets/indicator-offline.png" as="image" type="image/png" />
|
||||
<link rel="preload" href="%PUBLIC_URL%/assets/indicator-online.png" as="image" type="image/png" />
|
||||
<link rel="preload" href="%PUBLIC_URL%/assets/locked-icon.png" as="image" type="image/png" />
|
||||
<link rel="preload" href="%PUBLIC_URL%/assets/logo/seedit.png" as="image" type="image/png" />
|
||||
<link rel="preload" href="%PUBLIC_URL%/assets/logo/seedit-text-dark.svg" as="image" type="image/svg+xml" />
|
||||
<link rel="preload" href="%PUBLIC_URL%/assets/logo/seedit-text-light.svg" as="image" type="image/svg+xml" />
|
||||
<link rel="preload" href="%PUBLIC_URL%/assets/mail-unread.png" as="image" type="image/png" />
|
||||
<link rel="preload" href="%PUBLIC_URL%/assets/mail.png" as="image" type="image/png" />
|
||||
<link rel="preload" href="%PUBLIC_URL%/assets/mod.png" as="image" type="image/png" />
|
||||
<link rel="preload" href="%PUBLIC_URL%/assets/over18.png" as="image" type="image/png" />
|
||||
<link rel="preload" href="%PUBLIC_URL%/assets/thumbnail-icon-link-dark.png" as="image" type="image/png" />
|
||||
<link rel="preload" href="%PUBLIC_URL%/assets/thumbnail-icon-link.png" as="image" type="image/png" />
|
||||
<link rel="preload" href="%PUBLIC_URL%/assets/thumbnail-icon-nsfw-dark.png" as="image" type="image/png" />
|
||||
<link rel="preload" href="%PUBLIC_URL%/assets/thumbnail-icon-nsfw.png" as="image" type="image/png" />
|
||||
<link rel="preload" href="%PUBLIC_URL%/assets/thumbnail-icon-spoiler-dark.png" as="image" type="image/png" />
|
||||
<link rel="preload" href="%PUBLIC_URL%/assets/thumbnail-icon-spoiler.png" as="image" type="image/png" />
|
||||
<link rel="preload" href="%PUBLIC_URL%/assets/thumbnail-icon-text-dark.png" as="image" type="image/png" />
|
||||
<link rel="preload" href="%PUBLIC_URL%/assets/thumbnail-icon-text.png" as="image" type="image/png" />
|
||||
|
||||
<title>seedit</title>
|
||||
</head>
|
||||
|
||||
@@ -90,7 +90,7 @@ const ModMenu = ({ cid, isCommentAuthorMod }: ModMenuProps) => {
|
||||
...state,
|
||||
commentModeration: {
|
||||
...state.commentModeration,
|
||||
reason: e.target.value ? e.target.value : undefined,
|
||||
reason: e.target.value || '',
|
||||
},
|
||||
}));
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
}
|
||||
|
||||
.label {
|
||||
padding-right: 8px;
|
||||
padding: 0 5px;
|
||||
}
|
||||
|
||||
.black {
|
||||
|
||||
@@ -6,7 +6,7 @@ import { getHasThumbnail } from '../../lib/utils/media-utils';
|
||||
import { getPostScore, formatScore } from '../../lib/utils/post-utils';
|
||||
import { getFormattedTimeAgo, formatLocalizedUTCTimestamp } from '../../lib/utils/time-utils';
|
||||
import { getHostname } from '../../lib/utils/url-utils';
|
||||
import { isAllView, isPostPageView, isProfileHiddenView, isSubplebbitView } from '../../lib/utils/view-utils';
|
||||
import { isAllView, isPostPageView, isProfileHiddenView, isProfileView, isSubplebbitView } from '../../lib/utils/view-utils';
|
||||
import { usePinnedPostsStore } from '../../stores/use-pinned-posts-store';
|
||||
import { useCommentMediaInfo } from '../../hooks/use-comment-media-info';
|
||||
import useDownvote from '../../hooks/use-downvote';
|
||||
@@ -127,6 +127,7 @@ const Post = ({ index, post = {} }: PostProps) => {
|
||||
|
||||
const isInAllView = isAllView(location.pathname);
|
||||
const isInPostPageView = isPostPageView(location.pathname, params);
|
||||
const isInProfileView = isProfileView(location.pathname);
|
||||
const isInProfileHiddenView = isProfileHiddenView(location.pathname);
|
||||
const isInSubplebbitView = isSubplebbitView(location.pathname, params);
|
||||
|
||||
@@ -184,7 +185,7 @@ const Post = ({ index, post = {} }: PostProps) => {
|
||||
</div>
|
||||
<div className={`${styles.container} ${blocked && !isInProfileHiddenView ? styles.hidden : styles.visible}`}>
|
||||
<div className={styles.row}>
|
||||
{!isMobile && isInSubplebbitView && !isInPostPageView && <div className={styles.rank}>{pinned ? undefined : rank}</div>}
|
||||
{!isMobile && !isInProfileView && !isInPostPageView && <div className={styles.rank}>{pinned ? undefined : rank}</div>}
|
||||
<div className={styles.leftcol}>
|
||||
<div className={styles.midcol}>
|
||||
<div className={styles.arrowWrapper}>
|
||||
|
||||
@@ -199,9 +199,6 @@
|
||||
.stateLabel {
|
||||
height: 0;
|
||||
display: inline-block;
|
||||
padding: 0 5px;
|
||||
margin-right: -5px;
|
||||
margin-left: -3px;
|
||||
}
|
||||
|
||||
.moderatorBrackets {
|
||||
|
||||
@@ -365,7 +365,7 @@ const Reply = ({ cidOfReplyWithContext, depth = 0, isSingleComment, isSingleRepl
|
||||
};
|
||||
|
||||
const stateLabel = (
|
||||
<span className={`${styles.stateLabel} ${collapsed ? styles.collapsedStateLabel : ''}`}>
|
||||
<span className={styles.stateLabel}>
|
||||
{state === 'failed' && <Label color='red' text={t('failed')} />}
|
||||
{cid === undefined && state !== 'failed' && <Label color='yellow' text={t('pending')} />}
|
||||
{editState === 'failed' && <Label color='red' text={t('failed_edit')} />}
|
||||
@@ -412,11 +412,13 @@ const Reply = ({ cidOfReplyWithContext, depth = 0, isSingleComment, isSingleRepl
|
||||
<span className={styles.time}>
|
||||
<span title={formatLocalizedUTCTimestamp(timestamp, language)}>{getFormattedTimeAgo(timestamp)}</span>
|
||||
{edit && <span className={styles.timeEdited}> {t('edited_timestamp', { timestamp: getFormattedTimeAgo(edit.timestamp) })}</span>}
|
||||
</span>{' '}
|
||||
</span>
|
||||
{pinned && <span className={styles.pinned}>- {t('stickied_comment')}</span>}
|
||||
{collapsed && (
|
||||
<>
|
||||
<span className={styles.children}>({childrenString})</span> {stateLabel} {state === 'pending' && loadingString}
|
||||
<span className={styles.children}> ({childrenString})</span>
|
||||
{stateLabel}
|
||||
{state === 'pending' && loadingString}
|
||||
</>
|
||||
)}
|
||||
{!collapsed && stateLabel}
|
||||
@@ -426,7 +428,7 @@ const Reply = ({ cidOfReplyWithContext, depth = 0, isSingleComment, isSingleRepl
|
||||
<Flair flair={flair} />
|
||||
</>
|
||||
)}
|
||||
{state === 'pending' && !collapsed && <> {loadingString}</>}
|
||||
{state === 'pending' && !collapsed && loadingString}
|
||||
</p>
|
||||
)}
|
||||
{isInInboxView && (
|
||||
|
||||
@@ -37,14 +37,14 @@ const useSubplebbitSettingsStore = create<SubplebbitSettingsState>((set) => ({
|
||||
}
|
||||
});
|
||||
const editOptions: Partial<SubplebbitSettingsState> = {};
|
||||
if (nextState.title !== undefined) editOptions.title = nextState.title;
|
||||
if (nextState.description !== undefined) editOptions.description = nextState.description;
|
||||
if (nextState.address !== undefined) editOptions.address = nextState.address;
|
||||
if (nextState.title !== undefined) editOptions.title = nextState.title?.trim() === '' ? undefined : nextState.title;
|
||||
if (nextState.description !== undefined) editOptions.description = nextState.description?.trim() === '' ? undefined : nextState.description;
|
||||
if (nextState.address !== undefined) editOptions.address = nextState.address?.trim() === '' ? undefined : nextState.address;
|
||||
if (nextState.suggested !== undefined) editOptions.suggested = nextState.suggested;
|
||||
if (nextState.rules !== undefined) editOptions.rules = nextState.rules;
|
||||
if (nextState.roles !== undefined) editOptions.roles = nextState.roles;
|
||||
if (nextState.settings !== undefined) editOptions.settings = nextState.settings;
|
||||
if (nextState.subplebbitAddress !== undefined) editOptions.subplebbitAddress = nextState.subplebbitAddress;
|
||||
if (nextState.subplebbitAddress !== undefined) editOptions.subplebbitAddress = nextState.subplebbitAddress?.trim() === '' ? undefined : nextState.subplebbitAddress;
|
||||
nextState.publishSubplebbitEditOptions = editOptions;
|
||||
return nextState;
|
||||
}),
|
||||
|
||||
@@ -232,9 +232,9 @@ const PostPage = () => {
|
||||
document.title = `${postTitle || ''}${postTitle && subplebbitTitle ? ' - ' : ''}${subplebbitTitle || ''}${postTitle || subplebbitTitle ? ' - Seedit' : 'Seedit'}`;
|
||||
}, [postTitle, subplebbitTitle]);
|
||||
|
||||
// useEffect(() => {
|
||||
// window.scrollTo(0, 0);
|
||||
// }, []);
|
||||
useEffect(() => {
|
||||
window.scrollTo(0, 0);
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div className={styles.content}>
|
||||
|
||||
@@ -100,7 +100,7 @@ const AvatarSettings = () => {
|
||||
// how to resolve and verify NFT signatures https://github.com/plebbit/plebbit-js/blob/master/docs/nft.md
|
||||
const avatar = {
|
||||
chainTicker: chainTicker?.toLowerCase() || account?.author?.avatar?.chainTicker,
|
||||
timestamp,
|
||||
timestamp: timestamp || account?.author?.avatar?.timestamp,
|
||||
address: tokenAddress || account?.author?.avatar?.address,
|
||||
id: tokenId || account?.author?.avatar?.id,
|
||||
signature: {
|
||||
@@ -200,7 +200,7 @@ const AvatarSettings = () => {
|
||||
autoCorrect='off'
|
||||
autoComplete='off'
|
||||
spellCheck='false'
|
||||
value={timestamp}
|
||||
defaultValue={account?.author?.avatar?.timestamp}
|
||||
onChange={(e) => setTimestamp(Number(e.target.value))}
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -316,6 +316,11 @@
|
||||
padding-left: 10px;
|
||||
}
|
||||
|
||||
.error {
|
||||
color: var(--red);
|
||||
margin: 5px;
|
||||
}
|
||||
|
||||
.logoPreview img {
|
||||
max-height: 40px;
|
||||
padding-left: 10px;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
||||
import { useEffect, useMemo, useRef, useState } from 'react';
|
||||
import { useLocation, useNavigate, useParams } from 'react-router-dom';
|
||||
import { deleteSubplebbit, Role, useAccount, useCreateSubplebbit, usePlebbitRpcSettings, usePublishSubplebbitEdit, useSubplebbit } from '@plebbit/plebbit-react-hooks';
|
||||
import { Roles } from '../../lib/utils/user-utils';
|
||||
@@ -8,7 +8,6 @@ import { isValidURL } from '../../lib/utils/url-utils';
|
||||
import { isCreateSubplebbitView, isSubplebbitSettingsView } from '../../lib/utils/view-utils';
|
||||
import useSubplebbitSettingsStore, { SubplebbitSettingsState } from '../../stores/use-subplebbit-settings-store';
|
||||
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';
|
||||
@@ -65,7 +64,7 @@ const Address = ({ isReadOnly = false }: { isReadOnly?: boolean }) => {
|
||||
const { address, setSubplebbitSettingsStore } = useSubplebbitSettingsStore();
|
||||
|
||||
const alertCryptoAddressInfo = () => {
|
||||
alert(`steps to set a .eth user address:\n1. go to app.ens.domains and search the address\n2. once you own the address, go to its page, click on "records", then "edit records"\n3. add a new text record with name "subplebbit-address" and value: ${address}\n\n steps to set a .sol user address:\n1. go to sns.id and search the address\n2. once you own the address, go to your profile, click the address menu "...", then "create subdomain"\n3. enter subdomain "subplebbit-address" and create\n4. go to subdomain, "content", change content to: ${address}
|
||||
alert(`steps to set a .eth community address:\n1. go to app.ens.domains and search the address\n2. once you own the address, go to its page, click on "records", then "edit records"\n3. add a new text record with name "subplebbit-address" and value: ${address}\n\n steps to set a .sol community address:\n1. go to sns.id and search the address\n2. once you own the address, go to your profile, click the address menu "...", then "create subdomain"\n3. enter subdomain "subplebbit-address" and create\n4. go to subdomain, "content", change content to: ${address}
|
||||
`);
|
||||
};
|
||||
|
||||
@@ -111,9 +110,9 @@ const Logo = ({ isReadOnly = false }: { isReadOnly?: boolean }) => {
|
||||
type='text'
|
||||
value={logoUrl ?? ''}
|
||||
onChange={(e) => {
|
||||
setLogoUrl(e.target.value);
|
||||
setLogoUrl(e.target.value.trim());
|
||||
setImageError(false);
|
||||
setSubplebbitSettingsStore({ suggested: { ...suggested, avatarUrl: e.target.value } });
|
||||
setSubplebbitSettingsStore({ suggested: { ...suggested, avatarUrl: e.target.value.trim() || undefined } });
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
@@ -134,6 +133,7 @@ const Rules = ({ isReadOnly = false }: { isReadOnly?: boolean }) => {
|
||||
const lastRuleRef = useRef(null);
|
||||
|
||||
const handleRuleChange = (index: number, newRule: string) => {
|
||||
if (!rules) return;
|
||||
const updatedRules = [...(rules ?? [])];
|
||||
updatedRules[index] = newRule;
|
||||
setSubplebbitSettingsStore({ rules: updatedRules });
|
||||
@@ -321,6 +321,35 @@ const rolesToExclude = ['moderator', 'admin', 'owner'];
|
||||
const actionsToExclude: Array<'post' | 'reply' | 'vote'> = ['post', 'reply', 'vote'];
|
||||
const nonActionsToExclude: Array<'not post' | 'not reply' | 'not vote'> = ['not post', 'not reply', 'not vote'];
|
||||
|
||||
const ExcludeAddressesFromChallengeInput = ({
|
||||
exclude,
|
||||
excludeIndex,
|
||||
handleExcludeAddress,
|
||||
isReadOnly,
|
||||
}: {
|
||||
exclude: any;
|
||||
excludeIndex: number;
|
||||
handleExcludeAddress: (index: number, value: string) => void;
|
||||
isReadOnly: boolean;
|
||||
}) => {
|
||||
const [addressInput, setAddressInput] = useState(exclude?.address?.join(', ') || '');
|
||||
|
||||
return isReadOnly ? (
|
||||
<span>{exclude?.address?.join(', ')}</span>
|
||||
) : (
|
||||
<input
|
||||
type='text'
|
||||
placeholder='address1.eth, address2.eth, address3.eth'
|
||||
value={addressInput}
|
||||
onChange={(e) => {
|
||||
const newValue = e.target.value;
|
||||
setAddressInput(newValue);
|
||||
handleExcludeAddress(excludeIndex, newValue);
|
||||
}}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
const ChallengeSettings = ({ challenge, challengesSettings, index, isReadOnly, setSubplebbitSettingsStore, settings, showSettings }: ChallengeSettingsProps) => {
|
||||
const { name, options } = challenge || {};
|
||||
const challengeSettings = challengesSettings[name];
|
||||
@@ -414,9 +443,10 @@ const ChallengeSettings = ({ challenge, challengesSettings, index, isReadOnly, s
|
||||
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);
|
||||
|
||||
handleExcludeChange(excludeIndex, 'address', addresses.length > 0 ? addresses : undefined);
|
||||
};
|
||||
|
||||
return (
|
||||
@@ -469,16 +499,12 @@ const ChallengeSettings = ({ challenge, challengesSettings, index, isReadOnly, s
|
||||
<div className={styles.challengeOption}>
|
||||
User's address
|
||||
<div className={styles.challengeOptionDescription}>Is one of the following:</div>
|
||||
{isReadOnly ? (
|
||||
<span>{exclude?.address?.join(', ')}</span>
|
||||
) : (
|
||||
<input
|
||||
type='text'
|
||||
placeholder='address1.eth, address2.eth, address3.eth'
|
||||
value={exclude?.address?.join(', ')}
|
||||
onChange={(e) => handleExcludeAddress(excludeIndex, e.target.value)}
|
||||
/>
|
||||
)}
|
||||
<ExcludeAddressesFromChallengeInput
|
||||
exclude={exclude}
|
||||
excludeIndex={excludeIndex}
|
||||
handleExcludeAddress={handleExcludeAddress}
|
||||
isReadOnly={isReadOnly}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
{isReadOnly && !(exclude?.postScore || exclude?.replyScore) ? null : (
|
||||
@@ -657,12 +683,38 @@ const Challenges = ({
|
||||
}) => {
|
||||
const { t } = useTranslation();
|
||||
const { settings, setSubplebbitSettingsStore } = useSubplebbitSettingsStore();
|
||||
const location = useLocation();
|
||||
const isInCreateSubplebbitView = isCreateSubplebbitView(location.pathname);
|
||||
const challenges = settings?.challenges || readOnlyChallenges || [];
|
||||
const [showSettings, setShowSettings] = useState<boolean[]>(challenges?.map(() => false));
|
||||
const challengeOptions = useChallengesOptions();
|
||||
|
||||
const location = useLocation();
|
||||
const isInCreateSubplebbitView = isCreateSubplebbitView(location.pathname);
|
||||
const hasSetDefaultChallenge = useRef(false);
|
||||
const valuesRef = useRef({ settings, setSubplebbitSettingsStore });
|
||||
|
||||
useEffect(() => {
|
||||
valuesRef.current = { settings, setSubplebbitSettingsStore };
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
if (isInCreateSubplebbitView && !hasSetDefaultChallenge.current && challengeOptions && challengesSettings && !valuesRef.current.settings?.challenges?.length) {
|
||||
const defaultChallengeName = challengesSettings?.['captcha-canvas-v3'] ? 'captcha-canvas-v3' : challengeNames?.[0] || Object.keys(challengeOptions)[0];
|
||||
console.log('Setting default challenge:', defaultChallengeName);
|
||||
const defaultChallenge = {
|
||||
name: defaultChallengeName,
|
||||
options: challengeOptions[defaultChallengeName] || {},
|
||||
};
|
||||
|
||||
valuesRef.current.setSubplebbitSettingsStore({
|
||||
settings: {
|
||||
...valuesRef.current.settings,
|
||||
challenges: [defaultChallenge],
|
||||
},
|
||||
});
|
||||
|
||||
hasSetDefaultChallenge.current = true;
|
||||
}
|
||||
}, [isInCreateSubplebbitView, challengeOptions, challengesSettings, challengeNames]);
|
||||
|
||||
const toggleSettings = (index: number) => {
|
||||
const newShowSettings = [...showSettings];
|
||||
@@ -689,9 +741,16 @@ const Challenges = ({
|
||||
|
||||
const handleChallengeTypeChange = (index: number, newType: string) => {
|
||||
const options = challengeOptions[newType] || {};
|
||||
const updatedChallenges = [...challenges];
|
||||
const currentChallenges = challenges || [];
|
||||
const updatedChallenges = [...currentChallenges];
|
||||
updatedChallenges[index] = { ...updatedChallenges[index], name: newType, options };
|
||||
setSubplebbitSettingsStore({ settings: { ...settings, challenges: updatedChallenges } });
|
||||
|
||||
setSubplebbitSettingsStore({
|
||||
settings: {
|
||||
...settings,
|
||||
challenges: updatedChallenges,
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
@@ -794,16 +853,21 @@ const SubplebbitSettings = () => {
|
||||
const isReadOnly = (!settings && isInSubplebbitSettingsView) || (!isOnFullNode && isInCreateSubplebbitView);
|
||||
|
||||
const { publishSubplebbitEditOptions, resetSubplebbitSettingsStore, setSubplebbitSettingsStore } = useSubplebbitSettingsStore();
|
||||
const { publishSubplebbitEdit } = usePublishSubplebbitEdit(publishSubplebbitEditOptions);
|
||||
const { error, publishSubplebbitEdit } = usePublishSubplebbitEdit(publishSubplebbitEditOptions);
|
||||
const { createdSubplebbit, createSubplebbit } = useCreateSubplebbit(publishSubplebbitEditOptions);
|
||||
|
||||
const [showSaving, setShowSaving] = useState(false);
|
||||
const saveSubplebbit = async () => {
|
||||
try {
|
||||
setShowSaving(true);
|
||||
console.log('Saving subplebbit with options:', publishSubplebbitEditOptions);
|
||||
await publishSubplebbitEdit();
|
||||
setShowSaving(false);
|
||||
alert(t('settings_saved', { subplebbitAddress }));
|
||||
if (error) {
|
||||
alert(error.message || 'Error: ' + error);
|
||||
} else {
|
||||
alert(t('settings_saved', { subplebbitAddress }));
|
||||
}
|
||||
} catch (e) {
|
||||
if (e instanceof Error) {
|
||||
console.warn(e);
|
||||
@@ -865,35 +929,6 @@ const SubplebbitSettings = () => {
|
||||
|
||||
const { challenges: rpcChallenges } = usePlebbitRpcSettings().plebbitRpcSettings || {};
|
||||
const challengeNames = Object.keys(rpcChallenges || {});
|
||||
const defaultChallengeName: string | undefined = challenges?.['captcha-canvas-v3'] ? 'captcha-canvas-v3' : challengeNames[0];
|
||||
const defaultChallengeSettings = useChallengeSettings(defaultChallengeName);
|
||||
const defaultChallengeOptions = useChallengesOptions()[defaultChallengeName];
|
||||
|
||||
const setDefaultChallenge = useCallback(() => {
|
||||
if (defaultChallengeSettings && defaultChallengeName && !settings?.challenges?.length) {
|
||||
const defaultChallenge = {
|
||||
...defaultChallengeSettings,
|
||||
name: defaultChallengeName,
|
||||
options: defaultChallengeOptions,
|
||||
};
|
||||
|
||||
if (!settings?.challenges?.length) {
|
||||
setSubplebbitSettingsStore({
|
||||
settings: {
|
||||
...settings,
|
||||
challenges: [defaultChallenge],
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
}, [defaultChallengeSettings, defaultChallengeName, defaultChallengeOptions, setSubplebbitSettingsStore, settings]);
|
||||
|
||||
useEffect(() => {
|
||||
if (isInCreateSubplebbitView) {
|
||||
setDefaultChallenge();
|
||||
}
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [isInCreateSubplebbitView]);
|
||||
|
||||
useEffect(() => {
|
||||
window.scrollTo(0, 0);
|
||||
@@ -913,6 +948,11 @@ const SubplebbitSettings = () => {
|
||||
document.title = documentTitle;
|
||||
}, [documentTitle]);
|
||||
|
||||
const handleCreateSubplebbit = () => {
|
||||
console.log('Creating subplebbit with settings:', publishSubplebbitEditOptions);
|
||||
createSubplebbit();
|
||||
};
|
||||
|
||||
if (!hasLoaded && !isInCreateSubplebbitView) {
|
||||
return (
|
||||
<div className={styles.loading}>
|
||||
@@ -935,9 +975,7 @@ const SubplebbitSettings = () => {
|
||||
<Logo isReadOnly={isReadOnly} />
|
||||
<Rules isReadOnly={isReadOnly} />
|
||||
<Moderators isReadOnly={isReadOnly} />
|
||||
{!isInCreateSubplebbitView && (
|
||||
<Challenges isReadOnly={isReadOnly} readOnlyChallenges={subplebbit?.challenges} challengeNames={challengeNames} challengesSettings={rpcChallenges} />
|
||||
)}
|
||||
<Challenges isReadOnly={isReadOnly} readOnlyChallenges={subplebbit?.challenges} challengeNames={challengeNames} challengesSettings={rpcChallenges} />
|
||||
{!isInCreateSubplebbitView && <JSONSettings isReadOnly={isReadOnly} />}
|
||||
<div className={styles.saveOptions}>
|
||||
{!isInCreateSubplebbitView && !isReadOnly && (
|
||||
@@ -955,11 +993,12 @@ const SubplebbitSettings = () => {
|
||||
</div>
|
||||
)}
|
||||
{!isReadOnly && (
|
||||
<button onClick={() => (isInCreateSubplebbitView ? createSubplebbit() : saveSubplebbit())} disabled={showSaving || showDeleting}>
|
||||
<button onClick={() => (isInCreateSubplebbitView ? handleCreateSubplebbit() : saveSubplebbit())} disabled={showSaving || showDeleting}>
|
||||
{isInCreateSubplebbitView ? t('create_community') : t('save_options')}
|
||||
</button>
|
||||
)}
|
||||
{showSaving && <LoadingEllipsis string={t('saving')} />}
|
||||
{error && <div className={styles.error}>error: {error.message || 'unknown error'}</div>}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user