This commit is contained in:
Sean Yesmunt 2019-06-27 16:27:38 -04:00
parent 2ca254a573
commit c6412eebef
20 changed files with 101 additions and 83 deletions

View file

@ -63,7 +63,7 @@
"@exponent/electron-cookies": "^2.0.0", "@exponent/electron-cookies": "^2.0.0",
"@hot-loader/react-dom": "16.8", "@hot-loader/react-dom": "16.8",
"@lbry/color": "^1.0.2", "@lbry/color": "^1.0.2",
"@lbry/components": "^2.7.2", "@lbry/components": "^2.7.4",
"@reach/rect": "^0.2.1", "@reach/rect": "^0.2.1",
"@reach/tabs": "^0.1.5", "@reach/tabs": "^0.1.5",
"@reach/tooltip": "^0.2.1", "@reach/tooltip": "^0.2.1",

View file

@ -1,5 +1,5 @@
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { makeSelectFileInfoForUri, makeSelectClaimIsMine, makeSelectClaimForUri } from 'lbry-redux'; import { makeSelectFileInfoForUri, makeSelectClaimIsMine } from 'lbry-redux';
import { selectRewardContentClaimIds } from 'lbryinc'; import { selectRewardContentClaimIds } from 'lbryinc';
import { makeSelectIsSubscribed, makeSelectIsNew } from 'redux/selectors/subscriptions'; import { makeSelectIsSubscribed, makeSelectIsNew } from 'redux/selectors/subscriptions';
import FileProperties from './view'; import FileProperties from './view';
@ -10,7 +10,6 @@ const select = (state, props) => ({
isSubscribed: makeSelectIsSubscribed(props.uri)(state), isSubscribed: makeSelectIsSubscribed(props.uri)(state),
isNew: makeSelectIsNew(props.uri)(state), isNew: makeSelectIsNew(props.uri)(state),
claimIsMine: makeSelectClaimIsMine(props.uri)(state), claimIsMine: makeSelectClaimIsMine(props.uri)(state),
claim: makeSelectClaimForUri(props.uri)(state),
}); });
export default connect( export default connect(

View file

@ -4,10 +4,10 @@ import * as React from 'react';
import { parseURI } from 'lbry-redux'; import { parseURI } from 'lbry-redux';
import Icon from 'component/common/icon'; import Icon from 'component/common/icon';
import FilePrice from 'component/filePrice'; import FilePrice from 'component/filePrice';
import VideoDuration from 'component/videoDuration';
type Props = { type Props = {
uri: string, uri: string,
claim: ?StreamClaim,
downloaded: boolean, downloaded: boolean,
claimIsMine: boolean, claimIsMine: boolean,
isSubscribed: boolean, isSubscribed: boolean,
@ -16,32 +16,17 @@ type Props = {
}; };
export default function FileProperties(props: Props) { export default function FileProperties(props: Props) {
const { claim, uri, downloaded, claimIsMine, rewardedContentClaimIds, isSubscribed } = props; const { uri, downloaded, claimIsMine, rewardedContentClaimIds, isSubscribed } = props;
const { claimId } = parseURI(uri); const { claimId } = parseURI(uri);
const isRewardContent = rewardedContentClaimIds.includes(claimId); const isRewardContent = rewardedContentClaimIds.includes(claimId);
const video = claim && claim.value && claim.value.video;
let duration;
if (video && video.duration) {
// $FlowFixMe
let date = new Date(null);
date.setSeconds(video.duration);
let timeString = date.toISOString().substr(11, 8);
if (timeString.startsWith('00:')) {
timeString = timeString.substr(3);
}
duration = timeString;
}
return ( return (
<div className="file-properties"> <div className="file-properties">
{isSubscribed && <Icon tooltip icon={icons.SUBSCRIPTION} />} {isSubscribed && <Icon tooltip icon={icons.SUBSCRIPTION} />}
{!claimIsMine && downloaded && <Icon tooltip icon={icons.DOWNLOAD} />} {!claimIsMine && downloaded && <Icon tooltip icon={icons.DOWNLOAD} />}
{isRewardContent && <Icon tooltip icon={icons.FEATURED} />} {isRewardContent && <Icon tooltip icon={icons.FEATURED} />}
<FilePrice hideFree uri={uri} /> <FilePrice hideFree uri={uri} />
{duration && <span className="media__subtitle">{duration}</span>} <VideoDuration className="media__subtitle" uri={uri} />
</div> </div>
); );
} }

View file

@ -15,6 +15,7 @@ const select = state => ({
channel: makeSelectPublishFormValue('channel')(state), channel: makeSelectPublishFormValue('channel')(state),
bid: makeSelectPublishFormValue('bid')(state), bid: makeSelectPublishFormValue('bid')(state),
uri: makeSelectPublishFormValue('uri')(state), uri: makeSelectPublishFormValue('uri')(state),
bid: makeSelectPublishFormValue('bid')(state),
isStillEditing: selectIsStillEditing(state), isStillEditing: selectIsStillEditing(state),
isResolvingUri: selectIsResolvingPublishUris(state), isResolvingUri: selectIsResolvingPublishUris(state),
amountNeededForTakeover: selectTakeOverAmount(state), amountNeededForTakeover: selectTakeOverAmount(state),

View file

@ -10,7 +10,7 @@ type Props = {
name: string, name: string,
channel: string, channel: string,
uri: string, uri: string,
bid: string, bid: number,
balance: number, balance: number,
isStillEditing: boolean, isStillEditing: boolean,
myClaimForUri: ?StreamClaim, myClaimForUri: ?StreamClaim,
@ -27,7 +27,7 @@ function PublishText(props: Props) {
uri, uri,
isStillEditing, isStillEditing,
myClaimForUri, myClaimForUri,
bid: bidString, bid,
isResolvingUri, isResolvingUri,
amountNeededForTakeover, amountNeededForTakeover,
prepareEdit, prepareEdit,
@ -37,7 +37,6 @@ function PublishText(props: Props) {
const [nameError, setNameError] = useState(undefined); const [nameError, setNameError] = useState(undefined);
const [bidError, setBidError] = useState(undefined); const [bidError, setBidError] = useState(undefined);
const previousBidAmount = myClaimForUri && Number(myClaimForUri.amount); const previousBidAmount = myClaimForUri && Number(myClaimForUri.amount);
const bid = Number(bidString);
function editExistingClaim() { function editExistingClaim() {
if (myClaimForUri) { if (myClaimForUri) {

View file

@ -1,4 +1,5 @@
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { doUpdatePublishForm } from 'redux/actions/publish';
import { makeSelectPublishFormValue } from 'redux/selectors/publish'; import { makeSelectPublishFormValue } from 'redux/selectors/publish';
import PublishPage from './view'; import PublishPage from './view';
@ -7,7 +8,11 @@ const select = state => ({
fee: makeSelectPublishFormValue('fee')(state), fee: makeSelectPublishFormValue('fee')(state),
}); });
const perform = dispatch => ({
updatePublishForm: values => dispatch(doUpdatePublishForm(values)),
});
export default connect( export default connect(
select, select,
null perform
)(PublishPage); )(PublishPage);

View file

@ -10,7 +10,7 @@ type Props = {
function RewardTotal(props: Props) { function RewardTotal(props: Props) {
const { rewards } = props; const { rewards } = props;
const rewardTotal = rewards.reduce((acc, val) => acc + val.reward_amount, 0); const rewardTotal = rewards.reduce((acc, val) => acc + val.reward_amount, 0);
const total = useTween(rewardTotal * 25); const total = useTween(rewardTotal * 40);
const integer = Math.round(total * rewardTotal); const integer = Math.round(total * rewardTotal);
return ( return (

View file

@ -20,6 +20,7 @@ export default function Tag(props: Props) {
<Button <Button
{...clickProps} {...clickProps}
disabled={disabled} disabled={disabled}
title={type === 'add' ? __('Add tag') : __('Remove tag')}
className={classnames('tag', { className={classnames('tag', {
'tag--add': type === 'add', 'tag--add': type === 'add',
'tag--remove': type === 'remove', 'tag--remove': type === 'remove',

View file

@ -19,7 +19,7 @@ type Props = {
}; };
export default function TagSelect(props: Props) { export default function TagSelect(props: Props) {
const { unfollowedTags, followedTags, doToggleTagFollow, doAddTag, onSelect } = props; const { unfollowedTags = [], followedTags = [], doToggleTagFollow, doAddTag, onSelect } = props;
const [newTag, setNewTag] = useState(''); const [newTag, setNewTag] = useState('');
let tags = unfollowedTags.slice(); let tags = unfollowedTags.slice();
@ -27,9 +27,14 @@ export default function TagSelect(props: Props) {
tags.unshift({ name: newTag }); tags.unshift({ name: newTag });
} }
const doesTagMatch = ({ name }) => (newTag ? name.toLowerCase().includes(newTag.toLowerCase()) : true); const doesTagMatch = name => (newTag ? name.toLowerCase().includes(newTag.toLowerCase()) : true);
const suggestedTags = tags.filter(doesTagMatch).slice(0, 5); // Make sure there are no duplicates, then trim
const suggestedTransitions = useTransition(suggestedTags, tag => tag.name, unfollowedTagsAnimation); const suggestedTagsSet = new Set(tags.map(tag => tag.name));
const suggestedTags = Array.from(suggestedTagsSet)
.filter(doesTagMatch)
.slice(0, 5);
const suggestedTransitions = useTransition(suggestedTags, tag => tag, unfollowedTagsAnimation);
function onChange(e) { function onChange(e) {
setNewTag(e.target.value); setNewTag(e.target.value);
@ -42,11 +47,11 @@ export default function TagSelect(props: Props) {
if (onSelect) { if (onSelect) {
onSelect({ name: newTag }); onSelect({ name: newTag });
} else { } else {
if (!unfollowedTags.includes(newTag)) { if (!unfollowedTags.map(({ name }) => name).includes(newTag)) {
doAddTag(newTag); doAddTag(newTag);
} }
if (!followedTags.includes(newTag)) { if (!followedTags.map(({ name }) => name).includes(newTag)) {
doToggleTagFollow(newTag); doToggleTagFollow(newTag);
} }
} }
@ -54,9 +59,9 @@ export default function TagSelect(props: Props) {
function handleTagClick(tag) { function handleTagClick(tag) {
if (onSelect) { if (onSelect) {
onSelect(tag); onSelect({ name: tag });
} else { } else {
doToggleTagFollow(tag.name); doToggleTagFollow(tag);
} }
} }
@ -74,7 +79,7 @@ export default function TagSelect(props: Props) {
<ul className="tags"> <ul className="tags">
{suggestedTransitions.map(({ item, key, props }) => ( {suggestedTransitions.map(({ item, key, props }) => (
<animated.li key={key} style={props}> <animated.li key={key} style={props}>
<Tag name={item.name} type="add" onClick={() => handleTagClick(item)} /> <Tag name={item} type="add" onClick={() => handleTagClick(item)} />
</animated.li> </animated.li>
))} ))}
{!suggestedTransitions.length && <p className="empty tags__empty-message">No suggested tags</p>} {!suggestedTransitions.length && <p className="empty tags__empty-message">No suggested tags</p>}

View file

@ -0,0 +1,12 @@
import { connect } from 'react-redux';
import { makeSelectClaimForUri } from 'lbry-redux';
import VideoDuration from './view';
const select = (state, props) => ({
claim: makeSelectClaimForUri(props.uri)(state),
});
export default connect(
select,
null
)(VideoDuration);

View file

@ -0,0 +1,30 @@
// @flow
import React from 'react';
type Props = {
claim: ?StreamClaim,
className?: string,
};
function VideoDuration(props: Props) {
const { claim, className } = props;
const video = claim && claim.value && claim.value.video;
let duration;
if (video && video.duration) {
// $FlowFixMe
let date = new Date(null);
date.setSeconds(video.duration);
let timeString = date.toISOString().substr(11, 8);
if (timeString.startsWith('00:')) {
timeString = timeString.substr(3);
}
duration = timeString;
}
return duration ? <span className={className}>{duration}</span> : null;
}
export default VideoDuration;

View file

@ -9,9 +9,7 @@ import InvitePage from 'page/invite';
const WalletPage = () => ( const WalletPage = () => (
<Page> <Page>
<UserEmail /> <UnsupportedOnWeb />
{IS_WEB && <UnsupportedOnWeb />}
<div className={classnames({ 'card--disabled': IS_WEB })}> <div className={classnames({ 'card--disabled': IS_WEB })}>
<div className="columns"> <div className="columns">
<UserEmail /> <UserEmail />

View file

@ -22,6 +22,7 @@ import RecommendedContent from 'component/recommendedContent';
import ClaimTags from 'component/claimTags'; import ClaimTags from 'component/claimTags';
import CommentsList from 'component/commentsList'; import CommentsList from 'component/commentsList';
import CommentCreate from 'component/commentCreate'; import CommentCreate from 'component/commentCreate';
import VideoDuration from 'component/videoDuration';
type Props = { type Props = {
claim: StreamClaim, claim: StreamClaim,
@ -184,21 +185,6 @@ class FilePage extends React.Component<Props> {
const insufficientCredits = !claimIsMine && costInfo && costInfo.cost > balance; const insufficientCredits = !claimIsMine && costInfo && costInfo.cost > balance;
const video = claim && claim.value && claim.value.video;
let duration;
if (video && video.duration) {
// $FlowFixMe
let date = new Date(null);
date.setSeconds(video.duration);
let timeString = date.toISOString().substr(11, 8);
if (timeString.startsWith('00:')) {
timeString = timeString.substr(3);
}
duration = timeString;
}
return ( return (
<Page className="main--file-page"> <Page className="main--file-page">
<div className="grid-area--content card"> <div className="grid-area--content card">
@ -295,7 +281,7 @@ class FilePage extends React.Component<Props> {
</div> </div>
<div className="media__subtext media__subtext--large"> <div className="media__subtext media__subtext--large">
{video && <p className="media__info-text">{duration}</p>} <VideoDuration uri={uri} />
{claimIsMine && ( {claimIsMine && (
<p> <p>

View file

@ -18,9 +18,16 @@
} }
} }
// Fix this in lbry/components .button--primary {
.button--primary:not(:hover) { &:not(:hover) {
background-color: $lbry-teal-4; // fix this in components repo
background-color: $lbry-teal-4;
}
&:hover {
background-color: $lbry-teal-3;
}
svg { svg {
color: white; color: white;
} }

View file

@ -96,8 +96,8 @@
} }
.claim-preview--injected, .claim-preview--injected,
.claim-preview { .claim-preview + .claim-preview {
border-top: 1px solid rgba($lbry-teal-5, 0.1); border-bottom: 1px solid rgba($lbry-teal-5, 0.1);
} }
.claim-preview--large { .claim-preview--large {
@ -147,6 +147,7 @@
.claim-preview-properties { .claim-preview-properties {
align-items: flex-end; align-items: flex-end;
flex: 1;
} }
.claim-preview-title { .claim-preview-title {

View file

@ -1,25 +1,5 @@
@import '~@lbry/components/sass/form/_index.scss'; @import '~@lbry/components/sass/form/_index.scss';
// replace this
form {
// setting the font size here sizes everything within
&:not(:last-child) {
margin-bottom: var(--spacing-s);
}
}
input,
select {
height: var(--spacing-l);
border: 1px solid;
}
checkbox-element,
radio-element,
select {
cursor: pointer;
}
textarea { textarea {
&::placeholder { &::placeholder {
opacity: 0.4; opacity: 0.4;

View file

@ -145,6 +145,7 @@
// S U B T I T L E // S U B T I T L E
.media__subtitle { .media__subtitle {
align-self: flex-start;
font-size: 0.8em; font-size: 0.8em;
color: rgba($lbry-black, 0.6); color: rgba($lbry-black, 0.6);

View file

@ -57,6 +57,10 @@ $main: $lbry-teal-5;
&:active { &:active {
background-color: $main; background-color: $main;
} }
&:focus {
@include focus;
}
} }
.tag--remove { .tag--remove {

View file

@ -15,3 +15,7 @@
} }
} }
} }
@mixin focus {
box-shadow: 0 0 0 2px $lbry-blue-1;
}

View file

@ -862,10 +862,10 @@
resolved "https://registry.yarnpkg.com/@lbry/color/-/color-1.1.1.tgz#b80ec25fb515d436129332b20c767c5a7014ac09" resolved "https://registry.yarnpkg.com/@lbry/color/-/color-1.1.1.tgz#b80ec25fb515d436129332b20c767c5a7014ac09"
integrity sha512-BdxqWmm84WYOd1ZsPruJiGr7WBEophVfJKg7oywFOAMb0h6ERe4Idx1ceweMSvCOyPlR5GAhil9Gvk70SBFdxQ== integrity sha512-BdxqWmm84WYOd1ZsPruJiGr7WBEophVfJKg7oywFOAMb0h6ERe4Idx1ceweMSvCOyPlR5GAhil9Gvk70SBFdxQ==
"@lbry/components@^2.7.2": "@lbry/components@^2.7.4":
version "2.7.2" version "2.7.4"
resolved "https://registry.yarnpkg.com/@lbry/components/-/components-2.7.2.tgz#a941ced2adf78ab52026f5533e5f6b3454f862a9" resolved "https://registry.yarnpkg.com/@lbry/components/-/components-2.7.4.tgz#3a633725137ffcb1f081f71dbf5397d66bf444cd"
integrity sha512-TSBmxc4i2E3v7qGC7LgdcrUUcpiUYBA1KMVSW5vrpDJroNy3fnr3/niGJTudVQ4LQzlOXpt7bsRATFh8vRmXnQ== integrity sha512-X0QBpdlsPntmuC/COolx/rOmUxa5XeHDjdcpl79Db3Y3upkEYwwtvl+S/OkkPbdxouoJfZTB4QqQuGkNi1xGdw==
"@mapbox/hast-util-table-cell-style@^0.1.3": "@mapbox/hast-util-table-cell-style@^0.1.3":
version "0.1.3" version "0.1.3"