featured icon for reward content

This commit is contained in:
Jeremy Kauffman 2017-07-29 18:56:08 -04:00
parent 230d2a451c
commit b6d3a52f5d
17 changed files with 67 additions and 36 deletions

View file

@ -133,13 +133,13 @@ export function doFetchFeaturedUris() {
}; };
} }
export function doFetchHotRightNowContent() { export function doFetchRewardedContent() {
return function(dispatch, getState) { return function(dispatch, getState) {
const state = getState(); const state = getState();
const success = nameToClaimId => { const success = nameToClaimId => {
dispatch({ dispatch({
type: types.FETCH_HOT_RIGHT_NOW_CONTENT_COMPLETED, type: types.FETCH_REWARD_CONTENT_COMPLETED,
data: { data: {
claimIds: Object.values(nameToClaimId), claimIds: Object.values(nameToClaimId),
success: true, success: true,
@ -149,7 +149,7 @@ export function doFetchHotRightNowContent() {
const failure = () => { const failure = () => {
dispatch({ dispatch({
type: types.FETCH_HOT_RIGHT_NOW_CONTENT_COMPLETED, type: types.FETCH_REWARD_CONTENT_COMPLETED,
data: { data: {
claimIds: [], claimIds: [],
success: false, success: false,

View file

@ -7,7 +7,7 @@ import {
doAlertError, doAlertError,
doRecordScroll, doRecordScroll,
} from "actions/app"; } from "actions/app";
import { doFetchHotRightNowContent } from "actions/content"; import { doFetchRewardedContent } from "actions/content";
import { doUpdateBalance } from "actions/wallet"; import { doUpdateBalance } from "actions/wallet";
import { selectWelcomeModalAcknowledged } from "selectors/app"; import { selectWelcomeModalAcknowledged } from "selectors/app";
@ -26,7 +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()), fetchRewardedContent: () => dispatch(doFetchRewardedContent()),
recordScroll: scrollPosition => dispatch(doRecordScroll(scrollPosition)), recordScroll: scrollPosition => dispatch(doRecordScroll(scrollPosition)),
}); });

View file

@ -16,7 +16,7 @@ class App extends React.PureComponent {
alertError, alertError,
checkUpgradeAvailable, checkUpgradeAvailable,
updateBalance, updateBalance,
fetchHotRightNowContent, fetchRewardedContent,
} = this.props; } = this.props;
document.addEventListener("unhandledError", event => { document.addEventListener("unhandledError", event => {
@ -31,7 +31,7 @@ class App extends React.PureComponent {
updateBalance(balance); updateBalance(balance);
}); });
fetchHotRightNowContent(); fetchRewardedContent();
this.showWelcome(this.props); this.showWelcome(this.props);

View file

@ -10,7 +10,7 @@ import {
import { makeSelectFileInfoForUri } from "selectors/file_info"; import { makeSelectFileInfoForUri } from "selectors/file_info";
import { import {
makeSelectIsResolvingForUri, makeSelectIsResolvingForUri,
selectHotRightNowClaimIds, selectRewardContentClaimIds,
} from "selectors/content"; } from "selectors/content";
import FileCard from "./view"; import FileCard from "./view";
@ -25,7 +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), rewardedContentClaimIds: selectRewardContentClaimIds(state, props),
isResolvingUri: selectResolvingUri(state, props), isResolvingUri: selectResolvingUri(state, props),
}); });

View file

@ -2,7 +2,8 @@ import React from "react";
import lbryuri from "lbryuri.js"; import lbryuri from "lbryuri.js";
import CardMedia from "component/cardMedia"; import CardMedia from "component/cardMedia";
import Link from "component/link"; import Link from "component/link";
import { Thumbnail, TruncatedText, Icon } from "component/common"; import { TruncatedText, Icon } from "component/common";
import IconFeatured from "component/iconFeatured";
import FilePrice from "component/filePrice"; import FilePrice from "component/filePrice";
import UriIndicator from "component/uriIndicator"; import UriIndicator from "component/uriIndicator";
import NsfwOverlay from "component/nsfwOverlay"; import NsfwOverlay from "component/nsfwOverlay";
@ -52,7 +53,7 @@ class FileCard extends React.PureComponent {
metadata, metadata,
isResolvingUri, isResolvingUri,
navigate, navigate,
hotRightNowClaimIds, rewardedContentClaimIds,
} = this.props; } = this.props;
const uri = lbryuri.normalize(this.props.uri); const uri = lbryuri.normalize(this.props.uri);
@ -61,7 +62,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); const isRewardContent = claim && rewardedContentClaimIds.includes(claim.claim_id);
let description = ""; let description = "";
if (isResolvingUri && !claim) { if (isResolvingUri && !claim) {
@ -91,13 +92,11 @@ 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>&#128293; 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} />
{fileInfo {isRewardContent && <span>{" "}<IconFeatured /></span> }
? <span>{" "}<Icon fixed icon="icon-folder" /></span> {fileInfo && <span>{" "}<Icon fixed icon="icon-folder" /></span> }
: ""}
</span> </span>
<UriIndicator uri={uri} /> <UriIndicator uri={uri} />
</div> </div>

View file

@ -10,7 +10,7 @@ import { makeSelectFileInfoForUri } from "selectors/file_info";
import { selectShowNsfw } from "selectors/settings"; import { selectShowNsfw } from "selectors/settings";
import { import {
makeSelectIsResolvingForUri, makeSelectIsResolvingForUri,
selectHotRightNowClaimIds, selectRewardContentClaimIds,
} from "selectors/content"; } from "selectors/content";
import FileTile from "./view"; import FileTile from "./view";
@ -26,7 +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), rewardedContentClaimIds: selectRewardContentClaimIds(state, props),
}); });
return select; return select;

View file

@ -1,11 +1,11 @@
import React from "react"; import React from "react";
import lbry from "lbry.js";
import lbryuri from "lbryuri.js"; import lbryuri from "lbryuri.js";
import CardMedia from "component/cardMedia"; import CardMedia from "component/cardMedia";
import Link from "component/link"; import Link from "component/link";
import { TruncatedText } from "component/common.js"; import { TruncatedText } from "component/common.js";
import FilePrice from "component/filePrice"; import FilePrice from "component/filePrice";
import NsfwOverlay from "component/nsfwOverlay"; import NsfwOverlay from "component/nsfwOverlay";
import IconFeatured from "component/iconFeatured";
class FileTile extends React.PureComponent { class FileTile extends React.PureComponent {
static SHOW_EMPTY_PUBLISH = "publish"; static SHOW_EMPTY_PUBLISH = "publish";
@ -58,7 +58,7 @@ class FileTile extends React.PureComponent {
showEmpty, showEmpty,
navigate, navigate,
hidePrice, hidePrice,
hotRightNowClaimIds, rewardedContentClaimIds,
} = this.props; } = this.props;
const uri = lbryuri.normalize(this.props.uri); const uri = lbryuri.normalize(this.props.uri);
@ -71,7 +71,7 @@ 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); const isRewardContent = claim && rewardedContentClaimIds.includes(claim.claim_id);
let onClick = () => navigate("/show", { uri }); let onClick = () => navigate("/show", { uri });
@ -109,9 +109,11 @@ class FileTile extends React.PureComponent {
<div className="file-tile__content"> <div className="file-tile__content">
<div className="card__title-primary"> <div className="card__title-primary">
{!hidePrice ? <FilePrice uri={this.props.uri} /> : null} {!hidePrice ? <FilePrice uri={this.props.uri} /> : null}
{isRewardContent && <IconFeatured /> }
<div className="meta">{uri}</div> <div className="meta">{uri}</div>
<h3><TruncatedText lines={1}>{title}</TruncatedText></h3> <h3>
{isHotRightNow && <span>&#128293; Hot Right Now</span>} <TruncatedText lines={1}>{title}</TruncatedText>
</h3>
</div> </div>
<div className="card__content card__subtext"> <div className="card__content card__subtext">
<TruncatedText lines={3}> <TruncatedText lines={3}>

View file

@ -0,0 +1,5 @@
import React from "react";
import { connect } from "react-redux";
import IconFeatured from "./view";
export default connect(null, null)(IconFeatured);

View file

@ -0,0 +1,14 @@
import React from "react";
import { Icon } from "component/common.js";
const IconFeatured = props => {
return (
<span className="icon-featured" title={ __("Watch content with this icon to earn weekly rewards.")}>
<Icon icon="icon-star"
fixed
className="card__icon-featured-content" />
</span>
);
};
export default IconFeatured;

View file

@ -112,5 +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 = export const FETCH_REWARD_CONTENT_COMPLETED =
"FETCH_HOT_RIGHT_NOW_CONTENT_COMPLETED"; "FETCH_REWARD_CONTENT_COMPLETED";

View file

@ -3,7 +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 { selectRewardContentClaimIds } from "selectors/content";
import { doFetchCostInfoForUri } from "actions/cost_info"; import { doFetchCostInfoForUri } from "actions/cost_info";
import { import {
makeSelectClaimForUri, makeSelectClaimForUri,
@ -28,7 +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), rewardedContentClaimIds: selectRewardContentClaimIds(state, props),
}); });
return select; return select;

View file

@ -8,6 +8,7 @@ import FilePrice from "component/filePrice";
import FileActions from "component/fileActions"; import FileActions from "component/fileActions";
import Link from "component/link"; import Link from "component/link";
import UriIndicator from "component/uriIndicator"; import UriIndicator from "component/uriIndicator";
import IconFeatured from "component/iconFeatured";
const FormatItem = props => { const FormatItem = props => {
const { contentType, metadata: { language, license } } = props; const { contentType, metadata: { language, license } } = props;
@ -60,7 +61,7 @@ class FilePage extends React.PureComponent {
metadata, metadata,
contentType, contentType,
uri, uri,
hotRightNowClaimIds, rewardedContentClaimIds,
} = this.props; } = this.props;
if (!claim || !metadata) { if (!claim || !metadata) {
@ -87,7 +88,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 isRewardContent = rewardedContentClaimIds.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;
@ -110,10 +111,10 @@ class FilePage extends React.PureComponent {
{!fileInfo || fileInfo.written_bytes <= 0 {!fileInfo || fileInfo.written_bytes <= 0
? <span style={{ float: "right" }}> ? <span style={{ float: "right" }}>
<FilePrice uri={lbryuri.normalize(uri)} /> <FilePrice uri={lbryuri.normalize(uri)} />
{isRewardContent && <span>{" "}<IconFeatured /></span> }
</span> </span>
: null} : null}
<h1>{title}</h1> <h1>{title}</h1>
{isHotRightNow && <span>&#128293; Hot Right Now</span>}
<div className="card__subtitle"> <div className="card__subtitle">
{channelUri {channelUri
? <Link ? <Link

View file

@ -2,7 +2,7 @@ import * as types from "constants/action_types";
const reducers = {}; const reducers = {};
const defaultState = { const defaultState = {
hotRightNowClaimIds: [], rewardedContentClaimIds: [],
}; };
reducers[types.FETCH_FEATURED_CONTENT_STARTED] = function(state, action) { reducers[types.FETCH_FEATURED_CONTENT_STARTED] = function(state, action) {
@ -21,15 +21,14 @@ reducers[types.FETCH_FEATURED_CONTENT_COMPLETED] = function(state, action) {
}); });
}; };
reducers[types.FETCH_HOT_RIGHT_NOW_CONTENT_COMPLETED] = function( reducers[types.FETCH_REWARD_CONTENT_COMPLETED] = function(
state, state,
action action
) { ) {
const { claimIds, success } = action.data; const { claimIds, success } = action.data;
return Object.assign({}, state, { return Object.assign({}, state, {
hotRightNowClaimIds: claimIds, rewardedContentClaimIds: claimIds,
fetchingHotRightNowContentFailed: !success,
}); });
}; };

View file

@ -38,7 +38,7 @@ export const makeSelectTotalPagesForChannel = () => {
return createSelector(selectTotalPagesForChannel, totalPages => totalPages); return createSelector(selectTotalPagesForChannel, totalPages => totalPages);
}; };
export const selectHotRightNowClaimIds = createSelector( export const selectRewardContentClaimIds = createSelector(
_selectState, _selectState,
state => state.hotRightNowClaimIds state => state.rewardedContentClaimIds
); );

View file

@ -134,10 +134,14 @@ p
} }
} }
/*should this be here or work this way? had to hack additional rule below*/
.icon:only-child { .icon:only-child {
position: relative; position: relative;
top: 0.16em; top: 0.16em;
} }
.icon-featured > .icon {
top: 0;
}
.help { .help {
font-size: .85em; font-size: .85em;

View file

@ -256,3 +256,7 @@ $padding-right-card-hover-hack: 30px;
.card-row__nav--right { .card-row__nav--right {
right: -1 * $padding-right-card-hover-hack; right: -1 * $padding-right-card-hover-hack;
} }
.card__icon-featured-content {
color: orangered;
}

View file

@ -7,6 +7,9 @@ $height-file-tile: $spacing-vertical * 6;
.credit-amount { .credit-amount {
float: right; float: right;
} }
.icon-featured {
float: right;
}
//also a hack //also a hack
.card__media { .card__media {
height: $height-file-tile; height: $height-file-tile;