From c383d90c5f711fcb83d02cbf99e9a10f6f50ac4f Mon Sep 17 00:00:00 2001 From: "plebeius.eth" Date: Fri, 19 Apr 2024 17:35:31 +0200 Subject: [PATCH 1/8] fix(home): remove feed render delay for subscriptions --- src/lib/utils/addresses-utils.ts | 15 +++++++++++++++ src/views/home/home.tsx | 17 ++++------------- 2 files changed, 19 insertions(+), 13 deletions(-) diff --git a/src/lib/utils/addresses-utils.ts b/src/lib/utils/addresses-utils.ts index 3fa7d031..7cfde7d5 100644 --- a/src/lib/utils/addresses-utils.ts +++ b/src/lib/utils/addresses-utils.ts @@ -25,6 +25,21 @@ export const useDefaultSubplebbitAddresses = () => { return useMemo(() => defaultSubplebbits.map((subplebbit: Subplebbit) => subplebbit.address), [defaultSubplebbits]); }; +export const useDefaultAndSubscriptionsSubplebbitAddresses = () => { + const subscriptions = useAccount()?.subscriptions ?? []; + const defaultSubplebbitAddresses = useDefaultSubplebbitAddresses(); + + return useMemo(() => { + const subplebbitAddresses = new Set(defaultSubplebbitAddresses); + + subscriptions.forEach((address: string) => { + subplebbitAddresses.add(address); + }); + + return Array.from(subplebbitAddresses); + }, [subscriptions, defaultSubplebbitAddresses]); +}; + export const useDefaultAndSubscriptionsSubplebbits = (): SubplebbitWithDisplay[] => { const account = useAccount(); const { subplebbitAddress: subplebbitAddressParam } = useParams(); diff --git a/src/views/home/home.tsx b/src/views/home/home.tsx index 1619bbd5..eca0c001 100644 --- a/src/views/home/home.tsx +++ b/src/views/home/home.tsx @@ -1,13 +1,13 @@ -import { useEffect, useRef, useState } from 'react'; +import { useEffect, useRef } from 'react'; import { useParams } from 'react-router-dom'; import { Virtuoso, VirtuosoHandle, StateSnapshot } from 'react-virtuoso'; -import { useAccount, useFeed } from '@plebbit/plebbit-react-hooks'; +import { useFeed } from '@plebbit/plebbit-react-hooks'; import { useTranslation } from 'react-i18next'; import styles from './home.module.css'; import LoadingEllipsis from '../../components/loading-ellipsis'; import Post from '../../components/post'; import Sidebar from '../../components/sidebar'; -import { useDefaultSubplebbitAddresses } from '../../lib/utils/addresses-utils'; +import { useDefaultAndSubscriptionsSubplebbitAddresses } from '../../lib/utils/addresses-utils'; import useFeedStateString from '../../hooks/use-feed-state-string'; import useTimeFilter, { TimeFilterKey } from '../../hooks/use-time-filter'; @@ -15,16 +15,7 @@ const lastVirtuosoStates: { [key: string]: StateSnapshot } = {}; const Home = () => { const { t } = useTranslation(); - const account = useAccount(); - const defaultSubplebbitAddresses = useDefaultSubplebbitAddresses(); - const [subplebbitAddresses, setSubplebbitAddresses] = useState(undefined); - - useEffect(() => { - if (defaultSubplebbitAddresses && account?.subscriptions) { - setSubplebbitAddresses(defaultSubplebbitAddresses.concat(account.subscriptions)); - } - }, [defaultSubplebbitAddresses, account?.subscriptions]); - + const subplebbitAddresses = useDefaultAndSubscriptionsSubplebbitAddresses(); const params = useParams<{ sortType?: string; timeFilterName?: string }>(); const sortType = params?.sortType || 'hot'; const timeFilterName = params.timeFilterName as TimeFilterKey; From 028a6e5e0bf06c29fb022dc81c082baa5dbd498c Mon Sep 17 00:00:00 2001 From: "plebeius.eth" Date: Fri, 19 Apr 2024 17:46:52 +0200 Subject: [PATCH 2/8] refactor: move addresses hooks in use-default-subplebbits --- src/components/topbar/topbar.tsx | 2 +- src/hooks/use-default-subplebbits.ts | 77 +++++++++++++++++++++++- src/lib/utils/addresses-utils.ts | 87 --------------------------- src/views/all/all.tsx | 2 +- src/views/home/home.tsx | 2 +- src/views/submit-page/submit-page.tsx | 7 ++- src/views/subplebbits/subplebbits.tsx | 2 +- 7 files changed, 84 insertions(+), 95 deletions(-) delete mode 100644 src/lib/utils/addresses-utils.ts diff --git a/src/components/topbar/topbar.tsx b/src/components/topbar/topbar.tsx index 90a9fa8e..4c4b1860 100644 --- a/src/components/topbar/topbar.tsx +++ b/src/components/topbar/topbar.tsx @@ -4,7 +4,7 @@ import { useTranslation } from 'react-i18next'; import { useAccount } from '@plebbit/plebbit-react-hooks'; import Plebbit from '@plebbit/plebbit-js/dist/browser/index.js'; import styles from './topbar.module.css'; -import { useDefaultSubplebbitAddresses } from '../../lib/utils/addresses-utils'; +import { useDefaultSubplebbitAddresses } from '../../hooks/use-default-subplebbits'; import useTimeFilter, { TimeFilterKey } from '../../hooks/use-time-filter'; import { isAllView, isHomeView, isSubplebbitView } from '../../lib/utils/view-utils'; diff --git a/src/hooks/use-default-subplebbits.ts b/src/hooks/use-default-subplebbits.ts index 9bf9173f..1e64fac6 100644 --- a/src/hooks/use-default-subplebbits.ts +++ b/src/hooks/use-default-subplebbits.ts @@ -1,4 +1,7 @@ -import { useState, useEffect } from 'react'; +import { useEffect, useMemo, useState } from 'react'; +import { useParams } from 'react-router-dom'; +import { useAccount } from '@plebbit/plebbit-react-hooks'; +import Plebbit from '@plebbit/plebbit-js/dist/browser/index.js'; interface Subplebbit { title?: string; @@ -7,9 +10,13 @@ interface Subplebbit { features?: string[]; } +export interface SubplebbitWithDisplay extends Subplebbit { + displayAddress: string; +} + let cache: Subplebbit[] | null = null; -const useDefaultSubplebbits = () => { +export const useDefaultSubplebbits = () => { const [subplebbits, setSubplebbits] = useState([]); useEffect(() => { @@ -33,4 +40,68 @@ const useDefaultSubplebbits = () => { return cache || subplebbits; }; -export default useDefaultSubplebbits; +export const useDefaultSubplebbitAddresses = () => { + const defaultSubplebbits = useDefaultSubplebbits(); + return useMemo(() => defaultSubplebbits.map((subplebbit: Subplebbit) => subplebbit.address), [defaultSubplebbits]); +}; + +export const useDefaultAndSubscriptionsSubplebbitAddresses = () => { + const subscriptions = useAccount()?.subscriptions ?? []; + const defaultSubplebbitAddresses = useDefaultSubplebbitAddresses(); + + return useMemo(() => { + const subplebbitAddresses = new Set(defaultSubplebbitAddresses); + + subscriptions.forEach((address: string) => { + subplebbitAddresses.add(address); + }); + + return Array.from(subplebbitAddresses); + }, [subscriptions, defaultSubplebbitAddresses]); +}; + +export const useDefaultAndSubscriptionsSubplebbits = (): SubplebbitWithDisplay[] => { + const account = useAccount(); + const { subplebbitAddress: subplebbitAddressParam } = useParams(); + const defaultSubplebbits = useDefaultSubplebbits(); + + return useMemo(() => { + const subplebbitsObj: { [key: string]: SubplebbitWithDisplay } = {}; + + const addSubplebbit = (subplebbit: Subplebbit) => { + let displayAddress = subplebbit.address.includes('.') ? subplebbit.address : Plebbit.getShortAddress(subplebbit.address); + + // Append title in parentheses only if the address doesn't contain '.' + if (!subplebbit.address.includes('.') && subplebbit.title) { + displayAddress += ` (${subplebbit.title})`; + } + + if (displayAddress.length > 40) { + displayAddress = displayAddress.substring(0, 37) + '...'; + } + + subplebbitsObj[subplebbit.address] = { ...subplebbit, displayAddress }; + }; + + // Add default subplebbits + defaultSubplebbits.forEach((subplebbit) => { + if (subplebbit.address) { + addSubplebbit(subplebbit); + } + }); + + // Add subscribed subplebbits + account?.subscriptions?.forEach((address: string) => { + if (!subplebbitsObj[address]) { + addSubplebbit({ address }); + } + }); + + // Add the current subplebbit if not already in the list + if (subplebbitAddressParam && !subplebbitsObj[subplebbitAddressParam]) { + addSubplebbit({ address: subplebbitAddressParam }); + } + + return Object.values(subplebbitsObj); + }, [account?.subscriptions, defaultSubplebbits, subplebbitAddressParam]); +}; diff --git a/src/lib/utils/addresses-utils.ts b/src/lib/utils/addresses-utils.ts deleted file mode 100644 index 7cfde7d5..00000000 --- a/src/lib/utils/addresses-utils.ts +++ /dev/null @@ -1,87 +0,0 @@ -import { useMemo } from 'react'; -import { useParams } from 'react-router-dom'; -import { useAccount } from '@plebbit/plebbit-react-hooks'; -import Plebbit from '@plebbit/plebbit-js/dist/browser/index.js'; -import useDefaultSubplebbits from '../../hooks/use-default-subplebbits'; - -interface Subplebbit { - title?: string; - address: string; - tags?: string[]; - features?: string[]; -} - -export interface SubplebbitWithDisplay extends Subplebbit { - displayAddress: string; -} - -export const getRandomSubplebbits = (addresses: string[], count: number) => { - let shuffled = addresses.sort(() => 0.5 - Math.random()); - return shuffled.slice(0, count); -}; - -export const useDefaultSubplebbitAddresses = () => { - const defaultSubplebbits = useDefaultSubplebbits(); - return useMemo(() => defaultSubplebbits.map((subplebbit: Subplebbit) => subplebbit.address), [defaultSubplebbits]); -}; - -export const useDefaultAndSubscriptionsSubplebbitAddresses = () => { - const subscriptions = useAccount()?.subscriptions ?? []; - const defaultSubplebbitAddresses = useDefaultSubplebbitAddresses(); - - return useMemo(() => { - const subplebbitAddresses = new Set(defaultSubplebbitAddresses); - - subscriptions.forEach((address: string) => { - subplebbitAddresses.add(address); - }); - - return Array.from(subplebbitAddresses); - }, [subscriptions, defaultSubplebbitAddresses]); -}; - -export const useDefaultAndSubscriptionsSubplebbits = (): SubplebbitWithDisplay[] => { - const account = useAccount(); - const { subplebbitAddress: subplebbitAddressParam } = useParams(); - const defaultSubplebbits = useDefaultSubplebbits(); - - return useMemo(() => { - const subplebbitsObj: { [key: string]: SubplebbitWithDisplay } = {}; - - const addSubplebbit = (subplebbit: Subplebbit) => { - let displayAddress = subplebbit.address.includes('.') ? subplebbit.address : Plebbit.getShortAddress(subplebbit.address); - - // Append title in parentheses only if the address doesn't contain '.' - if (!subplebbit.address.includes('.') && subplebbit.title) { - displayAddress += ` (${subplebbit.title})`; - } - - if (displayAddress.length > 40) { - displayAddress = displayAddress.substring(0, 37) + '...'; - } - - subplebbitsObj[subplebbit.address] = { ...subplebbit, displayAddress }; - }; - - // Add default subplebbits - defaultSubplebbits.forEach((subplebbit) => { - if (subplebbit.address) { - addSubplebbit(subplebbit); - } - }); - - // Add subscribed subplebbits - account?.subscriptions?.forEach((address: string) => { - if (!subplebbitsObj[address]) { - addSubplebbit({ address }); - } - }); - - // Add the current subplebbit if not already in the list - if (subplebbitAddressParam && !subplebbitsObj[subplebbitAddressParam]) { - addSubplebbit({ address: subplebbitAddressParam }); - } - - return Object.values(subplebbitsObj); - }, [account?.subscriptions, defaultSubplebbits, subplebbitAddressParam]); -}; diff --git a/src/views/all/all.tsx b/src/views/all/all.tsx index 707535fe..e7e8a9c2 100644 --- a/src/views/all/all.tsx +++ b/src/views/all/all.tsx @@ -7,7 +7,7 @@ import styles from '../home/home.module.css'; import LoadingEllipsis from '../../components/loading-ellipsis'; import Post from '../../components/post'; import Sidebar from '../../components/sidebar'; -import { useDefaultSubplebbitAddresses } from '../../lib/utils/addresses-utils'; +import { useDefaultSubplebbitAddresses } from '../../hooks/use-default-subplebbits'; import useFeedStateString from '../../hooks/use-feed-state-string'; import useTimeFilter, { TimeFilterKey } from '../../hooks/use-time-filter'; import _ from 'lodash'; diff --git a/src/views/home/home.tsx b/src/views/home/home.tsx index eca0c001..038472d0 100644 --- a/src/views/home/home.tsx +++ b/src/views/home/home.tsx @@ -7,7 +7,7 @@ import styles from './home.module.css'; import LoadingEllipsis from '../../components/loading-ellipsis'; import Post from '../../components/post'; import Sidebar from '../../components/sidebar'; -import { useDefaultAndSubscriptionsSubplebbitAddresses } from '../../lib/utils/addresses-utils'; +import { useDefaultAndSubscriptionsSubplebbitAddresses } from '../../hooks/use-default-subplebbits'; import useFeedStateString from '../../hooks/use-feed-state-string'; import useTimeFilter, { TimeFilterKey } from '../../hooks/use-time-filter'; diff --git a/src/views/submit-page/submit-page.tsx b/src/views/submit-page/submit-page.tsx index b605d6d5..bc79cc93 100644 --- a/src/views/submit-page/submit-page.tsx +++ b/src/views/submit-page/submit-page.tsx @@ -4,7 +4,7 @@ import { PublishCommentOptions, useAccount, usePublishComment, useSubplebbit } f import Plebbit from '@plebbit/plebbit-js/dist/browser/index.js'; import { Trans, useTranslation } from 'react-i18next'; import { create } from 'zustand'; -import { getRandomSubplebbits, useDefaultSubplebbitAddresses } from '../../lib/utils/addresses-utils'; +import { useDefaultSubplebbitAddresses } from '../../hooks/use-default-subplebbits'; import { alertChallengeVerificationFailed } from '../../lib/utils/challenge-utils'; import { getLinkMediaInfo } from '../../lib/utils/media-utils'; import { isValidURL } from '../../lib/utils/url-utils'; @@ -157,6 +157,11 @@ const Submit = () => { const subsDescription =
{subscriptions?.length > 5 ? t('submit_subscriptions') : t('submit_subscriptions_notice')}
; + const getRandomSubplebbits = (addresses: string[], count: number) => { + let shuffled = addresses.sort(() => 0.5 - Math.random()); + return shuffled.slice(0, count); + }; + const [randomSubplebbits, setRandomSubplebbits] = useState([]); useEffect(() => { // Generate random subplebbits only once when the component mounts diff --git a/src/views/subplebbits/subplebbits.tsx b/src/views/subplebbits/subplebbits.tsx index 2d3af546..d6c3132f 100644 --- a/src/views/subplebbits/subplebbits.tsx +++ b/src/views/subplebbits/subplebbits.tsx @@ -14,7 +14,7 @@ import { isSubplebbitsVotePassingView, isSubplebbitsVoteRejectingView, } from '../../lib/utils/view-utils'; -import { useDefaultSubplebbitAddresses } from '../../lib/utils/addresses-utils'; +import { useDefaultSubplebbitAddresses } from '../../hooks/use-default-subplebbits'; import Markdown from '../../components/markdown'; import Label from '../../components/post/label'; import Sidebar from '../../components/sidebar'; From 25ff98e09543195e9f5f5a30026d3ffc187a5871 Mon Sep 17 00:00:00 2001 From: "plebeius.eth" Date: Sat, 20 Apr 2024 22:12:31 +0200 Subject: [PATCH 3/8] feat(settings): add plebbit options route --- src/app.tsx | 1 + src/components/header/header.module.css | 2 +- src/components/header/header.tsx | 30 ++++++++- src/lib/utils/view-utils.ts | 4 ++ src/views/settings/plebbit-options/index.ts | 1 + .../plebbit-options.module.css | 29 ++++++++ .../plebbit-options/plebbit-options.tsx | 67 +++++++++++++++++++ src/views/settings/settings.tsx | 34 ++++++---- 8 files changed, 153 insertions(+), 15 deletions(-) create mode 100644 src/views/settings/plebbit-options/index.ts create mode 100644 src/views/settings/plebbit-options/plebbit-options.module.css create mode 100644 src/views/settings/plebbit-options/plebbit-options.tsx diff --git a/src/app.tsx b/src/app.tsx index b08be450..c7cf68b9 100644 --- a/src/app.tsx +++ b/src/app.tsx @@ -113,6 +113,7 @@ const App = () => { } /> } /> + } /> } /> diff --git a/src/components/header/header.module.css b/src/components/header/header.module.css index ad85da1a..bd2daa5c 100644 --- a/src/components/header/header.module.css +++ b/src/components/header/header.module.css @@ -131,7 +131,7 @@ .tabMenu li .choice { color: var(--text-primary); background-color: var(--background-secondary); - border-bottom: 0px solid var(--border-primary); + border-bottom: 1px solid var(--border-primary); } .tabs { diff --git a/src/components/header/header.tsx b/src/components/header/header.tsx index 2aecd3b7..d6c970a4 100644 --- a/src/components/header/header.tsx +++ b/src/components/header/header.tsx @@ -34,6 +34,7 @@ import { isSubplebbitsVoteView, isSubplebbitsOwnerView, isProfileUpvotedView, + isSettingsPlebbitOptionsView, } from '../../lib/utils/view-utils'; import useTheme from '../../hooks/use-theme'; import { TimeFilterKey } from '../../hooks/use-time-filter'; @@ -243,6 +244,26 @@ const SubplebbitsHeaderTabs = () => { ); }; +const SettingsHeaderTabs = () => { + const { t } = useTranslation(); + const isInSettingsPlebbitOptionsView = isSettingsPlebbitOptionsView(useLocation().pathname); + + return ( + <> +
  • + + {t('general')} + +
  • +
  • + + {t('plebbit_options')} + +
  • + + ); +}; + const HeaderTabs = () => { const { t } = useTranslation(); const params = useParams(); @@ -260,6 +281,8 @@ const HeaderTabs = () => { const isInSubplebbitSubmitView = isSubplebbitSubmitView(location.pathname, params); const isInSubplebbitsView = isSubplebbitsView(location.pathname); const isInCreateSubplebbitView = isCreateSubplebbitView(location.pathname); + const isInSettingsView = isSettingsView(location.pathname); + const isInSettingsPlebbitOptionsView = isSettingsPlebbitOptionsView(location.pathname); if (isInPostView) { return ; @@ -273,6 +296,8 @@ const HeaderTabs = () => { return ; } else if (isInSubplebbitsView && !isInCreateSubplebbitView) { return ; + } else if (isInSettingsView || isInSettingsPlebbitOptionsView) { + return ; } return null; }; @@ -288,6 +313,7 @@ const HeaderTitle = ({ title, shortAddress }: { title: string; shortAddress: str const isInPostView = isPostView(location.pathname, params); const isInProfileView = isProfileView(location.pathname); const isInSettingsView = isSettingsView(location.pathname); + const isInSettingsPlebbitOptionsView = isSettingsPlebbitOptionsView(location.pathname); const isInSubmitView = isSubmitView(location.pathname); const isInSubplebbitView = isSubplebbitView(location.pathname, params); const isInSubplebbitSubmitView = isSubplebbitSubmitView(location.pathname, params); @@ -317,7 +343,7 @@ const HeaderTitle = ({ title, shortAddress }: { title: string; shortAddress: str ); } else if (isInSubmitView) { return submitTitle; - } else if (isInSettingsView) { + } else if (isInSettingsView || isInSettingsPlebbitOptionsView) { return t('preferences'); } else if (isInProfileView) { return profileTitle; @@ -360,7 +386,7 @@ const Header = () => { const isInSubplebbitSettingsView = isSubplebbitSettingsView(location.pathname, params); const isInNotFoundView = useNotFoundStore((state) => state.isNotFound); - const hasFewTabs = isInPostView || isInSubmitView || isInSubplebbitSubmitView || isInSubplebbitSettingsView || isInSettingsView || isInInboxView; + const hasFewTabs = isInPostView || isInSubmitView || isInSubplebbitSubmitView || isInSubplebbitSettingsView || isInSettingsView || isInInboxView || isInSettingsView; const hasStickyHeader = isInHomeView || isInNotFoundView || diff --git a/src/lib/utils/view-utils.ts b/src/lib/utils/view-utils.ts index 12c56139..e31bbb2a 100644 --- a/src/lib/utils/view-utils.ts +++ b/src/lib/utils/view-utils.ts @@ -126,6 +126,10 @@ export const isSettingsView = (pathname: string): boolean => { return pathname === '/settings'; }; +export const isSettingsPlebbitOptionsView = (pathname: string): boolean => { + return pathname === '/settings/plebbit-options'; +}; + export const isSubmitView = (pathname: string): boolean => { return pathname === '/submit'; }; diff --git a/src/views/settings/plebbit-options/index.ts b/src/views/settings/plebbit-options/index.ts new file mode 100644 index 00000000..705f8559 --- /dev/null +++ b/src/views/settings/plebbit-options/index.ts @@ -0,0 +1 @@ +export { default } from './plebbit-options'; diff --git a/src/views/settings/plebbit-options/plebbit-options.module.css b/src/views/settings/plebbit-options/plebbit-options.module.css new file mode 100644 index 00000000..1b3843fe --- /dev/null +++ b/src/views/settings/plebbit-options/plebbit-options.module.css @@ -0,0 +1,29 @@ +.content { + margin: 7px 5px 40px 5px; + font-size: 12px; + color: var(--text); + width: 100%; +} + +.category { + display: flex; + align-items: flex-start; +} + +.categoryTitle { + flex: 0 0 169px; + height: 100%; + padding: 10px; + font-weight: bold; + text-align: right; + text-transform: lowercase; +} + +.categorySettings { + flex-grow: 1; + padding: 10px 0; +} + +.settingTitle { + font-style: italic; +} \ No newline at end of file diff --git a/src/views/settings/plebbit-options/plebbit-options.tsx b/src/views/settings/plebbit-options/plebbit-options.tsx new file mode 100644 index 00000000..60f28b11 --- /dev/null +++ b/src/views/settings/plebbit-options/plebbit-options.tsx @@ -0,0 +1,67 @@ +import styles from './plebbit-options.module.css'; +import { useTranslation } from 'react-i18next'; + +const PlebbitRPCSettings = () => { + const { t } = useTranslation(); + + return
    ; +}; + +const IPFSGatewaysSettings = () => { + const { t } = useTranslation(); + + return ( +
    +