Add "Hide Repost" button in channel page (#1796)

* Re-organized per 'state->var->func->effect->return' structure.

* Add "Hide Repost" button in channel page

Ticket: 1762

## Change
For the placement of the button, putting it inside the expanded settings group feels the most natural, plus we then don't need to check whether the channel has reposts or not before displaying it (the expanded area is for stuff like this).

## Notes
The tricky part was making the code maintainable w.r.t to the global "Hide Repost" setting. Changed `forceShowReposts` to `hideRepostsOverride`, hopefully makes things more obvious.
- undefined = fallback to global setting
- true/false = use override
This commit is contained in:
infinite-persistence 2022-07-06 01:20:10 +08:00 committed by GitHub
parent 5638f64831
commit b0e88ff5d1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 111 additions and 67 deletions

View file

@ -13,9 +13,11 @@ import Icon from 'component/common/icon';
import LivestreamLink from 'component/livestreamLink';
import { Form, FormField } from 'component/common/form';
import ScheduledStreams from 'component/scheduledStreams';
import { ClaimSearchFilterContext } from 'contexts/claimSearchFilterContext';
import { SearchResults } from './internal/searchResults';
import useFetchLiveStatus from 'effects/use-fetch-live';
import { useIsLargeScreen } from 'effects/use-screensize';
import usePersistedState from 'effects/use-persisted-state';
const TYPES_TO_ALLOW_FILTER = ['stream', 'repost'];
@ -74,6 +76,15 @@ function ChannelContent(props: Props) {
const {
location: { pathname, search },
} = useHistory();
// In Channel Page, ignore SETTINGS.HIDE_REPOSTS and show reposts by default:
const [hideReposts, setHideReposts] = usePersistedState('hideRepostsChannelPage');
const claimSearchFilterCtx = {
contentTypes: CS.CONTENT_TYPES,
repost: { hideReposts, setHideReposts },
};
const url = `${pathname}${search}`;
const claimId = claim && claim.claim_id;
const isChannelEmpty = !claim || !claim.meta;
@ -85,6 +96,10 @@ function ChannelContent(props: Props) {
const isLargeScreen = useIsLargeScreen();
const dynamicPageSize = isLargeScreen ? Math.ceil(defaultPageSize * 3) : defaultPageSize;
const isInitialized = Boolean(activeLivestreamForChannel) || activeLivestreamInitialized;
const isChannelBroadcasting = Boolean(activeLivestreamForChannel);
const showScheduledLiveStreams = claimType !== 'collection'; // ie. not on the playlist page.
function handleInputChange(e) {
const { value } = e.target;
setSearchQuery(value);
@ -94,13 +109,8 @@ function ChannelContent(props: Props) {
setSearchQuery('');
}, [url]);
const isInitialized = Boolean(activeLivestreamForChannel) || activeLivestreamInitialized;
const isChannelBroadcasting = Boolean(activeLivestreamForChannel);
useFetchLiveStatus(claimId, doFetchChannelLiveStatus, true);
const showScheduledLiveStreams = claimType !== 'collection'; // ie. not on the playlist page.
return (
<Fragment>
<GeoRestrictionInfo uri={uri} />
@ -146,12 +156,13 @@ function ChannelContent(props: Props) {
{!channelIsMine && claimsInChannel > 0 && <HiddenNsfwClaims uri={uri} />}
{!fetching && (
<ClaimSearchFilterContext.Provider value={claimSearchFilterCtx}>
<ClaimListDiscover
ignoreSearchInLanguage
hasSource
defaultFreshness={CS.FRESH_ALL}
showHiddenByUser={viewHiddenChannels}
forceShowReposts
hideRepostsOverride={hideReposts}
fetchViewCount
hideFilters={!showFilters}
hideAdvancedFilter={!showFilters}
@ -204,6 +215,7 @@ function ChannelContent(props: Props) {
channelIsMine={channelIsMine}
empty={isSearching ? ' ' : empty}
/>
</ClaimSearchFilterContext.Provider>
)}
</Fragment>
);

View file

@ -31,7 +31,7 @@ type Props = {
pageSize?: number,
fetchViewCount?: boolean,
forceShowReposts?: boolean,
hideRepostsOverride?: boolean, // undefined = use SETTINGS.HIDE_REPOSTS; true/false: use this.
hasNoSource?: boolean,
hasSource?: boolean,
hideAdvancedFilter?: boolean,
@ -165,7 +165,7 @@ function ClaimListDiscover(props: Props) {
hideFilters = false,
claimIds,
maxPages,
forceShowReposts = false,
hideRepostsOverride,
languageSetting,
searchLanguages,
searchInLanguage,
@ -214,6 +214,7 @@ function ClaimListDiscover(props: Props) {
new Set(mutedUris.concat(blockedUris).map((uri) => splitBySeparator(uri)[1]))
);
const [hiddenBuffer, setHiddenBuffer] = React.useState([]);
const hideRepostsEffective = resolveHideReposts(hideReposts, hideRepostsOverride);
const langParam = urlParams.get(CS.LANGUAGE_KEY) || null;
const searchInSelectedLang = searchInLanguage && !ignoreSearchInLanguage;
@ -438,7 +439,7 @@ function ClaimListDiscover(props: Props) {
}
}
if (hideReposts && !options.reposted_claim_id && !forceShowReposts) {
if (hideRepostsEffective && !options.reposted_claim_id) {
if (Array.isArray(options.claim_type)) {
if (options.claim_type.length > 1) {
options.claim_type = options.claim_type.filter((claimType) => claimType !== 'repost');
@ -602,6 +603,14 @@ function ClaimListDiscover(props: Props) {
}
}
function resolveHideReposts(hideRepostSetting, hideRepostOverride) {
if (hideRepostOverride === undefined || hideRepostOverride === null) {
return hideRepostSetting;
} else {
return hideRepostOverride;
}
}
function resolveOrderByOption(orderBy: string | Array<string>, sortBy: string | Array<string>) {
let order_by;

View file

@ -88,7 +88,8 @@ function ClaimListHeader(props: Props) {
urlParams.get(CS.DURATION_KEY) ||
urlParams.get(CS.TAGS_KEY) ||
urlParams.get(CS.FEE_AMOUNT_KEY) ||
urlParams.get(CS.LANGUAGE_KEY)
urlParams.get(CS.LANGUAGE_KEY) ||
filterCtx?.repost?.hideReposts
);
const languageValue = searchInLanguage
@ -103,6 +104,27 @@ function ClaimListHeader(props: Props) {
? languageParam !== languageSetting && languageParam !== null
: languageParam !== CS.LANGUAGES_ALL && languageParam !== null;
function getHideRepostsElem(filterCtx, contentType) {
if (filterCtx?.repost) {
return (
<div className={classnames(`card claim-search__menus`)}>
<FormField
label={__('Hide reposts')}
name="hide_reposts"
type="checkbox"
checked={filterCtx.repost.hideReposts}
disabled={contentType === CS.CLAIM_REPOST}
onChange={() => {
filterCtx.repost.setHideReposts((prev) => !prev);
}}
/>
</div>
);
} else {
return null;
}
}
React.useEffect(() => {
if (action !== 'POP' && isFiltered()) {
setExpanded(true);
@ -507,6 +529,7 @@ function ClaimListHeader(props: Props) {
</div>
)}
</div>
{getHideRepostsElem(filterCtx, contentTypeParam)}
</>
)}
</div>

View file

@ -270,7 +270,7 @@ function DiscoverPage(props: Props) {
}
meta={getMeta()}
hasSource
forceShowReposts={dynamicRouteProps}
hideRepostsOverride={dynamicRouteProps ? true : undefined}
searchLanguages={dynamicRouteProps?.options?.searchLanguages}
/>
</ClaimSearchFilterContext.Provider>