Indicate content eligible for Hot Right Now reward
This commit is contained in:
parent
1f588ff923
commit
230d2a451c
12 changed files with 97 additions and 6 deletions
|
@ -133,6 +133,34 @@ export function doFetchFeaturedUris() {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function doFetchHotRightNowContent() {
|
||||||
|
return function(dispatch, getState) {
|
||||||
|
const state = getState();
|
||||||
|
|
||||||
|
const success = nameToClaimId => {
|
||||||
|
dispatch({
|
||||||
|
type: types.FETCH_HOT_RIGHT_NOW_CONTENT_COMPLETED,
|
||||||
|
data: {
|
||||||
|
claimIds: Object.values(nameToClaimId),
|
||||||
|
success: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const failure = () => {
|
||||||
|
dispatch({
|
||||||
|
type: types.FETCH_HOT_RIGHT_NOW_CONTENT_COMPLETED,
|
||||||
|
data: {
|
||||||
|
claimIds: [],
|
||||||
|
success: false,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
lbryio.call("reward", "list_featured").then(success, failure);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
export function doUpdateLoadStatus(uri, outpoint) {
|
export function doUpdateLoadStatus(uri, outpoint) {
|
||||||
return function(dispatch, getState) {
|
return function(dispatch, getState) {
|
||||||
const state = getState();
|
const state = getState();
|
||||||
|
|
|
@ -7,6 +7,8 @@ import {
|
||||||
doAlertError,
|
doAlertError,
|
||||||
doRecordScroll,
|
doRecordScroll,
|
||||||
} from "actions/app";
|
} from "actions/app";
|
||||||
|
import { doFetchHotRightNowContent } from "actions/content";
|
||||||
|
|
||||||
import { doUpdateBalance } from "actions/wallet";
|
import { doUpdateBalance } from "actions/wallet";
|
||||||
import { selectWelcomeModalAcknowledged } from "selectors/app";
|
import { selectWelcomeModalAcknowledged } from "selectors/app";
|
||||||
import { selectUser } from "selectors/user";
|
import { selectUser } from "selectors/user";
|
||||||
|
@ -24,6 +26,7 @@ const perform = dispatch => ({
|
||||||
checkUpgradeAvailable: () => dispatch(doCheckUpgradeAvailable()),
|
checkUpgradeAvailable: () => dispatch(doCheckUpgradeAvailable()),
|
||||||
openWelcomeModal: () => dispatch(doOpenModal(modals.WELCOME)),
|
openWelcomeModal: () => dispatch(doOpenModal(modals.WELCOME)),
|
||||||
updateBalance: balance => dispatch(doUpdateBalance(balance)),
|
updateBalance: balance => dispatch(doUpdateBalance(balance)),
|
||||||
|
fetchHotRightNowContent: () => dispatch(doFetchHotRightNowContent()),
|
||||||
recordScroll: scrollPosition => dispatch(doRecordScroll(scrollPosition)),
|
recordScroll: scrollPosition => dispatch(doRecordScroll(scrollPosition)),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,12 @@ import * as modals from "constants/modal_types";
|
||||||
|
|
||||||
class App extends React.PureComponent {
|
class App extends React.PureComponent {
|
||||||
componentWillMount() {
|
componentWillMount() {
|
||||||
const { alertError, checkUpgradeAvailable, updateBalance } = this.props;
|
const {
|
||||||
|
alertError,
|
||||||
|
checkUpgradeAvailable,
|
||||||
|
updateBalance,
|
||||||
|
fetchHotRightNowContent,
|
||||||
|
} = this.props;
|
||||||
|
|
||||||
document.addEventListener("unhandledError", event => {
|
document.addEventListener("unhandledError", event => {
|
||||||
alertError(event.detail);
|
alertError(event.detail);
|
||||||
|
@ -26,6 +31,8 @@ class App extends React.PureComponent {
|
||||||
updateBalance(balance);
|
updateBalance(balance);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
fetchHotRightNowContent();
|
||||||
|
|
||||||
this.showWelcome(this.props);
|
this.showWelcome(this.props);
|
||||||
|
|
||||||
this.scrollListener = () => this.props.recordScroll(window.scrollY);
|
this.scrollListener = () => this.props.recordScroll(window.scrollY);
|
||||||
|
|
|
@ -8,7 +8,10 @@ import {
|
||||||
makeSelectMetadataForUri,
|
makeSelectMetadataForUri,
|
||||||
} from "selectors/claims";
|
} from "selectors/claims";
|
||||||
import { makeSelectFileInfoForUri } from "selectors/file_info";
|
import { makeSelectFileInfoForUri } from "selectors/file_info";
|
||||||
import { makeSelectIsResolvingForUri } from "selectors/content";
|
import {
|
||||||
|
makeSelectIsResolvingForUri,
|
||||||
|
selectHotRightNowClaimIds,
|
||||||
|
} from "selectors/content";
|
||||||
import FileCard from "./view";
|
import FileCard from "./view";
|
||||||
|
|
||||||
const makeSelect = () => {
|
const makeSelect = () => {
|
||||||
|
@ -22,6 +25,7 @@ const makeSelect = () => {
|
||||||
fileInfo: selectFileInfoForUri(state, props),
|
fileInfo: selectFileInfoForUri(state, props),
|
||||||
obscureNsfw: !selectShowNsfw(state),
|
obscureNsfw: !selectShowNsfw(state),
|
||||||
metadata: selectMetadataForUri(state, props),
|
metadata: selectMetadataForUri(state, props),
|
||||||
|
hotRightNowClaimIds: selectHotRightNowClaimIds(state, props),
|
||||||
isResolvingUri: selectResolvingUri(state, props),
|
isResolvingUri: selectResolvingUri(state, props),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -46,7 +46,14 @@ class FileCard extends React.PureComponent {
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { claim, fileInfo, metadata, isResolvingUri, navigate } = this.props;
|
const {
|
||||||
|
claim,
|
||||||
|
fileInfo,
|
||||||
|
metadata,
|
||||||
|
isResolvingUri,
|
||||||
|
navigate,
|
||||||
|
hotRightNowClaimIds,
|
||||||
|
} = this.props;
|
||||||
|
|
||||||
const uri = lbryuri.normalize(this.props.uri);
|
const uri = lbryuri.normalize(this.props.uri);
|
||||||
const title = metadata && metadata.title ? metadata.title : uri;
|
const title = metadata && metadata.title ? metadata.title : uri;
|
||||||
|
@ -54,6 +61,7 @@ class FileCard extends React.PureComponent {
|
||||||
? metadata.thumbnail
|
? metadata.thumbnail
|
||||||
: null;
|
: null;
|
||||||
const obscureNsfw = this.props.obscureNsfw && metadata && metadata.nsfw;
|
const obscureNsfw = this.props.obscureNsfw && metadata && metadata.nsfw;
|
||||||
|
const isHotRightNow = claim && hotRightNowClaimIds.includes(claim.claim_id);
|
||||||
|
|
||||||
let description = "";
|
let description = "";
|
||||||
if (isResolvingUri && !claim) {
|
if (isResolvingUri && !claim) {
|
||||||
|
@ -83,6 +91,7 @@ class FileCard extends React.PureComponent {
|
||||||
<div className="card__title" title={title}>
|
<div className="card__title" title={title}>
|
||||||
<TruncatedText lines={1}>{title}</TruncatedText>
|
<TruncatedText lines={1}>{title}</TruncatedText>
|
||||||
</div>
|
</div>
|
||||||
|
{isHotRightNow && <span>🔥 Hot Right Now</span>}
|
||||||
<div className="card__subtitle">
|
<div className="card__subtitle">
|
||||||
<span style={{ float: "right" }}>
|
<span style={{ float: "right" }}>
|
||||||
<FilePrice uri={uri} />
|
<FilePrice uri={uri} />
|
||||||
|
|
|
@ -8,7 +8,10 @@ import {
|
||||||
} from "selectors/claims";
|
} from "selectors/claims";
|
||||||
import { makeSelectFileInfoForUri } from "selectors/file_info";
|
import { makeSelectFileInfoForUri } from "selectors/file_info";
|
||||||
import { selectShowNsfw } from "selectors/settings";
|
import { selectShowNsfw } from "selectors/settings";
|
||||||
import { makeSelectIsResolvingForUri } from "selectors/content";
|
import {
|
||||||
|
makeSelectIsResolvingForUri,
|
||||||
|
selectHotRightNowClaimIds,
|
||||||
|
} from "selectors/content";
|
||||||
import FileTile from "./view";
|
import FileTile from "./view";
|
||||||
|
|
||||||
const makeSelect = () => {
|
const makeSelect = () => {
|
||||||
|
@ -23,6 +26,7 @@ const makeSelect = () => {
|
||||||
obscureNsfw: !selectShowNsfw(state),
|
obscureNsfw: !selectShowNsfw(state),
|
||||||
metadata: selectMetadataForUri(state, props),
|
metadata: selectMetadataForUri(state, props),
|
||||||
isResolvingUri: selectResolvingUri(state, props),
|
isResolvingUri: selectResolvingUri(state, props),
|
||||||
|
hotRightNowClaimIds: selectHotRightNowClaimIds(state, props),
|
||||||
});
|
});
|
||||||
|
|
||||||
return select;
|
return select;
|
||||||
|
|
|
@ -58,6 +58,7 @@ class FileTile extends React.PureComponent {
|
||||||
showEmpty,
|
showEmpty,
|
||||||
navigate,
|
navigate,
|
||||||
hidePrice,
|
hidePrice,
|
||||||
|
hotRightNowClaimIds,
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
const uri = lbryuri.normalize(this.props.uri);
|
const uri = lbryuri.normalize(this.props.uri);
|
||||||
|
@ -70,6 +71,8 @@ class FileTile extends React.PureComponent {
|
||||||
? metadata.thumbnail
|
? metadata.thumbnail
|
||||||
: null;
|
: null;
|
||||||
const obscureNsfw = this.props.obscureNsfw && metadata && metadata.nsfw;
|
const obscureNsfw = this.props.obscureNsfw && metadata && metadata.nsfw;
|
||||||
|
const isHotRightNow = claim && hotRightNowClaimIds.includes(claim.claim_id);
|
||||||
|
|
||||||
let onClick = () => navigate("/show", { uri });
|
let onClick = () => navigate("/show", { uri });
|
||||||
|
|
||||||
let description = "";
|
let description = "";
|
||||||
|
@ -108,6 +111,7 @@ class FileTile extends React.PureComponent {
|
||||||
{!hidePrice ? <FilePrice uri={this.props.uri} /> : null}
|
{!hidePrice ? <FilePrice uri={this.props.uri} /> : null}
|
||||||
<div className="meta">{uri}</div>
|
<div className="meta">{uri}</div>
|
||||||
<h3><TruncatedText lines={1}>{title}</TruncatedText></h3>
|
<h3><TruncatedText lines={1}>{title}</TruncatedText></h3>
|
||||||
|
{isHotRightNow && <span>🔥 Hot Right Now</span>}
|
||||||
</div>
|
</div>
|
||||||
<div className="card__content card__subtext">
|
<div className="card__content card__subtext">
|
||||||
<TruncatedText lines={3}>
|
<TruncatedText lines={3}>
|
||||||
|
|
|
@ -112,3 +112,5 @@ export const CLAIM_REWARD_STARTED = "CLAIM_REWARD_STARTED";
|
||||||
export const CLAIM_REWARD_SUCCESS = "CLAIM_REWARD_SUCCESS";
|
export const CLAIM_REWARD_SUCCESS = "CLAIM_REWARD_SUCCESS";
|
||||||
export const CLAIM_REWARD_FAILURE = "CLAIM_REWARD_FAILURE";
|
export const CLAIM_REWARD_FAILURE = "CLAIM_REWARD_FAILURE";
|
||||||
export const CLAIM_REWARD_CLEAR_ERROR = "CLAIM_REWARD_CLEAR_ERROR";
|
export const CLAIM_REWARD_CLEAR_ERROR = "CLAIM_REWARD_CLEAR_ERROR";
|
||||||
|
export const FETCH_HOT_RIGHT_NOW_CONTENT_COMPLETED =
|
||||||
|
"FETCH_HOT_RIGHT_NOW_CONTENT_COMPLETED";
|
||||||
|
|
|
@ -3,6 +3,7 @@ import { connect } from "react-redux";
|
||||||
import { doNavigate } from "actions/app";
|
import { doNavigate } from "actions/app";
|
||||||
import { doFetchFileInfo } from "actions/file_info";
|
import { doFetchFileInfo } from "actions/file_info";
|
||||||
import { makeSelectFileInfoForUri } from "selectors/file_info";
|
import { makeSelectFileInfoForUri } from "selectors/file_info";
|
||||||
|
import { selectHotRightNowClaimIds } from "selectors/content";
|
||||||
import { doFetchCostInfoForUri } from "actions/cost_info";
|
import { doFetchCostInfoForUri } from "actions/cost_info";
|
||||||
import {
|
import {
|
||||||
makeSelectClaimForUri,
|
makeSelectClaimForUri,
|
||||||
|
@ -27,6 +28,7 @@ const makeSelect = () => {
|
||||||
metadata: selectMetadata(state, props),
|
metadata: selectMetadata(state, props),
|
||||||
obscureNsfw: !selectShowNsfw(state),
|
obscureNsfw: !selectShowNsfw(state),
|
||||||
fileInfo: selectFileInfo(state, props),
|
fileInfo: selectFileInfo(state, props),
|
||||||
|
hotRightNowClaimIds: selectHotRightNowClaimIds(state, props),
|
||||||
});
|
});
|
||||||
|
|
||||||
return select;
|
return select;
|
||||||
|
|
|
@ -54,7 +54,14 @@ class FilePage extends React.PureComponent {
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { claim, fileInfo, metadata, contentType, uri } = this.props;
|
const {
|
||||||
|
claim,
|
||||||
|
fileInfo,
|
||||||
|
metadata,
|
||||||
|
contentType,
|
||||||
|
uri,
|
||||||
|
hotRightNowClaimIds,
|
||||||
|
} = this.props;
|
||||||
|
|
||||||
if (!claim || !metadata) {
|
if (!claim || !metadata) {
|
||||||
return (
|
return (
|
||||||
|
@ -80,6 +87,7 @@ class FilePage extends React.PureComponent {
|
||||||
? lbryuri.build({ channelName, claimId: channelClaimId }, false)
|
? lbryuri.build({ channelName, claimId: channelClaimId }, false)
|
||||||
: null;
|
: null;
|
||||||
const uriIndicator = <UriIndicator uri={uri} />;
|
const uriIndicator = <UriIndicator uri={uri} />;
|
||||||
|
const isHotRightNow = hotRightNowClaimIds.includes(claim.claim_id);
|
||||||
const mediaType = lbry.getMediaType(contentType);
|
const mediaType = lbry.getMediaType(contentType);
|
||||||
const player = require("render-media");
|
const player = require("render-media");
|
||||||
const obscureNsfw = this.props.obscureNsfw && metadata && metadata.nsfw;
|
const obscureNsfw = this.props.obscureNsfw && metadata && metadata.nsfw;
|
||||||
|
@ -105,6 +113,7 @@ class FilePage extends React.PureComponent {
|
||||||
</span>
|
</span>
|
||||||
: null}
|
: null}
|
||||||
<h1>{title}</h1>
|
<h1>{title}</h1>
|
||||||
|
{isHotRightNow && <span>🔥 Hot Right Now</span>}
|
||||||
<div className="card__subtitle">
|
<div className="card__subtitle">
|
||||||
{channelUri
|
{channelUri
|
||||||
? <Link
|
? <Link
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
import * as types from "constants/action_types";
|
import * as types from "constants/action_types";
|
||||||
|
|
||||||
const reducers = {};
|
const reducers = {};
|
||||||
const defaultState = {};
|
const defaultState = {
|
||||||
|
hotRightNowClaimIds: [],
|
||||||
|
};
|
||||||
|
|
||||||
reducers[types.FETCH_FEATURED_CONTENT_STARTED] = function(state, action) {
|
reducers[types.FETCH_FEATURED_CONTENT_STARTED] = function(state, action) {
|
||||||
return Object.assign({}, state, {
|
return Object.assign({}, state, {
|
||||||
|
@ -19,6 +21,18 @@ reducers[types.FETCH_FEATURED_CONTENT_COMPLETED] = function(state, action) {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
reducers[types.FETCH_HOT_RIGHT_NOW_CONTENT_COMPLETED] = function(
|
||||||
|
state,
|
||||||
|
action
|
||||||
|
) {
|
||||||
|
const { claimIds, success } = action.data;
|
||||||
|
|
||||||
|
return Object.assign({}, state, {
|
||||||
|
hotRightNowClaimIds: claimIds,
|
||||||
|
fetchingHotRightNowContentFailed: !success,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
reducers[types.RESOLVE_URI_STARTED] = function(state, action) {
|
reducers[types.RESOLVE_URI_STARTED] = function(state, action) {
|
||||||
const { uri } = action.data;
|
const { uri } = action.data;
|
||||||
|
|
||||||
|
|
|
@ -37,3 +37,8 @@ const selectTotalPagesForChannel = (state, props) => {
|
||||||
export const makeSelectTotalPagesForChannel = () => {
|
export const makeSelectTotalPagesForChannel = () => {
|
||||||
return createSelector(selectTotalPagesForChannel, totalPages => totalPages);
|
return createSelector(selectTotalPagesForChannel, totalPages => totalPages);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const selectHotRightNowClaimIds = createSelector(
|
||||||
|
_selectState,
|
||||||
|
state => state.hotRightNowClaimIds
|
||||||
|
);
|
||||||
|
|
Loading…
Reference in a new issue