featured icon for reward content
This commit is contained in:
parent
230d2a451c
commit
b6d3a52f5d
|
@ -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,
|
||||||
|
|
|
@ -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)),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -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>🔥 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>
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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>🔥 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}>
|
||||||
|
|
5
ui/js/component/iconFeatured/index.js
Normal file
5
ui/js/component/iconFeatured/index.js
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
import React from "react";
|
||||||
|
import { connect } from "react-redux";
|
||||||
|
import IconFeatured from "./view";
|
||||||
|
|
||||||
|
export default connect(null, null)(IconFeatured);
|
14
ui/js/component/iconFeatured/view.jsx
Normal file
14
ui/js/component/iconFeatured/view.jsx
Normal 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;
|
|
@ -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";
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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>🔥 Hot Right Now</span>}
|
|
||||||
<div className="card__subtitle">
|
<div className="card__subtitle">
|
||||||
{channelUri
|
{channelUri
|
||||||
? <Link
|
? <Link
|
||||||
|
|
|
@ -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,
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
);
|
);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in a new issue