Merge pull request #1 from dgarrett01/7645-LBRY-Hide-Watched-Content
7645 lbry hide watched content
This commit is contained in:
commit
cd20045c9e
8 changed files with 110 additions and 56 deletions
|
@ -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))
|
||||||
|
|
|
@ -106,6 +106,7 @@ function ChannelForm(props: Props) {
|
||||||
const languageParam = params.languages;
|
const languageParam = params.languages;
|
||||||
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) {
|
||||||
|
@ -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()}
|
||||||
</>
|
</>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue