mirror of
https://github.com/bitsocialnet/5chan.git
synced 2026-08-03 07:41:04 +02:00
refactor(settings): remove Hide threads without images setting
5chan boards enforce requirePostLinkIsMedia/requirePostLink at subplebbit level; client-side filter redundant.
This commit is contained in:
@@ -5,8 +5,6 @@ import useTheme from '../../../hooks/use-theme';
|
||||
import packageJson from '../../../../package.json';
|
||||
import styles from './interface-settings.module.css';
|
||||
import capitalize from 'lodash/capitalize';
|
||||
import useInterfaceSettingsStore from '../../../stores/use-interface-settings-store';
|
||||
import useCatalogFiltersStore from '../../../stores/use-catalog-filters-store';
|
||||
import useExpandedMediaStore from '../../../stores/use-expanded-media-store';
|
||||
import useSpecialThemeStore from '../../../stores/use-special-theme-store';
|
||||
import { isChristmas } from '../../../lib/utils/time-utils';
|
||||
@@ -127,8 +125,6 @@ const InterfaceLanguage = () => {
|
||||
const InterfaceSettings = () => {
|
||||
const { t } = useTranslation();
|
||||
const { hideAvatars, setHideAvatars } = useAvatarVisibilityStore();
|
||||
const { hideThreadsWithoutImages, setHideThreadsWithoutImages } = useInterfaceSettingsStore();
|
||||
const { setShowTextOnlyThreads } = useCatalogFiltersStore();
|
||||
const { fitExpandedImagesToScreen, setFitExpandedImagesToScreen } = useExpandedMediaStore();
|
||||
|
||||
const handleHideAvatarsChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
@@ -149,20 +145,6 @@ const InterfaceSettings = () => {
|
||||
<div className={styles.setting}>
|
||||
{capitalize(t('interface_language'))}: <InterfaceLanguage />
|
||||
</div>
|
||||
<div className={styles.setting}>
|
||||
<label>
|
||||
<input
|
||||
type='checkbox'
|
||||
checked={hideThreadsWithoutImages}
|
||||
onChange={(e) => {
|
||||
setHideThreadsWithoutImages(e.target.checked);
|
||||
setShowTextOnlyThreads(!e.target.checked);
|
||||
}}
|
||||
/>
|
||||
{capitalize(t('hide_threads_without_images'))}
|
||||
</label>
|
||||
<div className={styles.settingTip}>{capitalize(t('threads_without_images_tip'))}</div>
|
||||
</div>
|
||||
<div className={styles.setting}>
|
||||
<label>
|
||||
<input type='checkbox' checked={fitExpandedImagesToScreen} onChange={(e) => setFitExpandedImagesToScreen(e.target.checked)} />
|
||||
|
||||
@@ -1,11 +1,7 @@
|
||||
import { useMemo } from 'react';
|
||||
import { useAccountComments, Subplebbit } from '@plebbit/plebbit-react-hooks';
|
||||
import useInterfaceSettingsStore from '../stores/use-interface-settings-store';
|
||||
import { getCommentMediaInfo, getHasThumbnail } from '../lib/utils/media-utils';
|
||||
|
||||
const useCatalogFeedRows = (columnCount: number, feed: any, isFeedLoaded: boolean, subplebbit: Subplebbit) => {
|
||||
const { address } = subplebbit || {};
|
||||
const { hideThreadsWithoutImages } = useInterfaceSettingsStore();
|
||||
|
||||
const { accountComments } = useAccountComments();
|
||||
|
||||
@@ -18,16 +14,13 @@ const useCatalogFeedRows = (columnCount: number, feed: any, isFeedLoaded: boolea
|
||||
|
||||
// show account comments instantly in the feed once published (cid defined), instead of waiting for the feed to update
|
||||
const filteredComments = accountComments.filter((comment) => {
|
||||
const { cid, deleted, link, postCid, removed, state, subplebbitAddress, timestamp, thumbnailUrl, linkWidth, linkHeight } = comment || {};
|
||||
const commentMediaInfo = getCommentMediaInfo(link, thumbnailUrl, linkWidth, linkHeight);
|
||||
const isMediaShowed = getHasThumbnail(commentMediaInfo, link);
|
||||
const { cid, deleted, postCid, removed, state, subplebbitAddress, timestamp } = comment || {};
|
||||
|
||||
return (
|
||||
!deleted &&
|
||||
!removed &&
|
||||
timestamp > Date.now() - 60 * 60 * 1000 &&
|
||||
state === 'succeeded' &&
|
||||
(!hideThreadsWithoutImages || (hideThreadsWithoutImages && isMediaShowed)) &&
|
||||
cid &&
|
||||
cid === postCid &&
|
||||
subplebbitAddress === address &&
|
||||
@@ -49,7 +42,7 @@ const useCatalogFeedRows = (columnCount: number, feed: any, isFeedLoaded: boolea
|
||||
}
|
||||
|
||||
return _feed;
|
||||
}, [accountComments, feed, address, isFeedLoaded, hideThreadsWithoutImages]);
|
||||
}, [accountComments, feed, address, isFeedLoaded]);
|
||||
|
||||
const rows = useMemo(() => {
|
||||
const rows = [];
|
||||
|
||||
@@ -16,8 +16,6 @@ interface FilterItem {
|
||||
}
|
||||
|
||||
interface CatalogFiltersStore {
|
||||
showTextOnlyThreads: boolean;
|
||||
setShowTextOnlyThreads: (value: boolean) => void;
|
||||
filterText: string;
|
||||
setFilterText: (value: string) => void;
|
||||
filterItems: FilterItem[];
|
||||
@@ -45,11 +43,6 @@ interface CatalogFiltersStore {
|
||||
const useCatalogFiltersStore = create(
|
||||
persist<CatalogFiltersStore>(
|
||||
(set, get) => ({
|
||||
showTextOnlyThreads: false,
|
||||
setShowTextOnlyThreads: (value: boolean) => {
|
||||
set({ showTextOnlyThreads: value });
|
||||
get().updateFilter();
|
||||
},
|
||||
filterText: '',
|
||||
setFilterText: (value: string) => set({ filterText: value }),
|
||||
filterItems: [],
|
||||
@@ -358,7 +351,6 @@ const useCatalogFiltersStore = create(
|
||||
name: 'catalog-filters-storage',
|
||||
partialize: (state) => {
|
||||
return {
|
||||
showTextOnlyThreads: state.showTextOnlyThreads,
|
||||
filterItems: state.filterItems.map((item) => ({
|
||||
text: item.text,
|
||||
enabled: item.enabled,
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
import { create } from 'zustand';
|
||||
import { persist } from 'zustand/middleware';
|
||||
|
||||
interface InterfaceSettingsStore {
|
||||
hideThreadsWithoutImages: boolean;
|
||||
setHideThreadsWithoutImages: (value: boolean) => void;
|
||||
}
|
||||
|
||||
const useInterfaceSettingsStore = create(
|
||||
persist<InterfaceSettingsStore>(
|
||||
(set) => ({
|
||||
hideThreadsWithoutImages: true,
|
||||
setHideThreadsWithoutImages: (value: boolean) => set({ hideThreadsWithoutImages: value }),
|
||||
}),
|
||||
{
|
||||
name: 'interface-settings-storage',
|
||||
},
|
||||
),
|
||||
);
|
||||
|
||||
export default useInterfaceSettingsStore;
|
||||
@@ -6,13 +6,11 @@ import { Virtuoso, VirtuosoHandle, StateSnapshot } from 'react-virtuoso';
|
||||
import { Trans, useTranslation } from 'react-i18next';
|
||||
import styles from './board.module.css';
|
||||
import { shouldShowSnow } from '../../lib/snow';
|
||||
import { getCommentMediaInfo, getHasThumbnail } from '../../lib/utils/media-utils';
|
||||
import { useDirectoryAddresses, useDirectories } from '../../hooks/use-directories';
|
||||
import { useFilteredDirectoryAddresses } from '../../hooks/use-filtered-directory-addresses';
|
||||
import { useResolvedSubplebbitAddress, useBoardPath } from '../../hooks/use-resolved-subplebbit-address';
|
||||
import { useFeedStateString } from '../../hooks/use-state-string';
|
||||
import useTimeFilter, { timeFilterNameToSeconds } from '../../hooks/use-time-filter';
|
||||
import useInterfaceSettingsStore from '../../stores/use-interface-settings-store';
|
||||
import useFeedResetStore from '../../stores/use-feed-reset-store';
|
||||
import useSortingStore from '../../stores/use-sorting-store';
|
||||
import { getSubplebbitAddress, isDirectoryBoard } from '../../lib/utils/route-utils';
|
||||
@@ -150,17 +148,6 @@ const BoardFooter = ({
|
||||
);
|
||||
};
|
||||
|
||||
const createThreadsWithoutImagesFilter = () => ({
|
||||
filter: (comment: Comment) => {
|
||||
const { link, linkHeight, linkWidth, thumbnailUrl } = comment || {};
|
||||
if (!getHasThumbnail(getCommentMediaInfo(link, thumbnailUrl, linkWidth, linkHeight), link)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
key: 'threads-with-images-only',
|
||||
});
|
||||
|
||||
export interface BoardProps {
|
||||
feedCacheKey?: string;
|
||||
viewType?: 'all' | 'subs' | 'mod' | 'board';
|
||||
@@ -173,8 +160,6 @@ const Board = ({ feedCacheKey, viewType, boardIdentifier: boardIdentifierProp, t
|
||||
const { t } = useTranslation();
|
||||
const location = useLocation();
|
||||
const params = useParams();
|
||||
const { hideThreadsWithoutImages } = useInterfaceSettingsStore();
|
||||
|
||||
const isInAllView = viewType ? viewType === 'all' : false;
|
||||
const isInSubscriptionsView = viewType ? viewType === 'subs' : false;
|
||||
const isInModView = viewType ? viewType === 'mod' : false;
|
||||
@@ -221,7 +206,6 @@ const Board = ({ feedCacheKey, viewType, boardIdentifier: boardIdentifierProp, t
|
||||
sortType,
|
||||
postsPerPage: isInAllView || isInSubscriptionsView || isInModView ? 5 : 25,
|
||||
...(isInAllView || isInSubscriptionsView || isInModView ? { newerThan: timeFilterSeconds } : {}),
|
||||
filter: hideThreadsWithoutImages ? createThreadsWithoutImagesFilter() : undefined,
|
||||
};
|
||||
|
||||
const { feed, hasMore, loadMore, reset, subplebbitAddressesWithNewerPosts } = useFeed(feedOptions);
|
||||
@@ -247,13 +231,12 @@ const Board = ({ feedCacheKey, viewType, boardIdentifier: boardIdentifierProp, t
|
||||
timestamp > Date.now() / 1000 - 60 * 60 &&
|
||||
state === 'succeeded' &&
|
||||
cid &&
|
||||
(hideThreadsWithoutImages ? getHasThumbnail(getCommentMediaInfo(link, thumbnailUrl, linkWidth, linkHeight), comment?.link) : true) &&
|
||||
cid === postCid &&
|
||||
comment?.subplebbitAddress === subplebbitAddress &&
|
||||
!feed.some((post) => post.cid === cid)
|
||||
);
|
||||
}),
|
||||
[accountComments, subplebbitAddress, feed, hideThreadsWithoutImages],
|
||||
[accountComments, subplebbitAddress, feed],
|
||||
);
|
||||
|
||||
// show newest account comment at the top of the feed but after pinned posts
|
||||
@@ -293,19 +276,16 @@ const Board = ({ feedCacheKey, viewType, boardIdentifier: boardIdentifierProp, t
|
||||
subplebbitAddresses,
|
||||
sortType,
|
||||
newerThan: 60 * 60 * 24 * 7,
|
||||
filter: hideThreadsWithoutImages ? createThreadsWithoutImagesFilter() : undefined,
|
||||
});
|
||||
const { feed: monthlyFeed } = useFeed({
|
||||
subplebbitAddresses,
|
||||
sortType,
|
||||
newerThan: 60 * 60 * 24 * 30,
|
||||
filter: hideThreadsWithoutImages ? createThreadsWithoutImagesFilter() : undefined,
|
||||
});
|
||||
const { feed: yearlyFeed } = useFeed({
|
||||
subplebbitAddresses,
|
||||
sortType,
|
||||
newerThan: 60 * 60 * 24 * 365,
|
||||
filter: hideThreadsWithoutImages ? createThreadsWithoutImagesFilter() : undefined,
|
||||
});
|
||||
|
||||
const feedLength = feed.length;
|
||||
|
||||
@@ -3,7 +3,6 @@ import { Link, useLocation, useNavigationType, useParams } from 'react-router-do
|
||||
import { Trans, useTranslation } from 'react-i18next';
|
||||
import { Comment, useAccount, useFeed, useSubplebbit, useAccountComments } from '@plebbit/plebbit-react-hooks';
|
||||
import { Virtuoso, VirtuosoHandle, StateSnapshot } from 'react-virtuoso';
|
||||
import { getCommentMediaInfo, getHasThumbnail } from '../../lib/utils/media-utils';
|
||||
import useCatalogFeedRows from '../../hooks/use-catalog-feed-rows';
|
||||
import { useDirectories } from '../../hooks/use-directories';
|
||||
import { useFilteredDirectoryAddresses } from '../../hooks/use-filtered-directory-addresses';
|
||||
@@ -238,28 +237,12 @@ const createContentFilter = (
|
||||
};
|
||||
};
|
||||
|
||||
const createImageFilter = (showTextOnlyThreads: boolean) => {
|
||||
return {
|
||||
filter: (comment: Comment) => {
|
||||
if (showTextOnlyThreads) return true;
|
||||
|
||||
const { link, linkHeight, linkWidth, thumbnailUrl } = comment || {};
|
||||
const hasThumbnail = getHasThumbnail(getCommentMediaInfo(link, thumbnailUrl, linkWidth, linkHeight), link);
|
||||
|
||||
return hasThumbnail;
|
||||
},
|
||||
key: showTextOnlyThreads ? 'no-image-filter' : 'threads-with-images-only',
|
||||
};
|
||||
};
|
||||
|
||||
const createCombinedFilter = (
|
||||
showTextOnlyThreads: boolean,
|
||||
filterItems: { text: string; enabled: boolean; count: number; filteredCids: Set<string>; hide: boolean; top: boolean; color?: string }[],
|
||||
searchText: string,
|
||||
subplebbitAddress: string,
|
||||
onFilterMatch?: (filterIndex: number, cid: string, subplebbitAddress: string) => void,
|
||||
) => {
|
||||
const imageFilter = createImageFilter(showTextOnlyThreads);
|
||||
const contentFilter = createContentFilter(filterItems, subplebbitAddress, onFilterMatch);
|
||||
|
||||
const searchFilter = {
|
||||
@@ -272,13 +255,12 @@ const createCombinedFilter = (
|
||||
|
||||
return {
|
||||
filter: (comment: Comment) => {
|
||||
if (!imageFilter.filter(comment)) return false;
|
||||
if (!contentFilter.filter(comment)) return false;
|
||||
if (!searchFilter.filter(comment)) return false;
|
||||
|
||||
return true;
|
||||
},
|
||||
key: `${imageFilter.key}-${contentFilter.key}-${searchFilter.key}`,
|
||||
key: `${contentFilter.key}-${searchFilter.key}`,
|
||||
};
|
||||
};
|
||||
|
||||
@@ -308,7 +290,7 @@ const Catalog = ({ feedCacheKey, viewType, boardIdentifier: boardIdentifierProp,
|
||||
}, [boardIdentifierProp, directories, resolvedAddressFromUrl]);
|
||||
|
||||
const boardPath = useBoardPath(subplebbitAddress);
|
||||
const { showTextOnlyThreads, filterItems, searchText, clearMatchedFilters } = useCatalogFiltersStore();
|
||||
const { filterItems, searchText, clearMatchedFilters } = useCatalogFiltersStore();
|
||||
|
||||
const account = useAccount();
|
||||
const subscriptions = account?.subscriptions;
|
||||
@@ -354,7 +336,7 @@ const Catalog = ({ feedCacheKey, viewType, boardIdentifier: boardIdentifierProp,
|
||||
subplebbitAddresses,
|
||||
sortType,
|
||||
postsPerPage: isInAllView || isInSubscriptionsView ? 10 : postsPerPage,
|
||||
filter: createCombinedFilter(showTextOnlyThreads, filterItems, searchText, subplebbitAddress || 'all', handleFilterMatch),
|
||||
filter: createCombinedFilter(filterItems, searchText, subplebbitAddress || 'all', handleFilterMatch),
|
||||
};
|
||||
|
||||
if (isInAllView || isInSubscriptionsView) {
|
||||
@@ -362,19 +344,7 @@ const Catalog = ({ feedCacheKey, viewType, boardIdentifier: boardIdentifierProp,
|
||||
}
|
||||
|
||||
return options;
|
||||
}, [
|
||||
subplebbitAddresses,
|
||||
sortType,
|
||||
isInAllView,
|
||||
isInSubscriptionsView,
|
||||
postsPerPage,
|
||||
timeFilterSeconds,
|
||||
showTextOnlyThreads,
|
||||
filterItems,
|
||||
searchText,
|
||||
subplebbitAddress,
|
||||
handleFilterMatch,
|
||||
]);
|
||||
}, [subplebbitAddresses, sortType, isInAllView, isInSubscriptionsView, postsPerPage, timeFilterSeconds, filterItems, searchText, subplebbitAddress, handleFilterMatch]);
|
||||
|
||||
const { feed, hasMore, loadMore, reset, subplebbitAddressesWithNewerPosts } = useFeed(feedOptions);
|
||||
const { accountComments } = useAccountComments();
|
||||
@@ -385,7 +355,7 @@ const Catalog = ({ feedCacheKey, viewType, boardIdentifier: boardIdentifierProp,
|
||||
const filteredComments = useMemo(
|
||||
() =>
|
||||
accountComments.filter((comment) => {
|
||||
const { cid, deleted, link, linkHeight, linkWidth, postCid, removed, state, thumbnailUrl, timestamp } = comment || {};
|
||||
const { cid, deleted, postCid, removed, state, timestamp } = comment || {};
|
||||
|
||||
// Basic filtering conditions
|
||||
const basicConditions =
|
||||
@@ -394,7 +364,6 @@ const Catalog = ({ feedCacheKey, viewType, boardIdentifier: boardIdentifierProp,
|
||||
timestamp > Date.now() / 1000 - 60 * 60 &&
|
||||
state === 'succeeded' &&
|
||||
cid &&
|
||||
(showTextOnlyThreads ? getHasThumbnail(getCommentMediaInfo(link, thumbnailUrl, linkWidth, linkHeight), comment?.link) : true) &&
|
||||
cid === postCid &&
|
||||
comment?.subplebbitAddress === subplebbitAddress &&
|
||||
!feed.some((post) => post.cid === cid);
|
||||
@@ -410,7 +379,7 @@ const Catalog = ({ feedCacheKey, viewType, boardIdentifier: boardIdentifierProp,
|
||||
|
||||
return basicConditions;
|
||||
}),
|
||||
[accountComments, subplebbitAddress, feed, showTextOnlyThreads, searchText],
|
||||
[accountComments, subplebbitAddress, feed, searchText],
|
||||
);
|
||||
|
||||
// show newest account comment at the top of the feed but after pinned posts
|
||||
@@ -442,21 +411,21 @@ const Catalog = ({ feedCacheKey, viewType, boardIdentifier: boardIdentifierProp,
|
||||
subplebbitAddresses,
|
||||
sortType,
|
||||
newerThan: 60 * 60 * 24 * 7,
|
||||
filter: createCombinedFilter(showTextOnlyThreads, filterItems, searchText, subplebbitAddress || 'all', handleFilterMatch),
|
||||
filter: createCombinedFilter(filterItems, searchText, subplebbitAddress || 'all', handleFilterMatch),
|
||||
});
|
||||
|
||||
const { feed: monthlyFeed } = useFeed({
|
||||
subplebbitAddresses,
|
||||
sortType,
|
||||
newerThan: 60 * 60 * 24 * 30,
|
||||
filter: createCombinedFilter(showTextOnlyThreads, filterItems, searchText, subplebbitAddress || 'all', handleFilterMatch),
|
||||
filter: createCombinedFilter(filterItems, searchText, subplebbitAddress || 'all', handleFilterMatch),
|
||||
});
|
||||
|
||||
const { feed: yearlyFeed } = useFeed({
|
||||
subplebbitAddresses,
|
||||
sortType,
|
||||
newerThan: 60 * 60 * 24 * 365,
|
||||
filter: createCombinedFilter(showTextOnlyThreads, filterItems, searchText, subplebbitAddress || 'all', handleFilterMatch),
|
||||
filter: createCombinedFilter(filterItems, searchText, subplebbitAddress || 'all', handleFilterMatch),
|
||||
});
|
||||
|
||||
const [showMorePostsSuggestion, setShowMorePostsSuggestion] = useState(false);
|
||||
|
||||
Reference in New Issue
Block a user