Merge pull request #1 from dgarrett01/7645-LBRY-Hide-Watched-Content

7645 lbry hide watched content
This commit is contained in:
David Garrett 2022-11-27 19:26:35 -05:00 committed by GitHub
commit cd20045c9e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 110 additions and 56 deletions

View file

@ -5,7 +5,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
## [0.53.8] - [2022-11-17] ## [0.53.8] - [2022-11-17]
### Added ### Added
- Added the ability for users to hide content they've already watched throughout the app via a checkbox ([7645](Add Filter for Unwatched Content)) - Added the ability for users to hide content they've already watched throughout the app via a checkbox ([#7645](https://github.com/lbryio/lbry-desktop/issues/7645))
### Fixed ### Fixed
- Selecting a large file in publish no longer crashes ([#7736](https://github.com/lbryio/lbry-desktop/pull/7736)) - Selecting a large file in publish no longer crashes ([#7736](https://github.com/lbryio/lbry-desktop/pull/7736))

View file

@ -107,6 +107,7 @@ function ChannelForm(props: Props) {
const primaryLanguage = Array.isArray(languageParam) && languageParam.length && languageParam[0]; const primaryLanguage = Array.isArray(languageParam) && languageParam.length && languageParam[0];
const secondaryLanguage = Array.isArray(languageParam) && languageParam.length >= 2 && languageParam[1]; const secondaryLanguage = Array.isArray(languageParam) && languageParam.length >= 2 && languageParam[1];
const [hideWatched, setHideWatched] = usePersistedState('hideWatched', false); const [hideWatched, setHideWatched] = usePersistedState('hideWatched', false);
const [hideWatched, setHideWatched] = usePersistedState('hideWatched', false);
const submitLabel = React.useMemo(() => { const submitLabel = React.useMemo(() => {
if (isClaimingInitialRewards) { if (isClaimingInitialRewards) {
return __('Claiming credits...'); return __('Claiming credits...');
@ -239,7 +240,23 @@ function ChannelForm(props: Props) {
} }
if ((!isUpload.thumbnail && thumbError) || (!isUpload.cover && coverError)) { if ((!isUpload.thumbnail && thumbError) || (!isUpload.cover && coverError)) {
errorMsg = __('Invalid %error_type%', { error_type: (thumbError && 'thumbnail') || (coverError && 'cover image') }); errorMsg = __('Invalid %error_type%', { error_type: (thumbError && 'thumbnail') || (coverError && 'cover image') });
} }
function getHideWatchedElem() {
return (
<div className={classnames(`card claim-search__menus`)}>
<FormField
label={__('Hide Watched')}
name="hide_watched"
type="checkbox"
checked={hideWatched}
onChange={() => {
setHideWatched((prev) => !prev);
}}
/>
</div>
);
}
// Add "Hide Watched" to channel pages // Add "Hide Watched" to channel pages
function getHideWatchedElem() { function getHideWatchedElem() {
@ -544,7 +561,7 @@ function ChannelForm(props: Props) {
<ClaimAbandonButton uri={uri} abandonActionCallback={() => replace(`/$/${PAGES.CHANNELS}`)} /> <ClaimAbandonButton uri={uri} abandonActionCallback={() => replace(`/$/${PAGES.CHANNELS}`)} />
</div> </div>
)} )}
{getHideWatchedElem()} {getHideWatchedElem()}
</> </>
} }
/> />

View file

@ -115,6 +115,21 @@ function ClaimListHeader(props: Props) {
); );
} }
function getHideWatchedElem() {
return (
<div className={`claim-search__checkbox`}>
<FormField
name="hide_watched"
type="checkbox"
checked={hideWatched}
onChange={() => {
setHideWatched((prev) => !prev);
}}
/>
</div>
);
}
React.useEffect(() => { React.useEffect(() => {
if (action !== 'POP' && isFiltered()) { if (action !== 'POP' && isFiltered()) {
setExpanded(true); setExpanded(true);

View file

@ -47,7 +47,7 @@ const select = (state, props) => {
wasPurchased: props.uri && makeSelectClaimWasPurchased(props.uri)(state), wasPurchased: props.uri && makeSelectClaimWasPurchased(props.uri)(state),
isCollectionMine: makeSelectCollectionIsMine(props.collectionId)(state), isCollectionMine: makeSelectCollectionIsMine(props.collectionId)(state),
lang: selectLanguage(state), lang: selectLanguage(state),
isWatched: makeSelectContentWatchedPercentageForUri(props.uri)(state) > 80, // Content considered "watched" when viewed to 80% isWatched: makeSelectContentWatchedPercentageForUri(props.uri)(state) > 80,
}; };
}; };

View file

@ -31,7 +31,7 @@ const select = (state, props) => {
showMature: selectShowMatureContent(state), showMature: selectShowMatureContent(state),
isMature: claim ? isClaimNsfw(claim) : false, isMature: claim ? isClaimNsfw(claim) : false,
viewCount: selectViewCountForUri(state, props.uri), viewCount: selectViewCountForUri(state, props.uri),
isWatched: makeSelectContentWatchedPercentageForUri(props.uri)(state) > 80, // Content considered "watched" when viewed 80% isWatched: makeSelectContentWatchedPercentageForUri(props.uri)(state) > 80,
}; };
}; };

View file

@ -128,7 +128,23 @@ function ClaimPreviewTile(props: Props) {
} }
}, [isValid, isResolvingUri, uri, resolveUri, shouldFetch]); }, [isValid, isResolvingUri, uri, resolveUri, shouldFetch]);
let shouldHide = false; let shouldHide = false;
if (isMature && !showMature) {
// Unfortunately needed until this is resolved
// https://github.com/lbryio/lbry-sdk/issues/2785
shouldHide = true;
} else {
shouldHide =
banState.blacklisted ||
banState.filtered ||
(!showHiddenByUser && (banState.muted || banState.blocked)) ||
(isWatched && hideWatched);
}
if (shouldHide) {
return null;
}
if (isMature && !showMature) { if (isMature && !showMature) {
// Unfortunately needed until this is resolved // Unfortunately needed until this is resolved

View file

@ -64,7 +64,7 @@ const SearchOptions = (props: Props) => {
const [hideWatched, setHideWatched] = usePersistedState('hideWatched', false); const [hideWatched, setHideWatched] = usePersistedState('hideWatched', false);
React.useEffect(() => { React.useEffect(() => {
// We no longer let the user set the search results count, but the value // We no longer let the user set the search results count, but the value
// will be in local storage for existing users. Override that. // will be in local storage for existing users. Override that.
if (options[SEARCH_OPTIONS.RESULT_COUNT] !== SEARCH_PAGE_SIZE) { if (options[SEARCH_OPTIONS.RESULT_COUNT] !== SEARCH_PAGE_SIZE) {
@ -176,29 +176,29 @@ const SearchOptions = (props: Props) => {
</> </>
); );
// Changed element name to exactMatchElem
const exactMatchElem = ( const exactMatchElem = (
<> <>
<div className="filter-values"> <div className="filter-values">
<FormField <FormField
type="checkbox" type="checkbox"
name="exact-match" name="exact-match"
checked={options[SEARCH_OPTIONS.EXACT]} checked={options[SEARCH_OPTIONS.EXACT]}
onChange={() => updateSearchOptions(SEARCH_OPTIONS.EXACT, !options[SEARCH_OPTIONS.EXACT])} onChange={() => updateSearchOptions(SEARCH_OPTIONS.EXACT, !options[SEARCH_OPTIONS.EXACT])}
/> />
<Icon <Icon
className="icon--help" className="icon--help"
icon={ICONS.HELP} icon={ICONS.HELP}
tooltip tooltip
size={16} size={16}
customTooltipText={__( customTooltipText={__(
'Find results that include all the given words in the exact order.\nThis can also be done by surrounding the search query with quotation marks (e.g. "hello world").' 'Find results that include all the given words in the exact order.\nThis can also be done by surrounding the search query with quotation marks (e.g. "hello world").'
)} )}
/> />
</div> </div>
</>
);
</>
);
const uploadDateElem = ( const uploadDateElem = (
<div className="filter-values"> <div className="filter-values">
@ -228,7 +228,13 @@ const SearchOptions = (props: Props) => {
</div> </div>
); );
const sortByElem = ( const hideWatchedElem = (
<div>
{getHideWatchedElem()}
</div>
);
const sortByElem = (
<div className="filter-values"> <div className="filter-values">
<FormField <FormField
type="select" type="select"
@ -245,33 +251,33 @@ const SearchOptions = (props: Props) => {
const uploadDateLabel = const uploadDateLabel =
options[SEARCH_OPTIONS.CLAIM_TYPE] === SEARCH_OPTIONS.INCLUDE_CHANNELS ? __('Creation Date') : __('Upload Date'); options[SEARCH_OPTIONS.CLAIM_TYPE] === SEARCH_OPTIONS.INCLUDE_CHANNELS ? __('Creation Date') : __('Upload Date');
// Added row to table for hiding watched content in search settings
return ( return (
<div> <div>
<Button <Button
button="alt" button="alt"
label={__('Filter')} label={__('Filter')}
icon={ICONS.FILTER} icon={ICONS.FILTER}
iconRight={expanded ? ICONS.UP : ICONS.DOWN} iconRight={expanded ? ICONS.UP : ICONS.DOWN}
onClick={toggleSearchExpanded} onClick={toggleSearchExpanded}
/> />
<Form <Form
className={classnames('search__options', { className={classnames('search__options', {
'search__options--expanded': expanded, 'search__options--expanded': expanded,
})} })}
> >
<table className="table table--condensed"> <table className="table table--condensed">
<tbody> <tbody>
{addRow(__('Type'), typeElem)} {addRow(__('Type'), typeElem)}
{addRow(uploadDateLabel, uploadDateElem)} {addRow(uploadDateLabel, uploadDateElem)}
{addRow(__('Sort By'), sortByElem)} {addRow(__('Sort By'), sortByElem)}
{addRow(__('Exact Match'), exactMatchElem)} {addRow(__('Exact Match'), exactMatchElem)}
{addRow(__('Hide Watched Content'), hideWatchedElem)} {addRow(__('Hide Watched Content'), hideWatchedElem)}
</tbody> </tbody>
</table> </table>
</Form> </Form>
</div> </div>
); );
}; };
export default SearchOptions; export default SearchOptions;

View file

@ -36,7 +36,7 @@
//UPDATE: Added style for checkbox on search page //UPDATE: Added style for checkbox on search page
.claim-search__checkbox_searchbox { .claim-search__checkbox_searchbox {
// Placeholder. // Placeholder
} }
// UPDATE: Add style for checkbox label // UPDATE: Add style for checkbox label