mirror of
https://github.com/LBRYFoundation/lbry-desktop.git
synced 2025-08-28 16:01:26 +00:00
commit
1ead6a3be7
20 changed files with 243 additions and 244 deletions
|
@ -60,7 +60,7 @@ class IconComponent extends React.PureComponent<Props> {
|
||||||
}
|
}
|
||||||
const inner = <Icon size={size} className="icon" color={color} />;
|
const inner = <Icon size={size} className="icon" color={color} />;
|
||||||
|
|
||||||
return tooltip ? (
|
return tooltipText ? (
|
||||||
<Tooltip icon body={tooltipText} direction={tooltip}>
|
<Tooltip icon body={tooltipText} direction={tooltip}>
|
||||||
{inner}
|
{inner}
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
|
|
|
@ -5,10 +5,10 @@ import classnames from 'classnames';
|
||||||
type Props = {
|
type Props = {
|
||||||
body: string,
|
body: string,
|
||||||
label?: string,
|
label?: string,
|
||||||
children: ?React.Node,
|
children?: React.Node,
|
||||||
icon: ?boolean,
|
icon?: boolean,
|
||||||
direction: string,
|
direction: string,
|
||||||
onFormField?: boolean,
|
onComponent?: boolean, // extra padding to account for button/form field size
|
||||||
};
|
};
|
||||||
|
|
||||||
class ToolTip extends React.PureComponent<Props> {
|
class ToolTip extends React.PureComponent<Props> {
|
||||||
|
@ -17,9 +17,11 @@ class ToolTip extends React.PureComponent<Props> {
|
||||||
};
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { children, label, body, icon, direction, onFormField } = this.props;
|
const { children, label, body, icon, direction, onComponent } = this.props;
|
||||||
|
|
||||||
const tooltipContent = children || label;
|
const tooltipContent = children || label;
|
||||||
|
const bodyLength = body.length;
|
||||||
|
const isShortDescription = bodyLength < 30;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<span
|
<span
|
||||||
|
@ -30,11 +32,17 @@ class ToolTip extends React.PureComponent<Props> {
|
||||||
'tooltip--right': direction === 'right',
|
'tooltip--right': direction === 'right',
|
||||||
'tooltip--bottom': direction === 'bottom',
|
'tooltip--bottom': direction === 'bottom',
|
||||||
'tooltip--left': direction === 'left',
|
'tooltip--left': direction === 'left',
|
||||||
'tooltip--on-formfield': onFormField,
|
'tooltip--on-component': onComponent,
|
||||||
})}
|
})}
|
||||||
>
|
>
|
||||||
{tooltipContent}
|
{tooltipContent}
|
||||||
<span className="tooltip__body">{body}</span>
|
<span
|
||||||
|
className={classnames('tooltip__body', {
|
||||||
|
'tooltip__body--short': isShortDescription,
|
||||||
|
})}
|
||||||
|
>
|
||||||
|
{body}
|
||||||
|
</span>
|
||||||
</span>
|
</span>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
// @flow
|
// @flow
|
||||||
import React from 'react';
|
import * as React from 'react';
|
||||||
import Button from 'component/button';
|
import Button from 'component/button';
|
||||||
import { MODALS } from 'lbry-redux';
|
import { MODALS } from 'lbry-redux';
|
||||||
import classnames from 'classnames';
|
|
||||||
import * as icons from 'constants/icons';
|
import * as icons from 'constants/icons';
|
||||||
|
import Tooltip from 'component/common/tooltip';
|
||||||
|
|
||||||
type FileInfo = {
|
type FileInfo = {
|
||||||
claim_id: string,
|
claim_id: string,
|
||||||
|
@ -15,34 +15,35 @@ type Props = {
|
||||||
openModal: ({ id: string }, { uri: string }) => void,
|
openModal: ({ id: string }, { uri: string }) => void,
|
||||||
claimIsMine: boolean,
|
claimIsMine: boolean,
|
||||||
fileInfo: FileInfo,
|
fileInfo: FileInfo,
|
||||||
vertical?: boolean, // should the buttons be stacked vertically?
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class FileActions extends React.PureComponent<Props> {
|
class FileActions extends React.PureComponent<Props> {
|
||||||
render() {
|
render() {
|
||||||
const { fileInfo, uri, openModal, claimIsMine, vertical, claimId } = this.props;
|
const { fileInfo, uri, openModal, claimIsMine, claimId } = this.props;
|
||||||
const showDelete = fileInfo && Object.keys(fileInfo).length > 0;
|
const showDelete = fileInfo && Object.keys(fileInfo).length > 0;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<section className={classnames('card__actions', { 'card__actions--vertical': vertical })}>
|
<React.Fragment>
|
||||||
{showDelete && (
|
{showDelete && (
|
||||||
|
<Tooltip onComponent body={__('Delete this file')}>
|
||||||
<Button
|
<Button
|
||||||
button="alt"
|
button="alt"
|
||||||
icon={icons.TRASH}
|
icon={icons.TRASH}
|
||||||
iconColor="red"
|
description={__('Delete')}
|
||||||
label={__('Delete')}
|
|
||||||
onClick={() => openModal({ id: MODALS.CONFIRM_FILE_REMOVE }, { uri })}
|
onClick={() => openModal({ id: MODALS.CONFIRM_FILE_REMOVE }, { uri })}
|
||||||
/>
|
/>
|
||||||
|
</Tooltip>
|
||||||
)}
|
)}
|
||||||
{!claimIsMine && (
|
{!claimIsMine && (
|
||||||
|
<Tooltip onComponent body={__('Report content')}>
|
||||||
<Button
|
<Button
|
||||||
button="alt"
|
button="alt"
|
||||||
icon={icons.REPORT}
|
icon={icons.REPORT}
|
||||||
href={`https://lbry.io/dmca?claim_id=${claimId}`}
|
href={`https://lbry.io/dmca?claim_id=${claimId}`}
|
||||||
label={__('Report content')}
|
|
||||||
/>
|
/>
|
||||||
|
</Tooltip>
|
||||||
)}
|
)}
|
||||||
</section>
|
</React.Fragment>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import Button from 'component/button';
|
import Button from 'component/button';
|
||||||
import * as icons from 'constants/icons';
|
import * as icons from 'constants/icons';
|
||||||
|
import ToolTip from 'component/common/tooltip';
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
uri: string,
|
uri: string,
|
||||||
|
@ -59,7 +60,7 @@ class FileDownloadLink extends React.PureComponent<Props> {
|
||||||
if (loading || downloading) {
|
if (loading || downloading) {
|
||||||
const progress =
|
const progress =
|
||||||
fileInfo && fileInfo.written_bytes
|
fileInfo && fileInfo.written_bytes
|
||||||
? fileInfo.written_bytes / fileInfo.total_bytes * 100
|
? (fileInfo.written_bytes / fileInfo.total_bytes) * 100
|
||||||
: 0;
|
: 0;
|
||||||
const label = fileInfo
|
const label = fileInfo
|
||||||
? __('Downloading: ') + progress.toFixed(0) + __('% complete')
|
? __('Downloading: ') + progress.toFixed(0) + __('% complete')
|
||||||
|
@ -72,25 +73,22 @@ class FileDownloadLink extends React.PureComponent<Props> {
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
<ToolTip onComponent body={__('Download')}>
|
||||||
<Button
|
<Button
|
||||||
button="alt"
|
button="alt"
|
||||||
label={__('Download')}
|
|
||||||
icon={icons.DOWNLOAD}
|
icon={icons.DOWNLOAD}
|
||||||
iconColor="purple"
|
iconColor="purple"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
purchaseUri(uri);
|
purchaseUri(uri);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
</ToolTip>
|
||||||
);
|
);
|
||||||
} else if (fileInfo && fileInfo.download_path) {
|
} else if (fileInfo && fileInfo.download_path) {
|
||||||
return (
|
return (
|
||||||
<Button
|
<ToolTip onComponent body={__('Open file')}>
|
||||||
button="alt"
|
<Button button="alt" iconColor="purple" icon={icons.LOCAL} onClick={() => openFile()} />
|
||||||
iconColor="purple"
|
</ToolTip>
|
||||||
label={__('Open File')}
|
|
||||||
icon={icons.OPEN}
|
|
||||||
onClick={() => openFile()}
|
|
||||||
/>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,5 @@
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import {
|
import { makeSelectSearchUris, selectIsSearching, selectSearchDownloadUris } from 'lbry-redux';
|
||||||
doSearch,
|
|
||||||
makeSelectSearchUris,
|
|
||||||
selectIsSearching,
|
|
||||||
selectSearchDownloadUris,
|
|
||||||
} from 'lbry-redux';
|
|
||||||
import FileListSearch from './view';
|
import FileListSearch from './view';
|
||||||
|
|
||||||
const select = (state, props) => ({
|
const select = (state, props) => ({
|
||||||
|
@ -13,8 +8,9 @@ const select = (state, props) => ({
|
||||||
isSearching: selectIsSearching(state),
|
isSearching: selectIsSearching(state),
|
||||||
});
|
});
|
||||||
|
|
||||||
const perform = dispatch => ({
|
const perform = () => ({});
|
||||||
search: search => dispatch(doSearch(search)),
|
|
||||||
});
|
|
||||||
|
|
||||||
export default connect(select, perform)(FileListSearch);
|
export default connect(
|
||||||
|
select,
|
||||||
|
perform
|
||||||
|
)(FileListSearch);
|
||||||
|
|
|
@ -3,14 +3,10 @@ import React from 'react';
|
||||||
import FileTile from 'component/fileTile';
|
import FileTile from 'component/fileTile';
|
||||||
import ChannelTile from 'component/channelTile';
|
import ChannelTile from 'component/channelTile';
|
||||||
import { parseURI } from 'lbry-redux';
|
import { parseURI } from 'lbry-redux';
|
||||||
import debounce from 'util/debounce';
|
|
||||||
|
|
||||||
const SEARCH_DEBOUNCE_TIME = 800;
|
|
||||||
|
|
||||||
const NoResults = () => <div className="file-tile">{__('No results')}</div>;
|
const NoResults = () => <div className="file-tile">{__('No results')}</div>;
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
search: string => void,
|
|
||||||
query: string,
|
query: string,
|
||||||
isSearching: boolean,
|
isSearching: boolean,
|
||||||
uris: ?Array<string>,
|
uris: ?Array<string>,
|
||||||
|
@ -18,27 +14,6 @@ type Props = {
|
||||||
};
|
};
|
||||||
|
|
||||||
class FileListSearch extends React.PureComponent<Props> {
|
class FileListSearch extends React.PureComponent<Props> {
|
||||||
constructor(props: Props) {
|
|
||||||
super(props);
|
|
||||||
this.debouncedSearch = debounce(this.props.search, SEARCH_DEBOUNCE_TIME);
|
|
||||||
}
|
|
||||||
|
|
||||||
componentDidMount() {
|
|
||||||
const { search, query } = this.props;
|
|
||||||
search(query);
|
|
||||||
}
|
|
||||||
|
|
||||||
componentWillReceiveProps(nextProps: Props) {
|
|
||||||
const { query: nextQuery } = nextProps;
|
|
||||||
const { query: currentQuerry } = this.props;
|
|
||||||
|
|
||||||
if (nextQuery !== currentQuerry) {
|
|
||||||
this.debouncedSearch(nextQuery);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
debouncedSearch: string => void;
|
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { uris, query, downloadUris, isSearching } = this.props;
|
const { uris, query, downloadUris, isSearching } = this.props;
|
||||||
|
|
||||||
|
|
|
@ -131,17 +131,15 @@ class ActiveShapeShift extends React.PureComponent<Props> {
|
||||||
href={`https://shapeshift.io/#/status/${shiftOrderId}`}
|
href={`https://shapeshift.io/#/status/${shiftOrderId}`}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
</div>
|
||||||
{shiftState === statuses.NO_DEPOSITS &&
|
{shiftState === statuses.NO_DEPOSITS &&
|
||||||
shiftReturnAddress && (
|
shiftReturnAddress && (
|
||||||
<div className="shapeshift__actions-help">
|
<div className="help">
|
||||||
<span className="help">
|
|
||||||
If the transaction doesn't go through, ShapeShift will return your {shiftCoinType}{' '}
|
If the transaction doesn't go through, ShapeShift will return your {shiftCoinType}{' '}
|
||||||
back to {shiftReturnAddress}
|
back to {shiftReturnAddress}
|
||||||
</span>
|
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@ type Props = {
|
||||||
errorMessage: ?string,
|
errorMessage: ?string,
|
||||||
email: string,
|
email: string,
|
||||||
isPending: boolean,
|
isPending: boolean,
|
||||||
|
onModal?: boolean,
|
||||||
verifyUserEmail: (string, string) => void,
|
verifyUserEmail: (string, string) => void,
|
||||||
verifyUserEmailFailure: string => void,
|
verifyUserEmailFailure: string => void,
|
||||||
resendVerificationEmail: string => void,
|
resendVerificationEmail: string => void,
|
||||||
|
@ -50,7 +51,7 @@ class UserEmailVerify extends React.PureComponent<Props, State> {
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { cancelButton, errorMessage, email, isPending } = this.props;
|
const { cancelButton, errorMessage, email, isPending, onModal } = this.props;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Form onSubmit={this.handleSubmit}>
|
<Form onSubmit={this.handleSubmit}>
|
||||||
|
@ -77,12 +78,23 @@ class UserEmailVerify extends React.PureComponent<Props, State> {
|
||||||
<div className="card__actions">
|
<div className="card__actions">
|
||||||
<Submit label={__('Verify')} disabled={isPending} />
|
<Submit label={__('Verify')} disabled={isPending} />
|
||||||
{cancelButton}
|
{cancelButton}
|
||||||
|
{!onModal && (
|
||||||
|
<Button
|
||||||
|
button="link"
|
||||||
|
label={__('Resend verification email')}
|
||||||
|
onClick={this.handleResendVerificationEmail}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
{onModal && (
|
||||||
|
<div className="card__actions help">
|
||||||
<Button
|
<Button
|
||||||
button="link"
|
button="link"
|
||||||
label={__('Resend verification email')}
|
label={__('Resend verification email')}
|
||||||
onClick={this.handleResendVerificationEmail}
|
onClick={this.handleResendVerificationEmail}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
)}
|
||||||
</Form>
|
</Form>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -66,9 +66,11 @@ class WalletAddress extends React.PureComponent<Props> {
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{showQR && (
|
||||||
<div className="card__content">
|
<div className="card__content">
|
||||||
{showQR && <QRCode value={receiveAddress} paddingTop />}
|
<QRCode value={receiveAddress} paddingTop />
|
||||||
</div>
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
<div className="card__content">
|
<div className="card__content">
|
||||||
<div className="help">
|
<div className="help">
|
||||||
|
|
|
@ -3,8 +3,6 @@ import {
|
||||||
selectSearchState as selectSearch,
|
selectSearchState as selectSearch,
|
||||||
selectWunderBarAddress,
|
selectWunderBarAddress,
|
||||||
doUpdateSearchQuery,
|
doUpdateSearchQuery,
|
||||||
doNotify,
|
|
||||||
MODALS,
|
|
||||||
doFocusSearchInput,
|
doFocusSearchInput,
|
||||||
doBlurSearchInput,
|
doBlurSearchInput,
|
||||||
doSearch,
|
doSearch,
|
||||||
|
@ -28,7 +26,7 @@ const select = state => {
|
||||||
|
|
||||||
const perform = dispatch => ({
|
const perform = dispatch => ({
|
||||||
onSearch: query => {
|
onSearch: query => {
|
||||||
dispatch(doSearch(query));
|
dispatch(doSearch(query, 30)); // Hard coding this for now until https://github.com/lbryio/lbry-app/pull/1639 is merged
|
||||||
dispatch(doNavigate(`/search`, { query }));
|
dispatch(doNavigate(`/search`, { query }));
|
||||||
},
|
},
|
||||||
onSubmit: (uri, extraParams) => dispatch(doNavigate('/show', { uri, ...extraParams })),
|
onSubmit: (uri, extraParams) => dispatch(doNavigate('/show', { uri, ...extraParams })),
|
||||||
|
@ -37,4 +35,7 @@ const perform = dispatch => ({
|
||||||
doBlur: () => dispatch(doBlurSearchInput()),
|
doBlur: () => dispatch(doBlurSearchInput()),
|
||||||
});
|
});
|
||||||
|
|
||||||
export default connect(select, perform)(Wunderbar);
|
export default connect(
|
||||||
|
select,
|
||||||
|
perform
|
||||||
|
)(Wunderbar);
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
// @flow
|
// @flow
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import classnames from 'classnames';
|
import classnames from 'classnames';
|
||||||
import { normalizeURI } from 'lbry-redux';
|
import { normalizeURI, SEARCH_TYPES } from 'lbry-redux';
|
||||||
import Icon from 'component/common/icon';
|
import Icon from 'component/common/icon';
|
||||||
import { parseQueryParams } from 'util/query_params';
|
import { parseQueryParams } from 'util/query_params';
|
||||||
import * as icons from 'constants/icons';
|
import * as icons from 'constants/icons';
|
||||||
|
@ -29,7 +29,7 @@ class WunderBar extends React.PureComponent<Props> {
|
||||||
getSuggestionIcon = (type: string) => {
|
getSuggestionIcon = (type: string) => {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case 'file':
|
case 'file':
|
||||||
return icons.COMPASS;
|
return icons.LOCAL;
|
||||||
case 'channel':
|
case 'channel':
|
||||||
return icons.AT_SIGN;
|
return icons.AT_SIGN;
|
||||||
default:
|
default:
|
||||||
|
@ -109,7 +109,7 @@ class WunderBar extends React.PureComponent<Props> {
|
||||||
placeholder="Enter LBRY URL here or search for videos, music, games and more"
|
placeholder="Enter LBRY URL here or search for videos, music, games and more"
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
renderItem={({ value, type, shorthand }, isHighlighted) => (
|
renderItem={({ value, type }, isHighlighted) => (
|
||||||
<div
|
<div
|
||||||
key={value}
|
key={value}
|
||||||
className={classnames('wunderbar__suggestion', {
|
className={classnames('wunderbar__suggestion', {
|
||||||
|
@ -117,11 +117,13 @@ class WunderBar extends React.PureComponent<Props> {
|
||||||
})}
|
})}
|
||||||
>
|
>
|
||||||
<Icon icon={this.getSuggestionIcon(type)} />
|
<Icon icon={this.getSuggestionIcon(type)} />
|
||||||
<span className="wunderbar__suggestion-label">{shorthand || value}</span>
|
<span className="wunderbar__suggestion-label">{value}</span>
|
||||||
{(true || isHighlighted) && (
|
{isHighlighted && (
|
||||||
<span className="wunderbar__suggestion-label--action">
|
<span className="wunderbar__suggestion-label--action">
|
||||||
{'- '}
|
{'- '}
|
||||||
{type === 'search' ? 'Search' : value}
|
{type === SEARCH_TYPES.SEARCH && __('Search')}
|
||||||
|
{type === SEARCH_TYPES.CHANNEL && __('View channel')}
|
||||||
|
{type === SEARCH_TYPES.FILE && __('View file')}
|
||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -20,7 +20,7 @@ class ModalEmailCollection extends React.PureComponent<Props> {
|
||||||
if (user && !user.has_verified_email && !email) {
|
if (user && !user.has_verified_email && !email) {
|
||||||
return <UserEmailNew cancelButton={cancelButton} />;
|
return <UserEmailNew cancelButton={cancelButton} />;
|
||||||
} else if (user && !user.has_verified_email) {
|
} else if (user && !user.has_verified_email) {
|
||||||
return <UserEmailVerify cancelButton={cancelButton} />;
|
return <UserEmailVerify onModal cancelButton={cancelButton} />;
|
||||||
}
|
}
|
||||||
|
|
||||||
return closeModal();
|
return closeModal();
|
||||||
|
|
|
@ -167,10 +167,10 @@ class FilePage extends React.Component<Props> {
|
||||||
<div className="card__title-identity--file">
|
<div className="card__title-identity--file">
|
||||||
<h1 className="card__title card__title--file">{title}</h1>
|
<h1 className="card__title card__title--file">{title}</h1>
|
||||||
<div className="card__title-identity-icons">
|
<div className="card__title-identity-icons">
|
||||||
<FilePrice uri={normalizeURI(uri)} />
|
|
||||||
{isRewardContent && (
|
{isRewardContent && (
|
||||||
<Icon iconColor="red" tooltip="bottom" icon={icons.FEATURED} />
|
<Icon iconColor="red" tooltip="bottom" icon={icons.FEATURED} />
|
||||||
)}
|
)}
|
||||||
|
<FilePrice uri={normalizeURI(uri)} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<span className="card__subtitle card__subtitle--file">
|
<span className="card__subtitle card__subtitle--file">
|
||||||
|
@ -180,7 +180,10 @@ class FilePage extends React.Component<Props> {
|
||||||
{metadata.nsfw && <div>NSFW</div>}
|
{metadata.nsfw && <div>NSFW</div>}
|
||||||
<div className="card__channel-info">
|
<div className="card__channel-info">
|
||||||
<UriIndicator uri={uri} link />
|
<UriIndicator uri={uri} link />
|
||||||
<div className="card__actions card__actions--no-margin">
|
</div>
|
||||||
|
<div className="card__actions card__actions--between">
|
||||||
|
{(claimIsMine || subscriptionUri || speechSharable) && (
|
||||||
|
<div className="card__actions">
|
||||||
{claimIsMine ? (
|
{claimIsMine ? (
|
||||||
<Button
|
<Button
|
||||||
button="primary"
|
button="primary"
|
||||||
|
@ -194,10 +197,6 @@ class FilePage extends React.Component<Props> {
|
||||||
) : (
|
) : (
|
||||||
<SubscribeButton uri={subscriptionUri} channelName={channelName} />
|
<SubscribeButton uri={subscriptionUri} channelName={channelName} />
|
||||||
)}
|
)}
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{(!claimIsMine || speechSharable) && (
|
|
||||||
<div className="card__actions card__actions--end">
|
|
||||||
{!claimIsMine && (
|
{!claimIsMine && (
|
||||||
<Button
|
<Button
|
||||||
button="alt"
|
button="alt"
|
||||||
|
@ -211,29 +210,25 @@ class FilePage extends React.Component<Props> {
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
<FormRow alignRight padded>
|
|
||||||
|
<div className="card__actions">
|
||||||
|
<FileDownloadLink uri={uri} />
|
||||||
|
<FileActions uri={uri} claimId={claim.claim_id} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<FormRow padded>
|
||||||
|
<ToolTip onComponent body={__('Automatically download and play free content.')}>
|
||||||
<FormField
|
<FormField
|
||||||
useToggle
|
useToggle
|
||||||
name="autoplay"
|
name="autoplay"
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
|
postfix={__('Autoplay')}
|
||||||
checked={autoplay}
|
checked={autoplay}
|
||||||
onChange={this.onAutoplayChange}
|
onChange={this.onAutoplayChange}
|
||||||
postfix={
|
|
||||||
<ToolTip
|
|
||||||
onFormField
|
|
||||||
label={__('Autoplay')}
|
|
||||||
body={__('Automatically download and play free content.')}
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
/>
|
/>
|
||||||
|
</ToolTip>
|
||||||
</FormRow>
|
</FormRow>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="card__content">
|
|
||||||
<FileDownloadLink uri={uri} />
|
|
||||||
<FileActions uri={uri} claimId={claim.claim_id} />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="card__content--extra-padding">
|
<div className="card__content--extra-padding">
|
||||||
<FileDetails uri={uri} />
|
<FileDetails uri={uri} />
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,12 +1,11 @@
|
||||||
import React from 'react';
|
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import { selectIsSearching, selectSearchValue, doUpdateSearchQuery } from 'lbry-redux';
|
import { selectIsSearching, doUpdateSearchQuery, makeSelectCurrentParam } from 'lbry-redux';
|
||||||
import { doNavigate } from 'redux/actions/navigation';
|
import { doNavigate } from 'redux/actions/navigation';
|
||||||
import SearchPage from './view';
|
import SearchPage from './view';
|
||||||
|
|
||||||
const select = state => ({
|
const select = state => ({
|
||||||
isSearching: selectIsSearching(state),
|
isSearching: selectIsSearching(state),
|
||||||
query: selectSearchValue(state),
|
query: makeSelectCurrentParam('query')(state),
|
||||||
});
|
});
|
||||||
|
|
||||||
const perform = dispatch => ({
|
const perform = dispatch => ({
|
||||||
|
@ -14,4 +13,7 @@ const perform = dispatch => ({
|
||||||
updateSearchQuery: query => dispatch(doUpdateSearchQuery(query)),
|
updateSearchQuery: query => dispatch(doUpdateSearchQuery(query)),
|
||||||
});
|
});
|
||||||
|
|
||||||
export default connect(select, perform)(SearchPage);
|
export default connect(
|
||||||
|
select,
|
||||||
|
perform
|
||||||
|
)(SearchPage);
|
||||||
|
|
|
@ -8,31 +8,11 @@ import Page from 'component/page';
|
||||||
import Icon from 'component/common/icon';
|
import Icon from 'component/common/icon';
|
||||||
import * as icons from 'constants/icons';
|
import * as icons from 'constants/icons';
|
||||||
|
|
||||||
const MODAL_ANIMATION_TIME = 250;
|
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
query: ?string,
|
query: ?string,
|
||||||
};
|
};
|
||||||
|
|
||||||
class SearchPage extends React.PureComponent<Props> {
|
class SearchPage extends React.PureComponent<Props> {
|
||||||
constructor() {
|
|
||||||
super();
|
|
||||||
|
|
||||||
this.input = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
componentDidMount() {
|
|
||||||
// Wait for the modal to animate down before focusing
|
|
||||||
// without this there is an issue with scroll the page down
|
|
||||||
setTimeout(() => {
|
|
||||||
if (this.input) {
|
|
||||||
this.input.focus();
|
|
||||||
}
|
|
||||||
}, MODAL_ANIMATION_TIME);
|
|
||||||
}
|
|
||||||
|
|
||||||
input: ?HTMLInputElement;
|
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { query } = this.props;
|
const { query } = this.props;
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -190,15 +190,7 @@ p {
|
||||||
|
|
||||||
.main--contained {
|
.main--contained {
|
||||||
max-width: 1000px;
|
max-width: 1000px;
|
||||||
margin: 0 80px - $spacing-width;
|
margin: auto;
|
||||||
|
|
||||||
@media only screen and (min-width: $medium-breakpoint) {
|
|
||||||
margin: 0 120px - $spacing-width;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media only screen and (min-width: $large-breakpoint) {
|
|
||||||
margin: 0 200px - $spacing-width;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.main--no-padding {
|
.main--no-padding {
|
||||||
|
|
|
@ -93,9 +93,10 @@
|
||||||
.card__title-identity--file {
|
.card__title-identity--file {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
.credit-amount,
|
justify-content: space-between;
|
||||||
|
|
||||||
.icon {
|
.icon {
|
||||||
margin: $spacing-vertical * 1/3;
|
margin: 0 $spacing-vertical * 1/3;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -113,9 +114,9 @@
|
||||||
.card__title--small {
|
.card__title--small {
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
line-height: 18px;
|
line-height: 18px;
|
||||||
padding-top: 20px;
|
padding-top: $spacing-vertical / 3;
|
||||||
|
|
||||||
@media only screen and (min-width: $medium-breakpoint) {
|
@media only screen and (min-width: $large-breakpoint) {
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -198,7 +199,7 @@
|
||||||
|
|
||||||
.card__subtext-title {
|
.card__subtext-title {
|
||||||
color: var(--text-color);
|
color: var(--text-color);
|
||||||
font-size: calc(var(--font-size-subtext-multiple) * 1.5em);
|
font-size: calc(var(--font-size-subtext-multiple) * 1.2em);
|
||||||
|
|
||||||
&:not(:first-of-type) {
|
&:not(:first-of-type) {
|
||||||
margin-top: $spacing-vertical * 3/2;
|
margin-top: $spacing-vertical * 3/2;
|
||||||
|
@ -220,10 +221,14 @@
|
||||||
margin-top: $spacing-vertical * 2/3;
|
margin-top: $spacing-vertical * 2/3;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|
||||||
&:not(.card__actions--vertical) .btn:nth-child(n + 2) {
|
&:not(.card__actions--vertical) {
|
||||||
|
.btn:nth-child(n + 2),
|
||||||
|
// For buttons wrapped in a tooltip
|
||||||
|
.tooltip:nth-child(n + 2) {
|
||||||
margin-left: $spacing-vertical / 3;
|
margin-left: $spacing-vertical / 3;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.card__actions--no-margin {
|
.card__actions--no-margin {
|
||||||
margin-top: 0;
|
margin-top: 0;
|
||||||
|
@ -258,6 +263,11 @@
|
||||||
justify-content: flex-end;
|
justify-content: flex-end;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.card__actions--between {
|
||||||
|
justify-content: space-between;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
.card-row is used on the discover page
|
.card-row is used on the discover page
|
||||||
It is a list of cards that extend past the right edge of the screen
|
It is a list of cards that extend past the right edge of the screen
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
.file-download {
|
.file-download {
|
||||||
font-size: 0.8em;
|
font-size: 0.8em;
|
||||||
|
align-self: center;
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,6 +53,7 @@
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
justify-items: flex-start;
|
justify-items: flex-start;
|
||||||
|
align-items: center;
|
||||||
font-family: 'metropolis-medium';
|
font-family: 'metropolis-medium';
|
||||||
|
|
||||||
&:not(:first-of-type) {
|
&:not(:first-of-type) {
|
||||||
|
@ -74,6 +75,9 @@
|
||||||
.wunderbar__suggestion-label--action {
|
.wunderbar__suggestion-label--action {
|
||||||
margin-left: $spacing-vertical * 1/3;
|
margin-left: $spacing-vertical * 1/3;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
|
font-family: 'metropolis-medium';
|
||||||
|
font-size: 12px;
|
||||||
|
line-height: 0.1; // to vertically align because the font size is smaller
|
||||||
}
|
}
|
||||||
|
|
||||||
.wunderbar__active-suggestion {
|
.wunderbar__active-suggestion {
|
||||||
|
|
|
@ -13,16 +13,13 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.tooltip--on-formfield {
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tooltip--icon {
|
.tooltip--icon {
|
||||||
margin-top: 5px;
|
margin-top: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Tooltip text */
|
/* Tooltip text */
|
||||||
.tooltip .tooltip__body {
|
.tooltip {
|
||||||
|
.tooltip__body {
|
||||||
background-color: var(--tooltip-bg);
|
background-color: var(--tooltip-bg);
|
||||||
font-family: 'metropolis-medium';
|
font-family: 'metropolis-medium';
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
|
@ -37,7 +34,11 @@
|
||||||
visibility: hidden;
|
visibility: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tooltip .tooltip__body::after {
|
.tooltip__body--short {
|
||||||
|
width: 130px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tooltip__body::after {
|
||||||
content: ' ';
|
content: ' ';
|
||||||
width: 0;
|
width: 0;
|
||||||
height: 0;
|
height: 0;
|
||||||
|
@ -46,11 +47,24 @@
|
||||||
border-style: solid;
|
border-style: solid;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tooltip--top .tooltip__body {
|
&.tooltip--on-component {
|
||||||
|
.tooltip__body {
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.tooltip--top {
|
||||||
|
.tooltip__body {
|
||||||
bottom: 100%;
|
bottom: 100%;
|
||||||
left: 50%;
|
left: 50%;
|
||||||
margin-left: -100px;
|
margin-left: -100px;
|
||||||
|
|
||||||
|
&.tooltip__body--short {
|
||||||
|
margin-left: -65px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
&::after {
|
&::after {
|
||||||
top: 100%;
|
top: 100%;
|
||||||
left: 50%;
|
left: 50%;
|
||||||
|
@ -59,7 +73,8 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.tooltip--right .tooltip__body {
|
.tooltip--right {
|
||||||
|
.tooltip__body {
|
||||||
margin-top: -5px;
|
margin-top: -5px;
|
||||||
margin-left: 10px;
|
margin-left: 10px;
|
||||||
|
|
||||||
|
@ -70,12 +85,18 @@
|
||||||
border-color: transparent var(--tooltip-bg) transparent transparent;
|
border-color: transparent var(--tooltip-bg) transparent transparent;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.tooltip--bottom .tooltip__body {
|
.tooltip--bottom {
|
||||||
|
.tooltip__body {
|
||||||
top: 90%;
|
top: 90%;
|
||||||
left: 50%;
|
left: 50%;
|
||||||
margin-left: -100px;
|
margin-left: -100px;
|
||||||
|
|
||||||
|
&.tooltip__body--short {
|
||||||
|
margin-left: -65px;
|
||||||
|
}
|
||||||
|
|
||||||
&::after {
|
&::after {
|
||||||
bottom: 100%;
|
bottom: 100%;
|
||||||
left: 50%;
|
left: 50%;
|
||||||
|
@ -83,6 +104,7 @@
|
||||||
border-color: transparent transparent var(--tooltip-bg) transparent;
|
border-color: transparent transparent var(--tooltip-bg) transparent;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.tooltip--left .tooltip__body {
|
.tooltip--left .tooltip__body {
|
||||||
top: -5px;
|
top: -5px;
|
||||||
|
|
Loading…
Add table
Reference in a new issue