display repost counts on file pages, link to all reposts
This commit is contained in:
parent
3cc260e56c
commit
73d2eebb07
6 changed files with 93 additions and 49 deletions
|
@ -103,25 +103,27 @@ export default function ClaimList(props: Props) {
|
|||
{header !== false && (
|
||||
<React.Fragment>
|
||||
{headerLabel && <label className="claim-list__header-label">{headerLabel}</label>}
|
||||
<div className={classnames('claim-list__header', { 'section__title--small': type === 'small' })}>
|
||||
{header}
|
||||
{loading && <Spinner type="small" />}
|
||||
<div className="claim-list__alt-controls">
|
||||
{headerAltControls}
|
||||
{defaultSort && (
|
||||
<FormField
|
||||
className="claim-list__dropdown"
|
||||
type="select"
|
||||
name="file_sort"
|
||||
value={currentSort}
|
||||
onChange={handleSortChange}
|
||||
>
|
||||
<option value={SORT_NEW}>{__('Newest First')}</option>
|
||||
<option value={SORT_OLD}>{__('Oldest First')}</option>
|
||||
</FormField>
|
||||
)}
|
||||
{header && (
|
||||
<div className={classnames('claim-list__header', { 'section__title--small': type === 'small' })}>
|
||||
{header}
|
||||
{loading && <Spinner type="small" />}
|
||||
<div className="claim-list__alt-controls">
|
||||
{headerAltControls}
|
||||
{defaultSort && (
|
||||
<FormField
|
||||
className="claim-list__dropdown"
|
||||
type="select"
|
||||
name="file_sort"
|
||||
value={currentSort}
|
||||
onChange={handleSortChange}
|
||||
>
|
||||
<option value={SORT_NEW}>{__('Newest First')}</option>
|
||||
<option value={SORT_OLD}>{__('Oldest First')}</option>
|
||||
</FormField>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</React.Fragment>
|
||||
)}
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@ type Props = {
|
|||
doToggleTagFollowDesktop: string => void,
|
||||
meta?: Node,
|
||||
showNsfw: boolean,
|
||||
showReposts: boolean,
|
||||
// showReposts: boolean,
|
||||
history: { action: string, push: string => void, replace: string => void },
|
||||
location: { search: string, pathname: string },
|
||||
claimSearchByQuery: {
|
||||
|
@ -49,6 +49,7 @@ type Props = {
|
|||
defaultStreamType?: string | Array<string>,
|
||||
renderProperties?: Claim => Node,
|
||||
includeSupportAction?: boolean,
|
||||
repostedClaimId?: string,
|
||||
pageSize?: number,
|
||||
followedTags?: Array<Tag>,
|
||||
};
|
||||
|
@ -83,6 +84,7 @@ function ClaimListDiscover(props: Props) {
|
|||
defaultFreshness = CS.FRESH_WEEK,
|
||||
renderProperties,
|
||||
includeSupportAction,
|
||||
repostedClaimId,
|
||||
hideFilter,
|
||||
followedTags,
|
||||
} = props;
|
||||
|
@ -121,7 +123,7 @@ function ClaimListDiscover(props: Props) {
|
|||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, []);
|
||||
|
||||
const options: {
|
||||
let options: {
|
||||
page_size: number,
|
||||
page: number,
|
||||
no_totals: boolean,
|
||||
|
@ -134,6 +136,7 @@ function ClaimListDiscover(props: Props) {
|
|||
claim_type?: Array<string>,
|
||||
name?: string,
|
||||
duration?: string,
|
||||
reposted_claim_id: string,
|
||||
stream_types?: any,
|
||||
} = {
|
||||
page_size: pageSize || CS.PAGE_SIZE,
|
||||
|
@ -155,6 +158,12 @@ function ClaimListDiscover(props: Props) {
|
|||
? CS.ORDER_BY_NEW_VALUE
|
||||
: CS.ORDER_BY_TOP_VALUE, // Sort by top
|
||||
};
|
||||
|
||||
if (repostedClaimId) {
|
||||
// SDK chokes on reposted_claim_id of null or false, needs to not be present if no value
|
||||
options.reposted_claim_id = repostedClaimId;
|
||||
}
|
||||
|
||||
if (orderParam === CS.ORDER_BY_TOP && freshnessParam !== CS.FRESH_ALL) {
|
||||
options.release_time = `>${Math.floor(
|
||||
moment()
|
||||
|
@ -364,7 +373,7 @@ function ClaimListDiscover(props: Props) {
|
|||
}
|
||||
}, [doClaimSearch, shouldPerformSearch, optionsStringForEffect, forceRefresh]);
|
||||
|
||||
const defaultHeader = (
|
||||
const defaultHeader = repostedClaimId ? null : (
|
||||
<Fragment>
|
||||
<div className={'claim-search__wrapper'}>
|
||||
<div className={'claim-search__top'}>
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
// @flow
|
||||
import * as MODALS from 'constants/modal_types';
|
||||
import * as ICONS from 'constants/icons';
|
||||
import React from 'react';
|
||||
import React, { Fragment } from 'react';
|
||||
import Button from 'component/button';
|
||||
import FileDownloadLink from 'component/fileDownloadLink';
|
||||
import { buildURI } from 'lbry-redux';
|
||||
import * as PAGES from '../../constants/pages';
|
||||
import * as CS from '../../constants/claim_search';
|
||||
|
||||
type Props = {
|
||||
uri: string,
|
||||
|
@ -42,6 +44,20 @@ function FileActions(props: Props) {
|
|||
editUri = buildURI(uriObject);
|
||||
}
|
||||
|
||||
let repostLabel = <span>{__('Repost')}</span>;
|
||||
if (claim.meta.reposted > 0) {
|
||||
repostLabel = (
|
||||
<Fragment>
|
||||
{repostLabel}{' '}
|
||||
<Button
|
||||
button="alt"
|
||||
label={__('(%count%)', { count: claim.meta.reposted })}
|
||||
navigate={`/$/${PAGES.DISCOVER}?${CS.REPOSTED_URI_KEY}=${encodeURIComponent(uri)}`}
|
||||
/>
|
||||
</Fragment>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="media__actions">
|
||||
<div className="section__actions">
|
||||
|
@ -54,7 +70,7 @@ function FileActions(props: Props) {
|
|||
<Button
|
||||
button="alt"
|
||||
icon={ICONS.REPOST}
|
||||
label={__('Repost')}
|
||||
label={repostLabel}
|
||||
requiresAuth={IS_WEB}
|
||||
onClick={() => openModal(MODALS.REPOST, { uri })}
|
||||
/>
|
||||
|
|
|
@ -5,6 +5,7 @@ export const ORDER_BY_KEY = 'order';
|
|||
export const DURATION_KEY = 'duration';
|
||||
export const TAGS_KEY = 't';
|
||||
export const CONTENT_KEY = 'content';
|
||||
export const REPOSTED_URI_KEY = 'reposted_uri';
|
||||
|
||||
export const TAGS_ALL = 'tags_any';
|
||||
export const TAGS_FOLLOWED = 'tags_followed';
|
||||
|
|
|
@ -1,15 +1,20 @@
|
|||
import { connect } from 'react-redux';
|
||||
import { selectFollowedTags } from 'lbry-redux';
|
||||
import { makeSelectClaimForUri, selectFollowedTags } from 'lbry-redux';
|
||||
import { doToggleTagFollowDesktop } from 'redux/actions/tags';
|
||||
import * as CS from 'constants/claim_search';
|
||||
import Tags from './view';
|
||||
|
||||
const select = state => ({
|
||||
followedTags: selectFollowedTags(state),
|
||||
});
|
||||
const select = (state, props) => {
|
||||
const urlParams = new URLSearchParams(props.location.search);
|
||||
const repostedUri = decodeURIComponent(urlParams.get(CS.REPOSTED_URI_KEY));
|
||||
|
||||
export default connect(
|
||||
select,
|
||||
{
|
||||
doToggleTagFollowDesktop,
|
||||
}
|
||||
)(Tags);
|
||||
return {
|
||||
followedTags: selectFollowedTags(state),
|
||||
repostedUri: repostedUri,
|
||||
repostedClaim: repostedUri ? makeSelectClaimForUri(repostedUri)(state) : null,
|
||||
};
|
||||
};
|
||||
|
||||
export default connect(select, {
|
||||
doToggleTagFollowDesktop,
|
||||
})(Tags);
|
||||
|
|
|
@ -13,6 +13,8 @@ import * as CS from 'constants/claim_search';
|
|||
type Props = {
|
||||
location: { search: string },
|
||||
followedTags: Array<Tag>,
|
||||
repostedUri: string,
|
||||
repostedClaim: ?GenericClaim,
|
||||
doToggleTagFollowDesktop: string => void,
|
||||
};
|
||||
|
||||
|
@ -20,6 +22,8 @@ function TagsPage(props: Props) {
|
|||
const {
|
||||
location: { search },
|
||||
followedTags,
|
||||
repostedClaim,
|
||||
repostedUri,
|
||||
doToggleTagFollowDesktop,
|
||||
} = props;
|
||||
const buttonRef = useRef();
|
||||
|
@ -29,6 +33,7 @@ function TagsPage(props: Props) {
|
|||
const claimType = urlParams.get('claim_type');
|
||||
const tagsQuery = urlParams.get('t') || null;
|
||||
const tags = tagsQuery ? tagsQuery.split(',') : null;
|
||||
|
||||
// Eventually allow more than one tag on this page
|
||||
// Restricting to one to make follow/unfollow simpler
|
||||
const tag = (tags && tags[0]) || null;
|
||||
|
@ -48,27 +53,33 @@ function TagsPage(props: Props) {
|
|||
}
|
||||
}
|
||||
|
||||
let headerLabel;
|
||||
if (repostedClaim) {
|
||||
headerLabel = __('Reposts of %uri%', { uri: repostedUri });
|
||||
} else if (tag) {
|
||||
headerLabel = (
|
||||
<span>
|
||||
<Icon icon={ICONS.TAG} size={10} />
|
||||
{tag}
|
||||
</span>
|
||||
);
|
||||
} else {
|
||||
headerLabel = (
|
||||
<span>
|
||||
<Icon icon={ICONS.DISCOVER} size={10} />
|
||||
{__('All Content')}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<Page>
|
||||
<ClaimListDiscover
|
||||
claimType={claimType ? [claimType] : undefined}
|
||||
headerLabel={
|
||||
tag ? (
|
||||
<span>
|
||||
<Icon icon={ICONS.TAG} size={10} />
|
||||
{(tag === CS.TAGS_ALL && __('All Content')) ||
|
||||
(tag === CS.TAGS_FOLLOWED && __('Followed Tags')) ||
|
||||
__(tag)}
|
||||
</span>
|
||||
) : (
|
||||
<span>
|
||||
<Icon icon={ICONS.DISCOVER} size={10} />
|
||||
{__('All Content')}
|
||||
</span>
|
||||
)
|
||||
}
|
||||
defaultTags={CS.TAGS_ALL}
|
||||
headerLabel={headerLabel}
|
||||
tags={tags}
|
||||
hiddenNsfwMessage={<HiddenNsfw type="page" />}
|
||||
repostedClaimId={repostedClaim ? repostedClaim.claim_id : null}
|
||||
meta={
|
||||
tag && (
|
||||
<Button
|
||||
|
|
Loading…
Add table
Reference in a new issue