diff --git a/src/components/header/header.tsx b/src/components/header/header.tsx index ed8e3322..f8b5bd1d 100644 --- a/src/components/header/header.tsx +++ b/src/components/header/header.tsx @@ -304,12 +304,8 @@ const HeaderTitle = ({ title, shortAddress, pendingPostSubplebbitAddress }: { ti const subplebbitAddress = params.subplebbitAddress; - const contentOptionsStore = useContentOptionsStore(); - const hasUnhiddenAnyNsfwCommunity = - !contentOptionsStore.hideAdultCommunities || - !contentOptionsStore.hideGoreCommunities || - !contentOptionsStore.hideAntiCommunities || - !contentOptionsStore.hideVulgarCommunities; + const { hideAdultCommunities, hideGoreCommunities, hideAntiCommunities, hideVulgarCommunities } = useContentOptionsStore(); + const hasUnhiddenAnyNsfwCommunity = !hideAdultCommunities || !hideGoreCommunities || !hideAntiCommunities || !hideVulgarCommunities; const isBroadlyNsfwSubplebbit = useIsBroadlyNsfwSubplebbit(subplebbitAddress || ''); const subplebbitTitle = {title || shortAddress}; diff --git a/src/components/topbar/topbar.module.css b/src/components/topbar/topbar.module.css index d918dec4..11f0fb4f 100644 --- a/src/components/topbar/topbar.module.css +++ b/src/components/topbar/topbar.module.css @@ -15,13 +15,45 @@ .dropdown { float: left; - cursor: pointer; display: inline; position: relative; } .subsDropdown { padding-left: 5px; + cursor: pointer; +} + +.filterDropdown .dropChoices { + padding: 0 4px 4px 4px; + text-transform: none; + font-size: 11px; +} + +.filterDropdownItem label { + cursor: pointer; + padding-top: 2px; +} + +.filterDropdownItem { + padding-top: 4px; +} + +.filterDropdownItem input { + margin-right: 5px; +} + +.nsfwFilters { + background-image: url("/assets/buttons/droparrowgray.gif"); + background-repeat: no-repeat; + background-position: right bottom; + display: inline-block; + padding-right: 21px; + cursor: pointer; + height: 13px; + padding-top: 10px; + text-transform: uppercase; + font-size: 9px; } .dropChoices { diff --git a/src/components/topbar/topbar.tsx b/src/components/topbar/topbar.tsx index ff867e62..ef39230f 100644 --- a/src/components/topbar/topbar.tsx +++ b/src/components/topbar/topbar.tsx @@ -1,4 +1,4 @@ -import { useCallback, useEffect, useRef, useState } from 'react'; +import { useEffect, useRef, useState } from 'react'; import { Link, useLocation, useNavigate, useParams } from 'react-router-dom'; import { useTranslation } from 'react-i18next'; import { useAccount, useAccountSubplebbits } from '@plebbit/plebbit-react-hooks'; @@ -7,46 +7,25 @@ import styles from './topbar.module.css'; import { useDefaultSubplebbitAddresses } from '../../hooks/use-default-subplebbits'; import useTimeFilter from '../../hooks/use-time-filter'; import { isAllView, isHomeView, isModView, isSubplebbitView } from '../../lib/utils/view-utils'; +import useContentOptionsStore from '../../stores/use-content-options-store'; const sortTypes = ['hot', 'new', 'active', 'controversialAll', 'topAll']; const isElectron = window.isElectron === true; -const TopBar = () => { - const account = useAccount(); - const subplebbitAddresses = useDefaultSubplebbitAddresses(); +const FiltersDropdown = () => { const { t } = useTranslation(); - const location = useLocation(); const params = useParams(); - const subscriptions = account?.subscriptions; - const isinAllView = isAllView(location.pathname); - const isInHomeView = isHomeView(location.pathname); - const isInModView = isModView(location.pathname); + const location = useLocation(); + const navigate = useNavigate(); const isInSubplebbitView = isSubplebbitView(location.pathname, params); - const homeButtonClass = isInHomeView ? styles.selected : styles.choice; - - const { accountSubplebbits } = useAccountSubplebbits(); - const accountSubplebbitAddresses = Object.keys(accountSubplebbits); - + const isinAllView = isAllView(location.pathname); + const isInModView = isModView(location.pathname); const { timeFilterName, timeFilterNames } = useTimeFilter(); + const selectedTimeFilter = timeFilterName || (isInSubplebbitView ? 'all' : timeFilterName); - const [isSubsDropdownOpen, setIsSubsDropdownOpen] = useState(false); - const toggleSubsDropdown = () => setIsSubsDropdownOpen(!isSubsDropdownOpen); - const subsDropdownRef = useRef(null); - const subsdropdownItemsRef = useRef(null); - const subsDropdownClass = isSubsDropdownOpen ? styles.visible : styles.hidden; - - const [isSortsDropdownOpen, setIsSortsDropdownOpen] = useState(false); - const toggleSortsDropdown = () => setIsSortsDropdownOpen(!isSortsDropdownOpen); - const sortsDropdownRef = useRef(null); - const sortsdropdownItemsRef = useRef(null); - const sortsDropdownClass = isSortsDropdownOpen ? styles.visible : styles.hidden; - const [isFilterDropdownOpen, setIsFilterDropdownOpen] = useState(false); - const toggleFilterDropdown = () => setIsFilterDropdownOpen(!isFilterDropdownOpen); const filterDropdownRef = useRef(null); - const filterdropdownItemsRef = useRef(null); - const filterDropdownClass = isFilterDropdownOpen ? styles.visible : styles.hidden; const sortLabels = [t('hot'), t('new'), t('active'), t('controversial'), t('top')]; const selectedSortType = params.sortType || 'hot'; @@ -61,37 +40,12 @@ const TopBar = () => { : `/${selectedSortType}/${timeFilterName}`; }; - const getSelectedSortLabel = () => { - const index = sortTypes.indexOf(selectedSortType); - return index >= 0 ? sortLabels[index] : sortLabels[0]; + const handleClickOutside = (event: MouseEvent) => { + if (filterDropdownRef.current && !filterDropdownRef.current.contains(event.target as Node)) { + setIsFilterDropdownOpen(false); + } }; - const handleClickOutside = useCallback( - (event: MouseEvent) => { - const target = event.target as Node; - - const isOutsideSubs = - subsDropdownRef.current && !subsDropdownRef.current.contains(target) && subsdropdownItemsRef.current && !subsdropdownItemsRef.current.contains(target); - const isOutsideSorts = - sortsDropdownRef.current && !sortsDropdownRef.current.contains(target) && sortsdropdownItemsRef.current && !sortsdropdownItemsRef.current.contains(target); - const isOutsideFilter = - filterDropdownRef.current && !filterDropdownRef.current.contains(target) && filterdropdownItemsRef.current && !filterdropdownItemsRef.current.contains(target); - - if (isOutsideSubs) { - setIsSubsDropdownOpen(false); - } - - if (isOutsideSorts) { - setIsSortsDropdownOpen(false); - } - - if (isOutsideFilter) { - setIsFilterDropdownOpen(false); - } - }, - [subsDropdownRef, subsdropdownItemsRef, sortsDropdownRef, sortsdropdownItemsRef, filterDropdownRef, filterdropdownItemsRef], - ); - useEffect(() => { document.addEventListener('mousedown', handleClickOutside); return () => { @@ -99,8 +53,155 @@ const TopBar = () => { }; }, [handleClickOutside]); - const isConnectedToRpc = !!account?.plebbitOptions.plebbitRpcClientsOptions; + const { + blurNsfwThumbnails, + hideAdultCommunities, + hideGoreCommunities, + hideAntiCommunities, + hideVulgarCommunities, + setBlurNsfwThumbnails, + setHideAdultCommunities, + setHideGoreCommunities, + setHideAntiCommunities, + setHideVulgarCommunities, + } = useContentOptionsStore(); + + const [hideNsfwFilters, setHideNsfwFilters] = useState(true); + + return ( +
+ setIsFilterDropdownOpen(!isFilterDropdownOpen)}> + {t('filters')} + + {isFilterDropdownOpen && ( +
+
+ posts from:{' '} + +
+
+ sort posts by:{' '} + +
+
setHideNsfwFilters(!hideNsfwFilters)}> + NSFW filters +
+ {!hideNsfwFilters && ( + <> +
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+ + )} +
+ )} +
+ ); +}; + +const CommunitiesDropdown = () => { + const { t } = useTranslation(); + const account = useAccount(); const navigate = useNavigate(); + const subscriptions = account?.subscriptions; + const isConnectedToRpc = !!account?.plebbitOptions.plebbitRpcClientsOptions; + + const [isSubsDropdownOpen, setIsSubsDropdownOpen] = useState(false); + const toggleSubsDropdown = () => setIsSubsDropdownOpen(!isSubsDropdownOpen); + const subsDropdownRef = useRef(null); + const subsdropdownItemsRef = useRef(null); + const subsDropdownClass = isSubsDropdownOpen ? styles.visible : styles.hidden; + + const handleClickOutside = (event: MouseEvent) => { + if (subsDropdownRef.current && !subsDropdownRef.current.contains(event.target as Node)) { + setIsSubsDropdownOpen(false); + } + }; + + useEffect(() => { + if (isSubsDropdownOpen) { + document.addEventListener('mousedown', handleClickOutside); + } + }, [isSubsDropdownOpen]); + const handleCreateCommunity = () => { // creating a community only works if the user is running a full node if (isElectron || isConnectedToRpc) { @@ -116,54 +217,47 @@ const TopBar = () => { } }; + return ( +
+ {t('my_communities')} +
+ {subscriptions?.map((subscription: string, index: number) => ( + + {Plebbit.getShortAddress(subscription)} + + ))} + + {t('create_community')} + + + {t('default_communities')} + + + {t('edit_subscriptions')} + +
+
+ ); +}; + +const TopBar = () => { + const subplebbitAddresses = useDefaultSubplebbitAddresses(); + const { t } = useTranslation(); + const location = useLocation(); + const params = useParams(); + const isinAllView = isAllView(location.pathname); + const isInHomeView = isHomeView(location.pathname); + const isInModView = isModView(location.pathname); + const homeButtonClass = isInHomeView ? styles.selected : styles.choice; + + const { accountSubplebbits } = useAccountSubplebbits(); + const accountSubplebbitAddresses = Object.keys(accountSubplebbits); + return (
-
- {t('my_communities')} -
- {subscriptions?.map((subscription: string, index: number) => ( - - {Plebbit.getShortAddress(subscription)} - - ))} - - {t('create_community')} - - - {t('default_communities')} - - - {t('edit_subscriptions')} - -
-
-
- {getSelectedSortLabel()} -
- {sortTypes.map((sortType, index) => { - let dropdownLink = isInSubplebbitView ? `/p/${params.subplebbitAddress}/${sortType}` : isinAllView ? `/p/all/${sortType}` : sortType; - if (timeFilterName) { - dropdownLink += `/${timeFilterName}`; - } - return ( - - {sortLabels[index]} - - ); - })} -
-
-
- {selectedTimeFilter} -
- {timeFilterNames.slice(0, -1).map((timeFilterName, index) => ( - - {timeFilterNames[index]} - - ))} -
-
+ +
  • diff --git a/src/views/settings/settings.tsx b/src/views/settings/settings.tsx index de109660..0617e3e7 100644 --- a/src/views/settings/settings.tsx +++ b/src/views/settings/settings.tsx @@ -149,17 +149,18 @@ const ContentOptions = () => {

    {t('communities')}
    - setHideAdultCommunities(e.target.checked)} /> - -
    - setHideAntiCommunities(e.target.checked)} /> - -
    - setHideGoreCommunities(e.target.checked)} /> - -
    - setHideVulgarCommunities(e.target.checked)} /> - + { + setHideAdultCommunities(e.target.checked); + setHideAntiCommunities(e.target.checked); + setHideGoreCommunities(e.target.checked); + setHideVulgarCommunities(e.target.checked); + }} + /> +
); }; @@ -210,7 +211,7 @@ const GeneralSettings = () => { {t('version')}
- seedit + {isElectron && ( {t('node_stats')} diff --git a/src/views/subplebbit/subplebbit.tsx b/src/views/subplebbit/subplebbit.tsx index 2ed3637f..78d65f10 100644 --- a/src/views/subplebbit/subplebbit.tsx +++ b/src/views/subplebbit/subplebbit.tsx @@ -261,7 +261,8 @@ const Subplebbit = () => { }, [feed, setPinnedPostsCount]); // over 18 warning for subplebbit with nsfw tag in multisub default list - const { hasAcceptedWarning } = useContentOptionsStore(); + const { hideAdultCommunities, hideGoreCommunities, hideAntiCommunities, hideVulgarCommunities } = useContentOptionsStore(); + const hasUnhiddenAnyNsfwCommunity = !hideAdultCommunities || !hideGoreCommunities || !hideAntiCommunities || !hideVulgarCommunities; const isBroadlyNsfwSubplebbit = useIsBroadlyNsfwSubplebbit(subplebbitAddress || ''); // page title @@ -269,7 +270,7 @@ const Subplebbit = () => { document.title = title ? title : shortAddress || subplebbitAddress; }, [title, shortAddress, subplebbitAddress]); - return isBroadlyNsfwSubplebbit && !hasAcceptedWarning ? ( + return isBroadlyNsfwSubplebbit && !hasUnhiddenAnyNsfwCommunity ? ( ) : (