Merge branch 'master' into publishWarnings
This commit is contained in:
commit
b14336175e
28 changed files with 290 additions and 190 deletions
|
@ -40,6 +40,8 @@
|
|||
"react/require-default-props": 0,
|
||||
"react/jsx-closing-tag-location": 0,
|
||||
"jsx-a11y/no-noninteractive-element-to-interactive-role": 0,
|
||||
"class-methods-use-this": 0
|
||||
"class-methods-use-this": 0,
|
||||
"jsx-a11y/interactive-supports-focus": 0,
|
||||
"jsx-a11y/click-events-have-key-events": 0
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,9 +10,11 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/).
|
|||
|
||||
### Changed
|
||||
* Make tooltip smarter ([#1979](https://github.com/lbryio/lbry-desktop/pull/1979))
|
||||
* Change channel pages to have 48 items instead of 10 ([#2002](https://github.com/lbryio/lbry-desktop/pull/2002))
|
||||
|
||||
### Fixed
|
||||
* Invite table cutoff with large number of invites ([#1985](https://github.com/lbryio/lbry-desktop/pull/1985))
|
||||
* History styling on large screens and link issue with claims ([#1999](https://github.com/lbryio/lbry-desktop/pull/1999))
|
||||
* Satisfy console warnings in publishForm and validation messaging ([#2010](https://github.com/lbryio/lbry-desktop/pull/2010))
|
||||
|
||||
|
||||
|
|
10
src/renderer/component/copyableText/index.js
Normal file
10
src/renderer/component/copyableText/index.js
Normal file
|
@ -0,0 +1,10 @@
|
|||
import { connect } from 'react-redux';
|
||||
import { doNotify } from 'lbry-redux';
|
||||
import CopyableText from './view';
|
||||
|
||||
export default connect(
|
||||
null,
|
||||
{
|
||||
doNotify,
|
||||
}
|
||||
)(CopyableText);
|
63
src/renderer/component/copyableText/view.jsx
Normal file
63
src/renderer/component/copyableText/view.jsx
Normal file
|
@ -0,0 +1,63 @@
|
|||
// @flow
|
||||
import * as React from 'react';
|
||||
import { clipboard } from 'electron';
|
||||
import { FormRow } from 'component/common/form';
|
||||
import Button from 'component/button';
|
||||
import * as icons from 'constants/icons';
|
||||
/*
|
||||
noSnackbar added due to issue 1945
|
||||
https://github.com/lbryio/lbry-desktop/issues/1945
|
||||
"Snackbars and modals can't be displayed at the same time"
|
||||
*/
|
||||
type Props = {
|
||||
copyable: string,
|
||||
noSnackbar: boolean,
|
||||
doNotify: ({ message: string, displayType: Array<string> }) => void,
|
||||
};
|
||||
|
||||
export default class CopyableText extends React.PureComponent<Props> {
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.input = null;
|
||||
}
|
||||
|
||||
input: ?HTMLInputElement;
|
||||
|
||||
render() {
|
||||
const { copyable, doNotify, noSnackbar } = this.props;
|
||||
|
||||
return (
|
||||
<FormRow verticallyCentered padded stretch>
|
||||
<input
|
||||
className="input-copyable form-field__input"
|
||||
readOnly
|
||||
value={copyable || ''}
|
||||
ref={input => {
|
||||
this.input = input;
|
||||
}}
|
||||
onFocus={() => {
|
||||
if (this.input) {
|
||||
this.input.select();
|
||||
}
|
||||
}}
|
||||
/>
|
||||
|
||||
<Button
|
||||
noPadding
|
||||
button="secondary"
|
||||
icon={icons.CLIPBOARD}
|
||||
onClick={() => {
|
||||
clipboard.writeText(copyable);
|
||||
if (!noSnackbar) {
|
||||
doNotify({
|
||||
message: __('Text copied'),
|
||||
displayType: ['snackbar'],
|
||||
});
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</FormRow>
|
||||
);
|
||||
}
|
||||
}
|
|
@ -5,13 +5,11 @@ import { CC_LICENSES, COPYRIGHT, OTHER, PUBLIC_DOMAIN, NONE } from 'constants/li
|
|||
|
||||
type Props = {
|
||||
licenseType: string,
|
||||
copyrightNotice: ?string,
|
||||
licenseUrl: ?string,
|
||||
otherLicenseDescription: ?string,
|
||||
handleLicenseChange: (string, string) => void,
|
||||
handleLicenseDescriptionChange: (SyntheticInputEvent<*>) => void,
|
||||
handleLicenseUrlChange: (SyntheticInputEvent<*>) => void,
|
||||
handleCopyrightNoticeChange: (SyntheticInputEvent<*>) => void,
|
||||
};
|
||||
|
||||
class LicenseType extends React.PureComponent<Props> {
|
||||
|
@ -38,11 +36,8 @@ class LicenseType extends React.PureComponent<Props> {
|
|||
licenseType,
|
||||
otherLicenseDescription,
|
||||
licenseUrl,
|
||||
copyrightNotice,
|
||||
handleLicenseChange,
|
||||
handleLicenseDescriptionChange,
|
||||
handleLicenseUrlChange,
|
||||
handleCopyrightNoticeChange,
|
||||
} = this.props;
|
||||
|
||||
return (
|
||||
|
@ -72,8 +67,8 @@ class LicenseType extends React.PureComponent<Props> {
|
|||
label={__('Copyright notice')}
|
||||
type="text"
|
||||
name="copyright-notice"
|
||||
value={copyrightNotice}
|
||||
onChange={handleCopyrightNoticeChange}
|
||||
value={otherLicenseDescription}
|
||||
onChange={handleLicenseDescriptionChange}
|
||||
/>
|
||||
</FormRow>
|
||||
)}
|
||||
|
|
|
@ -44,7 +44,6 @@ type Props = {
|
|||
licenseType: string,
|
||||
otherLicenseDescription: ?string,
|
||||
licenseUrl: ?string,
|
||||
copyrightNotice: ?string,
|
||||
uri: ?string,
|
||||
bidError: ?string,
|
||||
publishing: boolean,
|
||||
|
@ -199,7 +198,6 @@ class PublishForm extends React.PureComponent<Props> {
|
|||
handlePublish() {
|
||||
const {
|
||||
filePath,
|
||||
copyrightNotice,
|
||||
licenseType,
|
||||
licenseUrl,
|
||||
otherLicenseDescription,
|
||||
|
@ -210,8 +208,6 @@ class PublishForm extends React.PureComponent<Props> {
|
|||
let publishingLicense;
|
||||
switch (licenseType) {
|
||||
case COPYRIGHT:
|
||||
publishingLicense = copyrightNotice;
|
||||
break;
|
||||
case OTHER:
|
||||
publishingLicense = otherLicenseDescription;
|
||||
break;
|
||||
|
@ -232,7 +228,6 @@ class PublishForm extends React.PureComponent<Props> {
|
|||
license: publishingLicense,
|
||||
licenseUrl: publishingLicenseUrl,
|
||||
otherLicenseDescription,
|
||||
copyrightNotice,
|
||||
name: this.props.name,
|
||||
contentIsFree: this.props.contentIsFree,
|
||||
price: this.props.price,
|
||||
|
@ -338,7 +333,6 @@ class PublishForm extends React.PureComponent<Props> {
|
|||
licenseType,
|
||||
otherLicenseDescription,
|
||||
licenseUrl,
|
||||
copyrightNotice,
|
||||
uri,
|
||||
bidError,
|
||||
publishing,
|
||||
|
@ -584,7 +578,6 @@ class PublishForm extends React.PureComponent<Props> {
|
|||
licenseType={licenseType}
|
||||
otherLicenseDescription={otherLicenseDescription}
|
||||
licenseUrl={licenseUrl}
|
||||
copyrightNotice={copyrightNotice}
|
||||
handleLicenseChange={(newLicenseType, newLicenseUrl) =>
|
||||
updatePublishForm({
|
||||
licenseType: newLicenseType,
|
||||
|
@ -599,9 +592,6 @@ class PublishForm extends React.PureComponent<Props> {
|
|||
handleLicenseUrlChange={event =>
|
||||
updatePublishForm({ licenseUrl: event.target.value })
|
||||
}
|
||||
handleCopyrightNoticeChange={event =>
|
||||
updatePublishForm({ copyrightNotice: event.target.value })
|
||||
}
|
||||
/>
|
||||
</section>
|
||||
|
||||
|
|
|
@ -3,12 +3,13 @@ import React from 'react';
|
|||
import type { Claim } from 'types/claim';
|
||||
import Button from 'component/button';
|
||||
import * as icons from 'constants/icons';
|
||||
import Tooltip from 'component/common/tooltip';
|
||||
import Address from 'component/address';
|
||||
import CopyableText from 'component/copyableText';
|
||||
import ToolTip from 'component/common/tooltip';
|
||||
|
||||
type Props = {
|
||||
claim: Claim,
|
||||
onDone: () => void,
|
||||
speechShareable: boolean,
|
||||
};
|
||||
|
||||
class SocialShare extends React.PureComponent<Props> {
|
||||
|
@ -27,46 +28,79 @@ class SocialShare extends React.PureComponent<Props> {
|
|||
channel_name: channelName,
|
||||
value,
|
||||
} = this.props.claim;
|
||||
const { speechShareable, onDone } = this.props;
|
||||
const channelClaimId =
|
||||
value && value.publisherSignature && value.publisherSignature.certificateId;
|
||||
const { onDone } = this.props;
|
||||
const speechPrefix = 'http://spee.ch/';
|
||||
const lbryPrefix = 'http://open.lbry.io/';
|
||||
|
||||
const speechURL =
|
||||
channelName && channelClaimId
|
||||
? `${speechPrefix}${channelName}:${channelClaimId}/${claimName}`
|
||||
: `${speechPrefix}${claimName}#${claimId}`;
|
||||
|
||||
const lbryURL = `${lbryPrefix}${claimName}#${claimId}`;
|
||||
|
||||
return (
|
||||
<section className="card__content">
|
||||
<Address address={speechURL} noSnackbar />
|
||||
<div className="card__actions card__actions--center">
|
||||
<Tooltip onComponent body={__('Facebook')}>
|
||||
<Button
|
||||
iconColor="blue"
|
||||
icon={icons.FACEBOOK}
|
||||
button="alt"
|
||||
label={__('')}
|
||||
href={`https://facebook.com/sharer/sharer.php?u=${speechURL}`}
|
||||
/>
|
||||
</Tooltip>
|
||||
<Tooltip onComponent body={__('Twitter')}>
|
||||
<Button
|
||||
iconColor="blue"
|
||||
icon={icons.TWITTER}
|
||||
button="alt"
|
||||
label={__('')}
|
||||
href={`https://twitter.com/home?status=${speechURL}`}
|
||||
/>
|
||||
</Tooltip>
|
||||
<Tooltip onComponent body={__('View on Spee.ch')}>
|
||||
<Button
|
||||
icon={icons.GLOBE}
|
||||
iconColor="blue"
|
||||
button="alt"
|
||||
label={__('')}
|
||||
href={`${speechURL}`}
|
||||
/>
|
||||
</Tooltip>
|
||||
{speechShareable && (
|
||||
<div className="card__content">
|
||||
<label className="card__subtitle">{__('Web link')}</label>
|
||||
<CopyableText copyable={speechURL} noSnackbar />
|
||||
<div className="card__actions card__actions--center">
|
||||
<ToolTip onComponent body={__('Facebook')}>
|
||||
<Button
|
||||
iconColor="blue"
|
||||
icon={icons.FACEBOOK}
|
||||
button="alt"
|
||||
label={__('')}
|
||||
href={`https://facebook.com/sharer/sharer.php?u=${speechURL}`}
|
||||
/>
|
||||
</ToolTip>
|
||||
<ToolTip onComponent body={__('Twitter')}>
|
||||
<Button
|
||||
iconColor="blue"
|
||||
icon={icons.TWITTER}
|
||||
button="alt"
|
||||
label={__('')}
|
||||
href={`https://twitter.com/home?status=${speechURL}`}
|
||||
/>
|
||||
</ToolTip>
|
||||
<ToolTip onComponent body={__('View on Spee.ch')}>
|
||||
<Button
|
||||
icon={icons.GLOBE}
|
||||
iconColor="blue"
|
||||
button="alt"
|
||||
label={__('')}
|
||||
href={`${speechURL}`}
|
||||
/>
|
||||
</ToolTip>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
<div className="card__content">
|
||||
<label className="card__subtitle">{__('LBRY App link')}</label>
|
||||
<CopyableText copyable={lbryURL} noSnackbar />
|
||||
<div className="card__actions card__actions--center">
|
||||
<ToolTip onComponent body={__('Facebook')}>
|
||||
<Button
|
||||
iconColor="blue"
|
||||
icon={icons.FACEBOOK}
|
||||
button="alt"
|
||||
label={__('')}
|
||||
href={`https://facebook.com/sharer/sharer.php?u=${lbryURL}`}
|
||||
/>
|
||||
</ToolTip>
|
||||
<ToolTip onComponent body={__('Twitter')}>
|
||||
<Button
|
||||
iconColor="blue"
|
||||
icon={icons.TWITTER}
|
||||
button="alt"
|
||||
label={__('')}
|
||||
href={`https://twitter.com/home?status=${lbryURL}`}
|
||||
/>
|
||||
</ToolTip>
|
||||
</div>
|
||||
</div>
|
||||
<div className="card__actions">
|
||||
<Button button="link" label={__('Done')} onClick={onDone} />
|
||||
|
|
|
@ -24,6 +24,10 @@ class TransactionListRecent extends React.PureComponent<Props> {
|
|||
return (
|
||||
<section className="card card--section">
|
||||
<div className="card__title">{__('Recent Transactions')}</div>
|
||||
<div className="card__subtitle">
|
||||
{__('To view all of your transactions, navigate to the')}{' '}
|
||||
<Button button="link" navigate="/history" label={__('transactions page')} />.
|
||||
</div>
|
||||
{fetchingTransactions && (
|
||||
<div className="card__content">
|
||||
<BusyIndicator message={__('Loading transactions')} />
|
||||
|
|
|
@ -99,7 +99,8 @@ class UserHistoryPage extends React.PureComponent<Props, State> {
|
|||
|
||||
const allSelected = Object.keys(itemsSelected).length === history.length;
|
||||
const selectHandler = allSelected ? this.unselectAll : this.selectAll;
|
||||
return (
|
||||
|
||||
return history.length ? (
|
||||
<React.Fragment>
|
||||
<div className="card__actions card__actions--between">
|
||||
{Object.keys(itemsSelected).length ? (
|
||||
|
@ -109,7 +110,6 @@ class UserHistoryPage extends React.PureComponent<Props, State> {
|
|||
{/* Using an empty span so spacing stays the same if the button isn't rendered */}
|
||||
</span>
|
||||
)}
|
||||
|
||||
<Button
|
||||
button="link"
|
||||
label={allSelected ? __('Cancel') : __('Select All')}
|
||||
|
@ -117,21 +117,19 @@ class UserHistoryPage extends React.PureComponent<Props, State> {
|
|||
/>
|
||||
</div>
|
||||
{!!history.length && (
|
||||
<table className="card--section table table--stretch table--history">
|
||||
<tbody>
|
||||
{history.map(item => (
|
||||
<UserHistoryItem
|
||||
key={item.uri}
|
||||
uri={item.uri}
|
||||
lastViewed={item.lastViewed}
|
||||
selected={!!itemsSelected[item.uri]}
|
||||
onSelect={() => {
|
||||
this.onSelect(item.uri);
|
||||
}}
|
||||
/>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
<section className="item-list">
|
||||
{history.map(item => (
|
||||
<UserHistoryItem
|
||||
key={item.uri}
|
||||
uri={item.uri}
|
||||
lastViewed={item.lastViewed}
|
||||
selected={!!itemsSelected[item.uri]}
|
||||
onSelect={() => {
|
||||
this.onSelect(item.uri);
|
||||
}}
|
||||
/>
|
||||
))}
|
||||
</section>
|
||||
)}
|
||||
{pageCount > 1 && (
|
||||
<FormRow padded verticallyCentered centered>
|
||||
|
@ -161,6 +159,13 @@ class UserHistoryPage extends React.PureComponent<Props, State> {
|
|||
</FormRow>
|
||||
)}
|
||||
</React.Fragment>
|
||||
) : (
|
||||
<div className="page__empty">
|
||||
{__("You don't have anything saved in history yet, go check out some content on LBRY!")}
|
||||
<div className="card__actions card__actions--center">
|
||||
<Button button="primary" navigate="/discover" label={__('Explore new content')} />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,27 +36,24 @@ class UserHistoryItem extends React.PureComponent<Props> {
|
|||
}
|
||||
|
||||
return (
|
||||
<tr
|
||||
<div
|
||||
role="button"
|
||||
onClick={onSelect}
|
||||
className={classnames({
|
||||
history__selected: selected,
|
||||
className={classnames('item-list__item', {
|
||||
'item-list__item--selected': selected,
|
||||
})}
|
||||
>
|
||||
<td>
|
||||
<input checked={selected} type="checkbox" onClick={onSelect} />
|
||||
</td>
|
||||
<td>{moment(lastViewed).from(moment())}</td>
|
||||
<td>{title}</td>
|
||||
<td>
|
||||
<Button
|
||||
tourniquet
|
||||
button="link"
|
||||
label={name ? `lbry://${name}` : `lbry://...`}
|
||||
navigate="/show"
|
||||
navigateParams={{ uri }}
|
||||
/>
|
||||
</td>
|
||||
</tr>
|
||||
<input checked={selected} type="checkbox" onClick={onSelect} />
|
||||
<span className="time time--ago">{moment(lastViewed).from(moment())}</span>
|
||||
<span className="item-list__item--cutoff">{title}</span>
|
||||
<Button
|
||||
tourniquet
|
||||
button="link"
|
||||
label={name ? `lbry://${name}` : `lbry://...`}
|
||||
navigate="/show"
|
||||
navigateParams={{ uri }}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
import * as React from 'react';
|
||||
import Button from 'component/button';
|
||||
import CardVerify from 'component/cardVerify';
|
||||
import Lbryio from 'lbryinc';
|
||||
import { Lbryio } from 'lbryinc';
|
||||
import * as icons from 'constants/icons';
|
||||
|
||||
type Props = {
|
||||
|
|
|
@ -6,14 +6,15 @@ import SocialShare from 'component/socialShare';
|
|||
type Props = {
|
||||
closeModal: () => void,
|
||||
uri: string,
|
||||
speechShareable: boolean,
|
||||
};
|
||||
|
||||
class ModalSocialShare extends React.PureComponent<Props> {
|
||||
render() {
|
||||
const { closeModal, uri } = this.props;
|
||||
const { closeModal, uri, speechShareable } = this.props;
|
||||
return (
|
||||
<Modal isOpen onAborted={closeModal} type="custom" title={__('Share')}>
|
||||
<SocialShare uri={uri} onDone={closeModal} />
|
||||
<SocialShare uri={uri} onDone={closeModal} speechShareable={speechShareable} />
|
||||
</Modal>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -145,12 +145,11 @@ class FilePage extends React.Component<Props> {
|
|||
if (channelName && channelClaimId) {
|
||||
subscriptionUri = buildURI({ channelName, claimId: channelClaimId }, false);
|
||||
}
|
||||
const speechSharable =
|
||||
const speechShareable =
|
||||
costInfo &&
|
||||
costInfo.cost === 0 &&
|
||||
contentType &&
|
||||
['video', 'image'].includes(contentType.split('/')[0]);
|
||||
|
||||
// We want to use the short form uri for editing
|
||||
// This is what the user is used to seeing, they don't care about the claim id
|
||||
// We will select the claim id before they publish
|
||||
|
@ -222,14 +221,17 @@ class FilePage extends React.Component<Props> {
|
|||
onClick={() => openModal({ id: MODALS.SEND_TIP }, { uri })}
|
||||
/>
|
||||
)}
|
||||
{speechSharable && (
|
||||
<Button
|
||||
button="alt"
|
||||
icon={icons.GLOBE}
|
||||
label={__('Share')}
|
||||
onClick={() => openModal({ id: MODALS.SOCIAL_SHARE }, { uri })}
|
||||
/>
|
||||
)}
|
||||
<Button
|
||||
button="alt"
|
||||
icon={icons.GLOBE}
|
||||
label={__('Share')}
|
||||
onClick={() =>
|
||||
openModal(
|
||||
{ id: MODALS.SOCIAL_SHARE },
|
||||
{ uri, speechShareable: speechShareable }
|
||||
)
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="card__actions">
|
||||
|
|
|
@ -199,7 +199,7 @@ class HelpPage extends React.PureComponent<Props, State> {
|
|||
)}
|
||||
|
||||
{this.state.uiVersion && ver ? (
|
||||
<table className="table table--stretch table--help">
|
||||
<table className="card__content table table--stretch table--help">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>{__('App')}</td>
|
||||
|
|
|
@ -6,7 +6,6 @@ import { doNavigate } from 'redux/actions/navigation';
|
|||
import {
|
||||
setSubscriptionLatest,
|
||||
setSubscriptionNotification,
|
||||
setSubscriptionNotifications,
|
||||
} from 'redux/actions/subscriptions';
|
||||
import { selectNotifications } from 'redux/selectors/subscriptions';
|
||||
import { selectBadgeNumber } from 'redux/selectors/app';
|
||||
|
@ -360,13 +359,13 @@ export function doPurchaseUri(uri, specificCostInfo, shouldRecordViewEvent) {
|
|||
}
|
||||
|
||||
export function doFetchClaimsByChannel(uri, page) {
|
||||
return (dispatch, getState) => {
|
||||
return dispatch => {
|
||||
dispatch({
|
||||
type: ACTIONS.FETCH_CHANNEL_CLAIMS_STARTED,
|
||||
data: { uri, page },
|
||||
});
|
||||
|
||||
Lbry.claim_list_by_channel({ uri, page: page || 1 }).then(result => {
|
||||
Lbry.claim_list_by_channel({ uri, page: page || 1, page_size: 48 }).then(result => {
|
||||
const claimResult = result[uri] || {};
|
||||
const { claims_in_channel: claimsInChannel, returned_page: returnedPage } = claimResult;
|
||||
|
||||
|
|
|
@ -8,6 +8,14 @@ export function doNavigate(path, params = {}, options = {}) {
|
|||
return;
|
||||
}
|
||||
|
||||
// ensure uri always has "lbry://" prefix
|
||||
const navigationParams = params;
|
||||
if (path === '/show') {
|
||||
if (navigationParams.uri && !navigationParams.uri.startsWith('lbry://')) {
|
||||
navigationParams.uri = `lbry://${navigationParams.uri}`;
|
||||
}
|
||||
}
|
||||
|
||||
let url = path;
|
||||
if (params && Object.values(params).length) {
|
||||
url += `?${toQueryString(params)}`;
|
||||
|
|
|
@ -18,25 +18,13 @@ import { selectosNotificationsEnabled } from 'redux/selectors/settings';
|
|||
import { doNavigate } from 'redux/actions/navigation';
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
import { CC_LICENSES, COPYRIGHT, OTHER } from 'constants/licenses';
|
||||
|
||||
type Action = UpdatePublishFormAction | { type: ACTIONS.CLEAR_PUBLISH };
|
||||
type PromiseAction = Promise<Action>;
|
||||
type Dispatch = (action: Action | PromiseAction | Array<Action>) => any;
|
||||
type GetState = () => {};
|
||||
|
||||
export const doClearPublish = () => (dispatch: Dispatch): PromiseAction => {
|
||||
dispatch({ type: ACTIONS.CLEAR_PUBLISH });
|
||||
return dispatch(doResetThumbnailStatus());
|
||||
};
|
||||
|
||||
export const doUpdatePublishForm = (publishFormValue: UpdatePublishFormData) => (
|
||||
dispatch: Dispatch
|
||||
): UpdatePublishFormAction =>
|
||||
dispatch({
|
||||
type: ACTIONS.UPDATE_PUBLISH_FORM,
|
||||
data: { ...publishFormValue },
|
||||
});
|
||||
|
||||
export const doResetThumbnailStatus = () => (dispatch: Dispatch): PromiseAction => {
|
||||
dispatch({
|
||||
type: ACTIONS.UPDATE_PUBLISH_FORM,
|
||||
|
@ -73,6 +61,19 @@ export const doResetThumbnailStatus = () => (dispatch: Dispatch): PromiseAction
|
|||
);
|
||||
};
|
||||
|
||||
export const doClearPublish = () => (dispatch: Dispatch): PromiseAction => {
|
||||
dispatch({ type: ACTIONS.CLEAR_PUBLISH });
|
||||
return dispatch(doResetThumbnailStatus());
|
||||
};
|
||||
|
||||
export const doUpdatePublishForm = (publishFormValue: UpdatePublishFormData) => (
|
||||
dispatch: Dispatch
|
||||
): UpdatePublishFormAction =>
|
||||
dispatch({
|
||||
type: ACTIONS.UPDATE_PUBLISH_FORM,
|
||||
data: { ...publishFormValue },
|
||||
});
|
||||
|
||||
export const doUploadThumbnail = (filePath: string, nsfw: boolean) => (dispatch: Dispatch) => {
|
||||
const thumbnail = fs.readFileSync(filePath);
|
||||
const fileExt = path.extname(filePath);
|
||||
|
@ -164,15 +165,27 @@ export const doPrepareEdit = (claim: any, uri: string) => (dispatch: Dispatch) =
|
|||
description,
|
||||
fee,
|
||||
language,
|
||||
licenseType: license,
|
||||
licenseUrl,
|
||||
nsfw,
|
||||
thumbnail,
|
||||
title,
|
||||
uri,
|
||||
uploadThumbnailStatus: thumbnail ? THUMBNAIL_STATUSES.MANUAL : undefined,
|
||||
licenseUrl,
|
||||
};
|
||||
|
||||
// Make sure custom liscence's are mapped properly
|
||||
if (!CC_LICENSES.some(({ value }) => value === license)) {
|
||||
if (!licenseUrl) {
|
||||
publishData.licenseType = COPYRIGHT;
|
||||
} else {
|
||||
publishData.licenseType = OTHER;
|
||||
}
|
||||
|
||||
publishData.otherLicenseDescription = license;
|
||||
} else {
|
||||
publishData.licenseType = license;
|
||||
}
|
||||
|
||||
dispatch({ type: ACTIONS.DO_PREPARE_EDIT, data: publishData });
|
||||
};
|
||||
|
||||
|
|
|
@ -28,7 +28,6 @@ type PublishState = {
|
|||
bidError: ?string,
|
||||
otherLicenseDescription: string,
|
||||
licenseUrl: string,
|
||||
copyrightNotice: string,
|
||||
pendingPublishes: Array<any>,
|
||||
};
|
||||
|
||||
|
@ -54,7 +53,6 @@ export type UpdatePublishFormData = {
|
|||
bidError?: string,
|
||||
otherLicenseDescription?: string,
|
||||
licenseUrl?: string,
|
||||
copyrightNotice?: string,
|
||||
};
|
||||
|
||||
export type UpdatePublishFormAction = {
|
||||
|
@ -114,9 +112,8 @@ const defaultState: PublishState = {
|
|||
bid: 0.1,
|
||||
bidError: undefined,
|
||||
licenseType: 'None',
|
||||
otherLicenseDescription: '',
|
||||
otherLicenseDescription: 'All rights reserved',
|
||||
licenseUrl: '',
|
||||
copyrightNotice: 'All rights reserved',
|
||||
publishing: false,
|
||||
publishSuccess: false,
|
||||
publishError: undefined,
|
||||
|
|
|
@ -39,7 +39,7 @@ html {
|
|||
}
|
||||
|
||||
body {
|
||||
font-family: 'metropolis-semibold';
|
||||
font-family: 'metropolis-medium';
|
||||
font-weight: 400;
|
||||
font-size: 16px;
|
||||
line-height: 1.5;
|
||||
|
@ -74,7 +74,6 @@ input {
|
|||
line-height: 1;
|
||||
cursor: text;
|
||||
background-color: transparent;
|
||||
font-family: 'metropolis-medium';
|
||||
|
||||
&[type='radio'],
|
||||
&[type='checkbox'],
|
||||
|
@ -92,6 +91,7 @@ input {
|
|||
color: var(--input-copyable-color);
|
||||
padding: 10px 16px;
|
||||
border: 1px dashed var(--input-copyable-border);
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
&:not(.input-copyable):not(.wunderbar__input):not(:placeholder-shown):not(:disabled) {
|
||||
|
@ -109,7 +109,6 @@ input {
|
|||
}
|
||||
|
||||
textarea {
|
||||
font-family: 'metropolis-medium';
|
||||
border: 1px solid var(--color-divider);
|
||||
font-size: 0.8em;
|
||||
width: 100%;
|
||||
|
@ -152,8 +151,6 @@ dd {
|
|||
}
|
||||
|
||||
p {
|
||||
font-family: 'metropolis-medium';
|
||||
|
||||
&:not(:first-of-type) {
|
||||
margin-top: $spacing-vertical * 1/3;
|
||||
}
|
||||
|
@ -227,7 +224,6 @@ p {
|
|||
.page__empty {
|
||||
margin-top: 200px;
|
||||
text-align: center;
|
||||
font-family: 'metropolis-medium';
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
|
@ -300,7 +296,6 @@ p {
|
|||
color: inherit;
|
||||
font-weight: inherit;
|
||||
font-size: inherit;
|
||||
font-family: 'metropolis-medium';
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
|
@ -333,10 +328,6 @@ p {
|
|||
-webkit-box-orient: vertical;
|
||||
}
|
||||
|
||||
.busy-indicator {
|
||||
font-family: 'metropolis-medium';
|
||||
}
|
||||
|
||||
.busy-indicator__loader {
|
||||
background: url('../../../static/img/busy.gif') no-repeat center center;
|
||||
display: inline-block;
|
||||
|
@ -355,7 +346,6 @@ p {
|
|||
|
||||
.help {
|
||||
font-size: 12px;
|
||||
font-family: 'metropolis-medium';
|
||||
color: var(--color-help);
|
||||
}
|
||||
|
||||
|
@ -364,7 +354,6 @@ p {
|
|||
}
|
||||
|
||||
.meta {
|
||||
font-family: 'metropolis-medium';
|
||||
font-size: 0.8em;
|
||||
color: var(--color-meta-light);
|
||||
}
|
||||
|
|
|
@ -52,6 +52,8 @@ $large-breakpoint: 1921px;
|
|||
--color-search-placeholder: var(--color-placeholder);
|
||||
--color-credit-free: var(--color-dark-blue);
|
||||
--color-credit-price: var(--card-text-color);
|
||||
--color-text-black: #444;
|
||||
--color-text-white: #efefef;
|
||||
|
||||
/* Shadows */
|
||||
--box-shadow-layer: transparent; // 0 2px 4px rgba(0,0,0,0.25);
|
||||
|
@ -60,8 +62,8 @@ $large-breakpoint: 1921px;
|
|||
--box-shadow-header: 0px 6px 20px 1px rgba(0, 0, 0, 0.05);
|
||||
|
||||
/* Text */
|
||||
--text-color: var(--color-black);
|
||||
--text-color-inverse: var(--color-white);
|
||||
--text-color: var(--color-text-black);
|
||||
--text-color-inverse: var(--color-text-white);
|
||||
--text-help-color: var(--color-help);
|
||||
--text-max-width: 660px;
|
||||
--text-link-padding: 4px;
|
||||
|
|
|
@ -29,3 +29,5 @@
|
|||
@import 'component/_toggle.scss';
|
||||
@import 'component/_search.scss';
|
||||
@import 'component/_dat-gui.scss';
|
||||
@import 'component/_item-list.scss';
|
||||
@import 'component/_time.scss';
|
||||
|
|
|
@ -19,7 +19,6 @@ button:disabled {
|
|||
fill: currentColor; // for proper icon color
|
||||
font-size: 12px;
|
||||
transition: all var(--animation-duration) var(--animation-style);
|
||||
font-family: 'metropolis-medium';
|
||||
|
||||
&:not(:disabled) {
|
||||
box-shadow: var(--box-shadow-button);
|
||||
|
@ -172,7 +171,6 @@ button:disabled {
|
|||
}
|
||||
|
||||
.btn.btn--header-balance {
|
||||
font-family: 'metropolis-medium';
|
||||
font-size: 14px;
|
||||
color: var(--header-primary-color);
|
||||
|
||||
|
|
|
@ -107,6 +107,7 @@
|
|||
.card__title {
|
||||
font-size: 18px;
|
||||
color: var(--text-color);
|
||||
font-family: 'metropolis-semibold';
|
||||
}
|
||||
|
||||
.card__title--small {
|
||||
|
@ -151,7 +152,6 @@
|
|||
.card__subtitle {
|
||||
margin: 0;
|
||||
font-size: 14px;
|
||||
font-family: 'metropolis-medium';
|
||||
color: var(--card-text-color);
|
||||
}
|
||||
|
||||
|
@ -336,6 +336,7 @@
|
|||
}
|
||||
|
||||
.card-row__title {
|
||||
font-family: 'metropolis-semibold';
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-size: 18px;
|
||||
|
|
26
src/renderer/scss/component/_item-list.scss
Normal file
26
src/renderer/scss/component/_item-list.scss
Normal file
|
@ -0,0 +1,26 @@
|
|||
.item-list {
|
||||
background-color: var(--card-bg);
|
||||
margin-top: $spacing-vertical;
|
||||
}
|
||||
|
||||
.item-list__item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: $spacing-vertical * 1/3;
|
||||
|
||||
input,
|
||||
.item-list__item--cutoff {
|
||||
margin-right: $spacing-vertical;
|
||||
}
|
||||
}
|
||||
|
||||
.item-list__item--selected {
|
||||
background-color: var(--table-item-odd);
|
||||
}
|
||||
|
||||
.item-list__item--cutoff {
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
overflow-x: hidden;
|
||||
max-width: 350px;
|
||||
}
|
|
@ -24,7 +24,6 @@
|
|||
padding: 10px;
|
||||
padding-left: 30px;
|
||||
font-size: 13px;
|
||||
font-family: 'metropolis-medium';
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
@ -54,7 +53,6 @@
|
|||
flex-direction: row;
|
||||
justify-items: flex-start;
|
||||
align-items: center;
|
||||
font-family: 'metropolis-medium';
|
||||
|
||||
&:not(:first-of-type) {
|
||||
border-top: 1px solid var(--search-item-border-color);
|
||||
|
@ -75,7 +73,6 @@
|
|||
.wunderbar__suggestion-label--action {
|
||||
margin-left: $spacing-vertical * 1/3;
|
||||
white-space: nowrap;
|
||||
font-family: 'metropolis-medium';
|
||||
font-size: 12px;
|
||||
line-height: 0.1; // to vertically align because the font size is smaller
|
||||
}
|
||||
|
|
|
@ -3,7 +3,6 @@ table.table,
|
|||
word-wrap: break-word;
|
||||
max-width: 100%;
|
||||
text-align: left;
|
||||
margin-top: $spacing-vertical * 2/3;
|
||||
|
||||
tr td:first-of-type,
|
||||
tr th:first-of-type {
|
||||
|
@ -107,48 +106,3 @@ table.table--transactions {
|
|||
width: 15%;
|
||||
}
|
||||
}
|
||||
|
||||
table.table--history {
|
||||
margin-top: $spacing-vertical * 1/3;
|
||||
|
||||
tbody {
|
||||
tr {
|
||||
&:nth-child(even),
|
||||
&:nth-child(odd) {
|
||||
background-color: var(--table-item-even);
|
||||
|
||||
&.history__selected {
|
||||
color: red;
|
||||
background-color: var(--table-item-odd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
td {
|
||||
cursor: default;
|
||||
padding: $spacing-vertical * 1/3 0;
|
||||
}
|
||||
|
||||
td:nth-of-type(1) {
|
||||
width: 7.5%;
|
||||
}
|
||||
td:nth-of-type(2) {
|
||||
width: 17.5%;
|
||||
}
|
||||
td:nth-of-type(3) {
|
||||
width: 40%;
|
||||
max-width: 30vw;
|
||||
padding-right: $spacing-vertical * 2/3;
|
||||
}
|
||||
td:nth-of-type(4) {
|
||||
width: 30%;
|
||||
}
|
||||
|
||||
td:nth-of-type(3),
|
||||
td:nth-of-type(4) {
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
9
src/renderer/scss/component/_time.scss
Normal file
9
src/renderer/scss/component/_time.scss
Normal file
|
@ -0,0 +1,9 @@
|
|||
// All CSS for date & time ui
|
||||
|
||||
.time {
|
||||
color: var(--color-help);
|
||||
}
|
||||
|
||||
.time--ago {
|
||||
min-width: 160px;
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
:root {
|
||||
|
||||
|
||||
/* Colors */
|
||||
--color-divider: #53637C;;
|
||||
--color-canvas: transparent;
|
||||
|
@ -12,7 +12,7 @@
|
|||
--color-credit-free: var(--color-secondary);
|
||||
|
||||
/* Text */
|
||||
--text-color: var(--color-white);
|
||||
--text-color: var(--color-text-white);
|
||||
--text-help-color: var(--color-help);
|
||||
|
||||
/* Form */
|
||||
|
|
Loading…
Add table
Reference in a new issue