Redesign fixes (#2164)
* fix: share modal not opening * fix: add more spacing above snackbar link * fix: properly close thumbnail error modal * fix: better align media property icons * fix: tx filter alignment and prevent hiding filter if no current tx's * fix: publish markdown on dark mode * fix: add max-width on container for large screens * fix: channel pagination aligmnent and spacing * fix: modal spacing and flow errors * fix: home page scrolling (now with mouse scrolling) * fix: hover color in dark mode for outline buttons * fix: improve file page spacing/layout * cleanup * fix: wrap file actions on smaller screens * fix: comment button spacing
This commit is contained in:
parent
42e3d74805
commit
ad90c1f96e
31 changed files with 384 additions and 347 deletions
|
@ -115,7 +115,7 @@
|
|||
"eslint-plugin-jsx-a11y": "^6.0.3",
|
||||
"eslint-plugin-prettier": "^2.6.0",
|
||||
"eslint-plugin-react": "^7.7.0",
|
||||
"flow-bin": "^0.69.0",
|
||||
"flow-bin": "^0.89.0",
|
||||
"flow-typed": "^2.3.0",
|
||||
"husky": "^0.14.3",
|
||||
"i18n-extract": "^0.5.1",
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
// @flow
|
||||
import type { Claim } from 'types/claim';
|
||||
import * as ICONS from 'constants/icons';
|
||||
import React, { PureComponent } from 'react';
|
||||
import React, { PureComponent, createRef } from 'react';
|
||||
import { normalizeURI } from 'lbry-redux';
|
||||
import ToolTip from 'component/common/tooltip';
|
||||
import FileCard from 'component/fileCard';
|
||||
import Button from 'component/button';
|
||||
import SubscribeButton from 'component/subscribeButton';
|
||||
import throttle from 'util/throttle';
|
||||
|
||||
type Props = {
|
||||
category: string,
|
||||
|
@ -33,12 +34,14 @@ class CategoryList extends PureComponent<Props, State> {
|
|||
|
||||
this.state = {
|
||||
canScrollPrevious: false,
|
||||
canScrollNext: false,
|
||||
canScrollNext: true,
|
||||
};
|
||||
|
||||
(this: any).handleScrollNext = this.handleScrollNext.bind(this);
|
||||
(this: any).handleScrollPrevious = this.handleScrollPrevious.bind(this);
|
||||
this.rowItems = undefined;
|
||||
(this: any).handleArrowButtonsOnScroll = this.handleArrowButtonsOnScroll.bind(this);
|
||||
|
||||
this.scrollWrapper = createRef();
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
|
@ -47,54 +50,50 @@ class CategoryList extends PureComponent<Props, State> {
|
|||
fetchChannel(categoryLink);
|
||||
}
|
||||
|
||||
const cardRow = this.rowItems;
|
||||
if (cardRow) {
|
||||
const cards = cardRow.getElementsByTagName('section');
|
||||
const lastCard = cards[cards.length - 1];
|
||||
const isCompletelyVisible = this.isCardVisible(lastCard);
|
||||
|
||||
if (!isCompletelyVisible) {
|
||||
// not sure how we can avoid doing this
|
||||
/* eslint-disable react/no-did-mount-set-state */
|
||||
this.setState({
|
||||
canScrollNext: true,
|
||||
});
|
||||
/* eslint-enable react/no-did-mount-set-state */
|
||||
}
|
||||
const scrollWrapper = this.scrollWrapper.current;
|
||||
if (scrollWrapper) {
|
||||
scrollWrapper.addEventListener('scroll', throttle(this.handleArrowButtonsOnScroll, 500));
|
||||
}
|
||||
}
|
||||
|
||||
rowItems: ?HTMLDivElement;
|
||||
scrollWrapper: { current: null | HTMLUListElement };
|
||||
|
||||
handleArrowButtonsOnScroll() {
|
||||
// Determine if the arrow buttons should be disabled
|
||||
const scrollWrapper = this.scrollWrapper.current;
|
||||
if (scrollWrapper) {
|
||||
// firstElementChild and lastElementChild will always exist
|
||||
// $FlowFixMe
|
||||
const hasHiddenCardToLeft = !this.isCardVisible(scrollWrapper.firstElementChild);
|
||||
// $FlowFixMe
|
||||
const hasHiddenCardToRight = !this.isCardVisible(scrollWrapper.lastElementChild);
|
||||
|
||||
handleScroll(cardRow: HTMLDivElement, scrollTarget: number) {
|
||||
const cards = cardRow.getElementsByTagName('section');
|
||||
const animationCallback = () => {
|
||||
const firstCard = cards[0];
|
||||
const lastCard = cards[cards.length - 1];
|
||||
const firstCardVisible = this.isCardVisible(firstCard);
|
||||
const lastCardVisible = this.isCardVisible(lastCard);
|
||||
this.setState({
|
||||
canScrollNext: !lastCardVisible,
|
||||
canScrollPrevious: !firstCardVisible,
|
||||
canScrollPrevious: hasHiddenCardToLeft,
|
||||
canScrollNext: hasHiddenCardToRight,
|
||||
});
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
const currentScrollLeft = cardRow.scrollLeft;
|
||||
const direction = currentScrollLeft > scrollTarget ? 'left' : 'right';
|
||||
this.scrollCardsAnimated(cardRow, scrollTarget, direction, animationCallback);
|
||||
handleScroll(scrollTarget: number) {
|
||||
const scrollWrapper = this.scrollWrapper.current;
|
||||
if (scrollWrapper) {
|
||||
const currentScrollLeft = scrollWrapper.scrollLeft;
|
||||
const direction = currentScrollLeft > scrollTarget ? 'left' : 'right';
|
||||
this.scrollCardsAnimated(scrollWrapper, scrollTarget, direction);
|
||||
}
|
||||
}
|
||||
|
||||
scrollCardsAnimated = (
|
||||
cardRow: HTMLDivElement,
|
||||
scrollWrapper: HTMLUListElement,
|
||||
scrollTarget: number,
|
||||
direction: string,
|
||||
callback: () => any
|
||||
direction: string
|
||||
) => {
|
||||
let start;
|
||||
const step = timestamp => {
|
||||
if (!start) start = timestamp;
|
||||
|
||||
const currentLeftVal = cardRow.scrollLeft;
|
||||
const currentLeftVal = scrollWrapper.scrollLeft;
|
||||
|
||||
let newTarget;
|
||||
let shouldContinue;
|
||||
|
@ -110,12 +109,10 @@ class CategoryList extends PureComponent<Props, State> {
|
|||
shouldContinue = newTarget > scrollTarget;
|
||||
}
|
||||
|
||||
cardRow.scrollLeft = newTarget; // eslint-disable-line no-param-reassign
|
||||
scrollWrapper.scrollLeft = newTarget; // eslint-disable-line no-param-reassign
|
||||
|
||||
if (shouldContinue) {
|
||||
window.requestAnimationFrame(step);
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -123,85 +120,93 @@ class CategoryList extends PureComponent<Props, State> {
|
|||
};
|
||||
|
||||
// check if a card is fully visible horizontally
|
||||
isCardVisible = (section: HTMLElement) => {
|
||||
if (!section) {
|
||||
isCardVisible = (card: HTMLLIElement): boolean => {
|
||||
if (!card) {
|
||||
return false;
|
||||
}
|
||||
const rect = section.getBoundingClientRect();
|
||||
const isVisible = rect.left >= 0 && rect.right <= window.innerWidth;
|
||||
return isVisible;
|
||||
const scrollWrapper = this.scrollWrapper.current;
|
||||
if (scrollWrapper) {
|
||||
const rect = card.getBoundingClientRect();
|
||||
const isVisible =
|
||||
scrollWrapper.scrollLeft < card.offsetLeft &&
|
||||
rect.left >= 0 &&
|
||||
rect.right <= window.innerWidth;
|
||||
return isVisible;
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
handleScrollNext() {
|
||||
const cardRow = this.rowItems;
|
||||
if (cardRow) {
|
||||
const cards = cardRow.getElementsByTagName('section');
|
||||
const scrollWrapper = this.scrollWrapper.current;
|
||||
if (!scrollWrapper) {
|
||||
return;
|
||||
}
|
||||
|
||||
// loop over items until we find one that is on the screen
|
||||
// continue searching until a card isn't fully visible, this is the new target
|
||||
let firstFullVisibleCard;
|
||||
let firstSemiVisibleCard;
|
||||
const cards = scrollWrapper.getElementsByTagName('li');
|
||||
|
||||
for (let i = 0; i < cards.length; i += 1) {
|
||||
const currentCardVisible = this.isCardVisible(cards[i]);
|
||||
// Loop over items until we find one that is visible
|
||||
// The card before that (starting from the end) is the new "first" card on the screen
|
||||
|
||||
if (firstFullVisibleCard && !currentCardVisible) {
|
||||
firstSemiVisibleCard = cards[i];
|
||||
break;
|
||||
} else if (currentCardVisible) {
|
||||
[firstFullVisibleCard] = cards;
|
||||
}
|
||||
let previousCard: ?HTMLLIElement;
|
||||
for (let i = cards.length - 1; i > 0; i -= 1) {
|
||||
const currentCard: HTMLLIElement = cards[i];
|
||||
const currentCardVisible = this.isCardVisible(currentCard);
|
||||
|
||||
if (currentCardVisible && previousCard) {
|
||||
const scrollTarget = previousCard.offsetLeft;
|
||||
this.handleScroll(scrollTarget);
|
||||
break;
|
||||
}
|
||||
|
||||
if (firstFullVisibleCard && firstSemiVisibleCard) {
|
||||
const scrollTarget = firstSemiVisibleCard.offsetLeft - firstFullVisibleCard.offsetLeft;
|
||||
this.handleScroll(cardRow, scrollTarget);
|
||||
}
|
||||
previousCard = currentCard;
|
||||
}
|
||||
}
|
||||
|
||||
handleScrollPrevious() {
|
||||
const cardRow = this.rowItems;
|
||||
if (cardRow) {
|
||||
const cards = cardRow.getElementsByTagName('section');
|
||||
const scrollWrapper = this.scrollWrapper.current;
|
||||
if (!scrollWrapper) {
|
||||
return;
|
||||
}
|
||||
|
||||
let hasFoundCard;
|
||||
let numberOfCardsThatCanFit = 0;
|
||||
const cards = scrollWrapper.getElementsByTagName('li');
|
||||
|
||||
// loop starting at the end until we find a visible card
|
||||
// then count to find how many cards can fit on the screen
|
||||
for (let i = cards.length - 1; i >= 0; i -= 1) {
|
||||
const currentCard = cards[i];
|
||||
const isCurrentCardVisible = this.isCardVisible(currentCard);
|
||||
let hasFoundCard;
|
||||
let numberOfCardsThatCanFit = 0;
|
||||
|
||||
if (isCurrentCardVisible) {
|
||||
if (!hasFoundCard) {
|
||||
hasFoundCard = true;
|
||||
}
|
||||
// loop starting at the end until we find a visible card
|
||||
// then count to find how many cards can fit on the screen
|
||||
for (let i = cards.length - 1; i >= 0; i -= 1) {
|
||||
const currentCard = cards[i];
|
||||
const isCurrentCardVisible = this.isCardVisible(currentCard);
|
||||
|
||||
numberOfCardsThatCanFit += 1;
|
||||
} else if (hasFoundCard) {
|
||||
// this card is off the screen to the left
|
||||
// we know how many cards can fit on a screen
|
||||
// find the new target and scroll
|
||||
const firstCardOffsetLeft = cards[0].offsetLeft;
|
||||
const cardIndexToScrollTo = i + 1 - numberOfCardsThatCanFit;
|
||||
const newFirstCard = cards[cardIndexToScrollTo];
|
||||
|
||||
let scrollTarget;
|
||||
if (newFirstCard) {
|
||||
scrollTarget = newFirstCard.offsetLeft;
|
||||
} else {
|
||||
// more cards can fit on the screen than are currently hidden
|
||||
// just scroll to the first card
|
||||
scrollTarget = cards[0].offsetLeft;
|
||||
}
|
||||
|
||||
scrollTarget -= firstCardOffsetLeft; // to play nice with the margins
|
||||
|
||||
this.handleScroll(cardRow, scrollTarget);
|
||||
break;
|
||||
if (isCurrentCardVisible) {
|
||||
if (!hasFoundCard) {
|
||||
hasFoundCard = true;
|
||||
}
|
||||
|
||||
numberOfCardsThatCanFit += 1;
|
||||
} else if (hasFoundCard) {
|
||||
// this card is off the screen to the left
|
||||
// we know how many cards can fit on a screen
|
||||
// find the new target and scroll
|
||||
const firstCardOffsetLeft = cards[0].offsetLeft;
|
||||
const cardIndexToScrollTo = i + 1 - numberOfCardsThatCanFit;
|
||||
const newFirstCard = cards[cardIndexToScrollTo];
|
||||
|
||||
let scrollTarget;
|
||||
if (newFirstCard) {
|
||||
scrollTarget = newFirstCard.offsetLeft;
|
||||
} else {
|
||||
// more cards can fit on the screen than are currently hidden
|
||||
// just scroll to the first card
|
||||
scrollTarget = cards[0].offsetLeft;
|
||||
}
|
||||
|
||||
scrollTarget -= firstCardOffsetLeft; // to play nice with the margins
|
||||
|
||||
this.handleScroll(scrollTarget);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -266,12 +271,7 @@ class CategoryList extends PureComponent<Props, State> {
|
|||
<Button button="link" navigate="/settings" label={__('here')} />.
|
||||
</p>
|
||||
) : (
|
||||
<ul
|
||||
className="media-scrollhouse"
|
||||
ref={ref => {
|
||||
this.rowItems = ref;
|
||||
}}
|
||||
>
|
||||
<ul className="media-scrollhouse" ref={this.scrollWrapper}>
|
||||
{names &&
|
||||
names.length &&
|
||||
names.map(name => (
|
||||
|
|
|
@ -64,11 +64,7 @@ class CreditAmount extends React.PureComponent<Props> {
|
|||
}
|
||||
|
||||
if (showLBC) {
|
||||
amountText = (
|
||||
<span>
|
||||
{amountText} {__('LBC')}
|
||||
</span>
|
||||
);
|
||||
amountText = `${amountText} ${__('LBC')}`;
|
||||
}
|
||||
|
||||
if (fee) {
|
||||
|
|
|
@ -81,6 +81,7 @@ class FileCard extends React.PureComponent<Props> {
|
|||
<div className="media__title media__title--placeholder" />
|
||||
<div className="media__channel media__channel--placeholder" />
|
||||
<div className="media__date media__date--placeholder" />
|
||||
<div className="media__properties media__properties--placeholder" />
|
||||
</li>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -108,7 +108,7 @@ class FileDetails extends PureComponent<Props> {
|
|||
|
||||
<div className="media__info-title">Comments</div>
|
||||
|
||||
<div className="card__actions">
|
||||
<div className="card__actions--center">
|
||||
<Button
|
||||
data-id="add-comment"
|
||||
disabled={hasClickedComment}
|
||||
|
@ -119,7 +119,7 @@ class FileDetails extends PureComponent<Props> {
|
|||
</div>
|
||||
<br />
|
||||
{hasClickedComment && (
|
||||
<p className="main--for-content">
|
||||
<p className="media__info-text media__info-text--center">
|
||||
{user
|
||||
? __('Your support has been added. You will be notified when comments are available.')
|
||||
: __('Your support has been added. Comments are coming soon.')}
|
||||
|
|
|
@ -292,9 +292,9 @@ class PublishForm extends React.PureComponent<Props> {
|
|||
{uploadThumbnailStatus === THUMBNAIL_STATUSES.IN_PROGRESS && (
|
||||
<div>{__('Please wait for thumbnail to finish uploading')}</div>
|
||||
)}
|
||||
{!!editingURI && !isStillEditing && !filePath && (
|
||||
<div>{__('You need to reselect a file after changing the LBRY URL')}</div>
|
||||
)}
|
||||
{!!editingURI &&
|
||||
!isStillEditing &&
|
||||
!filePath && <div>{__('You need to reselect a file after changing the LBRY URL')}</div>}
|
||||
</div>
|
||||
)
|
||||
);
|
||||
|
@ -351,7 +351,9 @@ class PublishForm extends React.PureComponent<Props> {
|
|||
<header className="card__header">
|
||||
<h2 className="card__title">{__('Content')}</h2>
|
||||
<p className="card__subtitle">
|
||||
{isStillEditing ? __('Editing a claim') : __('What are you publishing?')}{' '}
|
||||
{isStillEditing
|
||||
? __('You are currently editing a claim.')
|
||||
: __('What are you publishing?')}{' '}
|
||||
{__('Read our')}{' '}
|
||||
<Button button="link" label={__('FAQ')} href="https://lbry.io/faq/how-to-publish" />{' '}
|
||||
{__('to learn more.')}
|
||||
|
@ -370,13 +372,14 @@ class PublishForm extends React.PureComponent<Props> {
|
|||
)}
|
||||
<div className="card__content">
|
||||
<FileSelector currentPath={filePath} onFileChosen={this.handleFileChange} />
|
||||
{!!isStillEditing && name && (
|
||||
<p className="help">
|
||||
{__("If you don't choose a file, the file from your existing claim")}
|
||||
{` "${name}" `}
|
||||
{__('will be used.')}
|
||||
</p>
|
||||
)}
|
||||
{!!isStillEditing &&
|
||||
name && (
|
||||
<p className="help">
|
||||
{__("If you don't choose a file, the file from your existing claim")}
|
||||
{` "${name}" `}
|
||||
{__('will be used.')}
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
</section>
|
||||
<div className={classnames({ 'card--disabled': formDisabled })}>
|
||||
|
|
|
@ -12,7 +12,7 @@ type Props = {
|
|||
formDisabled: boolean,
|
||||
uploadThumbnailStatus: string,
|
||||
thumbnailPath: ?string,
|
||||
openModal: ({ id: string }, {}) => void,
|
||||
openModal: (id: string, {}) => void,
|
||||
updatePublishForm: ({}) => void,
|
||||
resetThumbnailStatus: () => void,
|
||||
};
|
||||
|
|
|
@ -9,6 +9,7 @@ type Props = {
|
|||
linkTarget: ?string,
|
||||
linkText: ?string,
|
||||
message: string,
|
||||
isError: boolean,
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -20,6 +21,9 @@ class SnackBar extends React.PureComponent<Props> {
|
|||
this.hideTimeout = null;
|
||||
}
|
||||
|
||||
hideTimeout: ?TimeoutID;
|
||||
displayTime: number;
|
||||
|
||||
render() {
|
||||
const { snack, removeSnack } = this.props;
|
||||
|
||||
|
@ -47,9 +51,10 @@ class SnackBar extends React.PureComponent<Props> {
|
|||
<div>ⓘ</div>
|
||||
<div>{message}</div>
|
||||
</div>
|
||||
{linkText && linkTarget && (
|
||||
<Button navigate={linkTarget} className="snack-bar__action" label={linkText} />
|
||||
)}
|
||||
{linkText &&
|
||||
linkTarget && (
|
||||
<Button navigate={linkTarget} className="snack-bar__action" label={linkText} />
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@ type Props = {
|
|||
subscriptions: Array<string>,
|
||||
doChannelSubscribe: ({ channelName: string, uri: string }) => void,
|
||||
doChannelUnsubscribe: SubscribtionArgs => void,
|
||||
doOpenModal: ({ id: string }) => void,
|
||||
doOpenModal: (id: string) => void,
|
||||
firstRunCompleted: boolean,
|
||||
showSnackBarOnSubscribe: boolean,
|
||||
doToast: ({ message: string }) => void,
|
||||
|
@ -46,7 +46,7 @@ export default (props: Props) => {
|
|||
<Button
|
||||
iconColor="red"
|
||||
icon={isSubscribed ? undefined : ICONS.HEART}
|
||||
button={buttonStyle ? buttonStyle : 'alt'}
|
||||
button={buttonStyle || 'alt'}
|
||||
label={subscriptionLabel}
|
||||
onClick={e => {
|
||||
e.stopPropagation();
|
||||
|
|
|
@ -24,7 +24,7 @@ type Props = {
|
|||
slim?: boolean,
|
||||
transactions: Array<Transaction>,
|
||||
rewards: {},
|
||||
openModal: ({ id: string }, { nout: number, txid: string }) => void,
|
||||
openModal: (id: string, { nout: number, txid: string }) => void,
|
||||
myClaims: any,
|
||||
filterSetting: string,
|
||||
setTransactionFilter: string => void,
|
||||
|
@ -79,43 +79,44 @@ class TransactionList extends React.PureComponent<Props> {
|
|||
return (
|
||||
<React.Fragment>
|
||||
<header className="card__header">
|
||||
{!transactionList.length && (
|
||||
<p className="card__content">{emptyMessage || __('No transactions to list.')}</p>
|
||||
)}
|
||||
{!slim && !!transactionList.length && (
|
||||
<div className="card__actions card__actions--between card__actions--top-space">
|
||||
<FileExporter
|
||||
data={transactionList}
|
||||
label={__('Export')}
|
||||
title={__('Export Transactions')}
|
||||
filters={['nout']}
|
||||
defaultPath={__('lbry-transactions-history')}
|
||||
/>
|
||||
{!slim &&
|
||||
!!transactions.length && (
|
||||
<div className="card__actions card__actions--between card__actions--top-space">
|
||||
<FileExporter
|
||||
data={transactionList}
|
||||
label={__('Export')}
|
||||
title={__('Export Transactions')}
|
||||
filters={['nout']}
|
||||
defaultPath={__('lbry-transactions-history')}
|
||||
/>
|
||||
|
||||
<FormField
|
||||
type="select"
|
||||
value={filterSetting || TRANSACTIONS.ALL}
|
||||
onChange={this.handleFilterChanged}
|
||||
affixClass="form-field--align-center"
|
||||
prefix={__('Show')}
|
||||
postfix={
|
||||
<Button
|
||||
button="link"
|
||||
icon={icons.HELP}
|
||||
href="https://lbry.io/faq/transaction-types"
|
||||
title={__('Help')}
|
||||
/>
|
||||
}
|
||||
>
|
||||
{transactionTypes.map(tt => (
|
||||
<option key={tt} value={tt}>
|
||||
{__(`${this.capitalize(tt)}`)}
|
||||
</option>
|
||||
))}
|
||||
</FormField>
|
||||
</div>
|
||||
)}
|
||||
<FormField
|
||||
type="select"
|
||||
value={filterSetting || TRANSACTIONS.ALL}
|
||||
onChange={this.handleFilterChanged}
|
||||
affixClass="form-field--align-center"
|
||||
prefix={__('Show')}
|
||||
postfix={
|
||||
<Button
|
||||
button="link"
|
||||
icon={icons.HELP}
|
||||
href="https://lbry.io/faq/transaction-types"
|
||||
title={__('Help')}
|
||||
/>
|
||||
}
|
||||
>
|
||||
{transactionTypes.map(tt => (
|
||||
<option key={tt} value={tt}>
|
||||
{__(`${this.capitalize(tt)}`)}
|
||||
</option>
|
||||
))}
|
||||
</FormField>
|
||||
</div>
|
||||
)}
|
||||
</header>
|
||||
{!transactionList.length && (
|
||||
<p className="card__content">{emptyMessage || __('No transactions to list.')}</p>
|
||||
)}
|
||||
|
||||
{!!transactionList.length && (
|
||||
<div className="card__content">
|
||||
|
|
|
@ -12,7 +12,7 @@ type DraftTransaction = {
|
|||
};
|
||||
|
||||
type Props = {
|
||||
openModal: ({ id: string }, { address: string, amount: number }) => void,
|
||||
openModal: (id: string, { address: string, amount: number }) => void,
|
||||
balance: number,
|
||||
};
|
||||
|
||||
|
|
|
@ -69,27 +69,24 @@ export class Modal extends React.PureComponent<ModalProps> {
|
|||
>
|
||||
<h1 className="card__title">{title}</h1>
|
||||
<div className="card__content">{children}</div>
|
||||
|
||||
<div className="card__content">
|
||||
{type === 'custom' ? null : ( // custom modals define their own buttons
|
||||
<div className="card__actions">
|
||||
{type === 'custom' ? null : ( // custom modals define their own buttons
|
||||
<div className="card__actions">
|
||||
<Button
|
||||
button="primary"
|
||||
label={confirmButtonLabel}
|
||||
disabled={confirmButtonDisabled}
|
||||
onClick={onConfirmed}
|
||||
/>
|
||||
{type === 'confirm' ? (
|
||||
<Button
|
||||
button="primary"
|
||||
label={confirmButtonLabel}
|
||||
disabled={confirmButtonDisabled}
|
||||
onClick={onConfirmed}
|
||||
button="link"
|
||||
label={abortButtonLabel}
|
||||
disabled={abortButtonDisabled}
|
||||
onClick={onAborted}
|
||||
/>
|
||||
{type === 'confirm' ? (
|
||||
<Button
|
||||
button="link"
|
||||
label={abortButtonLabel}
|
||||
disabled={abortButtonDisabled}
|
||||
onClick={onAborted}
|
||||
/>
|
||||
) : null}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
) : null}
|
||||
</div>
|
||||
)}
|
||||
</ReactModal>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -6,13 +6,23 @@ import Button from 'component/button';
|
|||
|
||||
type Props = {
|
||||
closeModal: () => void,
|
||||
unlockWallet: string => void,
|
||||
walletEncryptSucceded: boolean,
|
||||
walletEncryptResult: boolean,
|
||||
updateWalletStatus: boolean,
|
||||
encryptWallet: string => void,
|
||||
updateWalletStatus: () => void,
|
||||
};
|
||||
|
||||
class ModalWalletEncrypt extends React.PureComponent<Props> {
|
||||
type State = {
|
||||
newPassword: ?string,
|
||||
newPasswordConfirm: ?string,
|
||||
passwordMismatch: boolean,
|
||||
understandConfirmed: boolean,
|
||||
understandError: boolean,
|
||||
submitted: boolean,
|
||||
failMessage: boolean,
|
||||
};
|
||||
|
||||
class ModalWalletEncrypt extends React.PureComponent<Props, State> {
|
||||
state = {
|
||||
newPassword: null,
|
||||
newPasswordConfirm: null,
|
||||
|
@ -23,15 +33,30 @@ class ModalWalletEncrypt extends React.PureComponent<Props> {
|
|||
failMessage: false,
|
||||
};
|
||||
|
||||
onChangeNewPassword(event) {
|
||||
componentDidUpdate() {
|
||||
const { props, state } = this;
|
||||
|
||||
if (state.submitted) {
|
||||
if (props.walletEncryptSucceded === true) {
|
||||
props.closeModal();
|
||||
props.updateWalletStatus();
|
||||
} else if (props.walletEncryptSucceded === false) {
|
||||
// See https://github.com/lbryio/lbry/issues/1307
|
||||
// eslint-disable-next-line react/no-did-update-set-state
|
||||
this.setState({ failMessage: 'Unable to encrypt wallet.' });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onChangeNewPassword(event: SyntheticInputEvent<>) {
|
||||
this.setState({ newPassword: event.target.value });
|
||||
}
|
||||
|
||||
onChangeNewPasswordConfirm(event) {
|
||||
onChangeNewPasswordConfirm(event: SyntheticInputEvent<>) {
|
||||
this.setState({ newPasswordConfirm: event.target.value });
|
||||
}
|
||||
|
||||
onChangeUnderstandConfirm(event) {
|
||||
onChangeUnderstandConfirm(event: SyntheticInputEvent<>) {
|
||||
this.setState({
|
||||
understandConfirmed: /^.?i understand.?$/i.test(event.target.value),
|
||||
});
|
||||
|
@ -60,20 +85,6 @@ class ModalWalletEncrypt extends React.PureComponent<Props> {
|
|||
this.props.encryptWallet(state.newPassword);
|
||||
}
|
||||
|
||||
componentDidUpdate() {
|
||||
const { props, state } = this;
|
||||
|
||||
if (state.submitted) {
|
||||
if (props.walletEncryptSucceded === true) {
|
||||
props.closeModal();
|
||||
props.updateWalletStatus();
|
||||
} else if (props.walletEncryptSucceded === false) {
|
||||
// See https://github.com/lbryio/lbry/issues/1307
|
||||
this.setState({ failMessage: 'Unable to encrypt wallet.' });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
const { closeModal } = this.props;
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@ type Props = {
|
|||
channelIsMine: boolean,
|
||||
fetchClaims: (string, number) => void,
|
||||
navigate: (string, {}) => void,
|
||||
openModal: ({ id: string }, { uri: string }) => void,
|
||||
openModal: (id: string, { uri: string }) => void,
|
||||
};
|
||||
|
||||
class ChannelPage extends React.PureComponent<Props> {
|
||||
|
@ -99,10 +99,7 @@ class ChannelPage extends React.PureComponent<Props> {
|
|||
icon={icons.GLOBE}
|
||||
label={__('Share Channel')}
|
||||
onClick={() =>
|
||||
openModal(
|
||||
{ id: MODALS.SOCIAL_SHARE },
|
||||
{ uri, speechShareable: true, isChannel: true }
|
||||
)
|
||||
openModal(MODALS.SOCIAL_SHARE, { uri, speechShareable: true, isChannel: true })
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
|
@ -111,33 +108,34 @@ class ChannelPage extends React.PureComponent<Props> {
|
|||
|
||||
<section className="media-group--list">{contentList}</section>
|
||||
|
||||
{(!fetching || (claimsInChannel && claimsInChannel.length)) && totalPages > 1 && (
|
||||
<FormRow verticallyCentered centered>
|
||||
<ReactPaginate
|
||||
pageCount={totalPages}
|
||||
pageRangeDisplayed={2}
|
||||
previousLabel="‹"
|
||||
nextLabel="›"
|
||||
activeClassName="pagination__item--selected"
|
||||
pageClassName="pagination__item"
|
||||
previousClassName="pagination__item pagination__item--previous"
|
||||
nextClassName="pagination__item pagination__item--next"
|
||||
breakClassName="pagination__item pagination__item--break"
|
||||
marginPagesDisplayed={2}
|
||||
onPageChange={e => this.changePage(e.selected + 1)}
|
||||
forcePage={currentPage}
|
||||
initialPage={currentPage}
|
||||
containerClassName="pagination"
|
||||
/>
|
||||
{(!fetching || (claimsInChannel && claimsInChannel.length)) &&
|
||||
totalPages > 1 && (
|
||||
<FormRow verticallyCentered centered>
|
||||
<ReactPaginate
|
||||
pageCount={totalPages}
|
||||
pageRangeDisplayed={2}
|
||||
previousLabel="‹"
|
||||
nextLabel="›"
|
||||
activeClassName="pagination__item--selected"
|
||||
pageClassName="pagination__item"
|
||||
previousClassName="pagination__item pagination__item--previous"
|
||||
nextClassName="pagination__item pagination__item--next"
|
||||
breakClassName="pagination__item pagination__item--break"
|
||||
marginPagesDisplayed={2}
|
||||
onPageChange={e => this.changePage(e.selected + 1)}
|
||||
forcePage={currentPage}
|
||||
initialPage={currentPage}
|
||||
containerClassName="pagination"
|
||||
/>
|
||||
|
||||
<FormField
|
||||
className="paginate-channel"
|
||||
onKeyUp={e => this.paginate(e, totalPages)}
|
||||
prefix={__('Go to page:')}
|
||||
type="text"
|
||||
/>
|
||||
</FormRow>
|
||||
)}
|
||||
<FormField
|
||||
className="paginate-channel"
|
||||
onKeyUp={e => this.paginate(e, totalPages)}
|
||||
prefix={__('Go to page:')}
|
||||
type="text"
|
||||
/>
|
||||
</FormRow>
|
||||
)}
|
||||
|
||||
{!channelIsMine && <HiddenNsfwClaims className="card__content help" uri={uri} />}
|
||||
</Page>
|
||||
|
|
|
@ -216,14 +216,14 @@ class FilePage extends React.Component<Props> {
|
|||
button="alt"
|
||||
icon={icons.GIFT}
|
||||
label={__('Send a tip')}
|
||||
onClick={() => openModal({ id: MODALS.SEND_TIP }, { uri })}
|
||||
onClick={() => openModal(MODALS.SEND_TIP, { uri })}
|
||||
/>
|
||||
)}
|
||||
<Button
|
||||
button="alt"
|
||||
icon={icons.GLOBE}
|
||||
label={__('Share')}
|
||||
onClick={() => openModal({ id: MODALS.SOCIAL_SHARE }, { uri, speechShareable })}
|
||||
onClick={() => openModal(MODALS.SOCIAL_SHARE, { uri, speechShareable })}
|
||||
/>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -191,8 +191,8 @@ class HelpPage extends React.PureComponent<Props, State> {
|
|||
<h2 className="card__title">{__('Report a Bug or Suggest a New Feature')}</h2>
|
||||
|
||||
<p className="card__subtitle">
|
||||
{__('Did you find something wrong? Think LBRY could add something useful and cool?')}
|
||||
<Button button="link" label={__('Learn more')} href="https://lbry.io/faq/support" />
|
||||
{__('Did you find something wrong? Think LBRY could add something useful and cool?')}{' '}
|
||||
<Button button="link" label={__('Learn more')} href="https://lbry.io/faq/support" />.
|
||||
</p>
|
||||
</header>
|
||||
|
||||
|
@ -274,14 +274,15 @@ class HelpPage extends React.PureComponent<Props, State> {
|
|||
{this.state.accessTokenHidden && (
|
||||
<Button button="link" label={__('View')} onClick={this.showAccessToken} />
|
||||
)}
|
||||
{!this.state.accessTokenHidden && accessToken && (
|
||||
<div>
|
||||
<p>{accessToken}</p>
|
||||
<div className="alert-text">
|
||||
{__('This is equivalent to a password. Do not post or share this.')}
|
||||
{!this.state.accessTokenHidden &&
|
||||
accessToken && (
|
||||
<div>
|
||||
<p>{accessToken}</p>
|
||||
<div className="alert-text">
|
||||
{__('This is equivalent to a password. Do not post or share this.')}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
)}
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
|
|
|
@ -99,7 +99,7 @@ export const doUploadThumbnail = (filePath: string, nsfw: boolean) => (
|
|||
type: ACTIONS.UPDATE_PUBLISH_FORM,
|
||||
data: { uploadThumbnailStatus: THUMBNAIL_STATUSES.API_DOWN },
|
||||
},
|
||||
dispatch(doOpenModal(MODALS.ERROR, { error }))
|
||||
doError(MODALS.ERROR, { error })
|
||||
)
|
||||
);
|
||||
|
||||
|
@ -119,16 +119,17 @@ export const doUploadThumbnail = (filePath: string, nsfw: boolean) => (
|
|||
body: data,
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(json =>
|
||||
json.success
|
||||
? dispatch({
|
||||
type: ACTIONS.UPDATE_PUBLISH_FORM,
|
||||
data: {
|
||||
uploadThumbnailStatus: THUMBNAIL_STATUSES.COMPLETE,
|
||||
thumbnail: `${json.data.url}${fileExt}`,
|
||||
},
|
||||
})
|
||||
: uploadError(json.message)
|
||||
.then(
|
||||
json =>
|
||||
json.success
|
||||
? dispatch({
|
||||
type: ACTIONS.UPDATE_PUBLISH_FORM,
|
||||
data: {
|
||||
uploadThumbnailStatus: THUMBNAIL_STATUSES.COMPLETE,
|
||||
thumbnail: `${json.data.url}${fileExt}`,
|
||||
},
|
||||
})
|
||||
: uploadError(json.message)
|
||||
)
|
||||
.catch(err => uploadError(err.message));
|
||||
};
|
||||
|
|
|
@ -21,7 +21,6 @@
|
|||
@import 'component/form-field';
|
||||
@import 'component/form-row';
|
||||
@import 'component/header';
|
||||
@import 'component/icon';
|
||||
@import 'component/item-list';
|
||||
@import 'component/load-screen';
|
||||
@import 'component/main';
|
||||
|
|
|
@ -91,7 +91,6 @@
|
|||
|
||||
&:hover {
|
||||
background-color: $lbry-gray-1;
|
||||
color: $lbry-black;
|
||||
|
||||
html[data-theme='dark'] & {
|
||||
background-color: rgba($lbry-white, 0.1);
|
||||
|
|
|
@ -60,6 +60,7 @@
|
|||
}
|
||||
|
||||
.card__actions--center {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
|
|
@ -19,13 +19,12 @@
|
|||
display: flex;
|
||||
justify-content: center;
|
||||
position: absolute;
|
||||
background-position: 50% 50%;
|
||||
background-repeat: no-repeat;
|
||||
background-size: contain;
|
||||
|
||||
&:not(.card__media--nsfw) {
|
||||
background-color: $lbry-black;
|
||||
|
||||
html[data-theme='dark'] & {
|
||||
background-color: rgba($lbry-white, 0.1);
|
||||
}
|
||||
background-color: #000; // solid black to blend nicely when the video starts (if it doesn't take the full width)
|
||||
}
|
||||
|
||||
&:hover {
|
||||
|
@ -76,7 +75,6 @@
|
|||
height: 100%;
|
||||
|
||||
align-items: center;
|
||||
background-color: rgba($lbry-black, 0.5);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
|
@ -93,6 +91,7 @@
|
|||
top: 0;
|
||||
left: 0;
|
||||
|
||||
background-color: #000;
|
||||
align-items: center;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
|
|
|
@ -18,7 +18,6 @@
|
|||
align-items: center;
|
||||
display: flex;
|
||||
font-size: 1.25rem;
|
||||
margin-bottom: var(--spacing-vertical-small);
|
||||
|
||||
&.form-field--auto-height {
|
||||
height: auto;
|
||||
|
@ -95,7 +94,7 @@
|
|||
.form-field__select-wrapper {
|
||||
position: relative;
|
||||
width: 20rem;
|
||||
height: 3rem;
|
||||
height: 2rem;
|
||||
|
||||
&::after {
|
||||
width: 100%;
|
||||
|
@ -104,8 +103,7 @@
|
|||
left: 0;
|
||||
|
||||
// TRIANGLE_DOWN
|
||||
// background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink'%3E %3Cpath d='M3 4 L21 4 12 20 3 4 Z' stroke='black' stroke-width='2' fill='black' fill-rule='evenodd' stroke-linejoin='round'/%3E %3C/svg%3E"),
|
||||
// linear-gradient(to right, transparent 80%, $lbry-gray-1 85%);
|
||||
background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink'%3E %3Cpath d='M3 4 L21 4 12 20 3 4 Z' stroke='black' stroke-width='2' fill='black' fill-rule='evenodd' stroke-linejoin='round'/%3E %3C/svg%3E");
|
||||
background-position: 95% center, right top;
|
||||
background-repeat: no-repeat;
|
||||
background-size: 0.8rem, 100%;
|
||||
|
@ -121,7 +119,7 @@
|
|||
|
||||
background-color: $lbry-gray-1;
|
||||
border-radius: 0;
|
||||
padding: var(--spacing-vertical-small);
|
||||
padding: 0 var(--spacing-vertical-small);
|
||||
|
||||
-webkit-appearance: none;
|
||||
|
||||
|
|
|
@ -1,6 +0,0 @@
|
|||
// Icons with icons directly following should have a margin-right for proper spacing
|
||||
// Same for prices on cards
|
||||
.icon + .icon,
|
||||
.credit-amount + .icon {
|
||||
margin-left: var(--spacing-vertical-small);
|
||||
}
|
|
@ -4,6 +4,10 @@
|
|||
position: relative;
|
||||
z-index: 1;
|
||||
|
||||
&.main--contained {
|
||||
max-width: 1000px;
|
||||
}
|
||||
|
||||
&:not(.main--no-padding) {
|
||||
padding: var(--spacing-vertical-large);
|
||||
}
|
||||
|
|
|
@ -15,20 +15,28 @@
|
|||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.CodeMirror-selected {
|
||||
// background-color: transparent;
|
||||
}
|
||||
|
||||
.CodeMirror-selectedtext {
|
||||
background-color: $lbry-teal-5 !important;
|
||||
color: $lbry-white;
|
||||
}
|
||||
|
||||
.cm-spell-error:not(.cm-url):not(.cm-comment):not(.cm-tag):not(.cm-word) {
|
||||
text-decoration: underline;
|
||||
text-decoration-color: $lbry-red-3;
|
||||
text-decoration-style: dotted;
|
||||
}
|
||||
|
||||
html[data-theme='dark'] & {
|
||||
border-left: 1px solid rgba($lbry-white, 0.2);
|
||||
border-right: 1px solid rgba($lbry-white, 0.2);
|
||||
border-bottom: 1px solid rgba($lbry-white, 0.2);
|
||||
background-color: rgba($lbry-white, 0.1);
|
||||
color: $lbry-white;
|
||||
|
||||
.CodeMirror-selectedtext {
|
||||
color: $lbry-black;
|
||||
}
|
||||
|
||||
.editor-preview.editor-preview-active {
|
||||
background-color: $lbry-gray-5;
|
||||
color: $lbry-black;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Fix selection
|
||||
|
@ -82,6 +90,33 @@
|
|||
i.separator {
|
||||
border: none;
|
||||
}
|
||||
|
||||
html[data-theme='dark'] & {
|
||||
background-color: rgba($lbry-white, 0.2);
|
||||
|
||||
a {
|
||||
color: $lbry-white !important; // We need to use !important to override the CodeMirror styles
|
||||
|
||||
&.active {
|
||||
background-color: rgba($lbry-black, 0.4);
|
||||
}
|
||||
|
||||
&:hover {
|
||||
color: $lbry-black !important;
|
||||
}
|
||||
}
|
||||
|
||||
&.disabled-for-preview {
|
||||
a:not(.no-disable) {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
// The markdown preview button is highlighted during preview when the other buttons are disabled
|
||||
a.no-disable {
|
||||
background-color: rgba($lbry-white, 0.3);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.editor-statusbar {
|
||||
|
|
|
@ -44,7 +44,8 @@
|
|||
.media--placeholder {
|
||||
.media__channel,
|
||||
.media__date,
|
||||
.media__title {
|
||||
.media__title,
|
||||
.media__properties {
|
||||
min-height: 1rem;
|
||||
}
|
||||
|
||||
|
@ -154,6 +155,7 @@
|
|||
|
||||
.media__actions {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
padding-top: var(--spacing-vertical-large);
|
||||
padding-bottom: var(--spacing-vertical-large);
|
||||
}
|
||||
|
@ -254,11 +256,16 @@
|
|||
&:not(:last-of-type) {
|
||||
margin-bottom: var(--spacing-vertical-large);
|
||||
}
|
||||
|
||||
&.media__info-text--center {
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
||||
.media__info-title {
|
||||
font-size: 1.25rem;
|
||||
font-weight: 500;
|
||||
margin-bottom: var(--spacing-vertical-small);
|
||||
}
|
||||
|
||||
// M E D I A
|
||||
|
@ -298,10 +305,6 @@
|
|||
position: relative;
|
||||
top: 0.2rem;
|
||||
}
|
||||
|
||||
svg {
|
||||
padding-top: 0.2rem;
|
||||
}
|
||||
}
|
||||
|
||||
svg {
|
||||
|
@ -328,6 +331,10 @@
|
|||
}
|
||||
}
|
||||
|
||||
.media__properties--placeholder {
|
||||
@include placeholder;
|
||||
}
|
||||
|
||||
// M E D I A
|
||||
// S U B T I T L E
|
||||
|
||||
|
@ -518,18 +525,6 @@
|
|||
rgba(mix($lbry-blue-3, $lbry-black, 70%), 0.8) 100%
|
||||
);
|
||||
}
|
||||
|
||||
// The featured row needs different top spacing
|
||||
// depending on screen width
|
||||
|
||||
@media (min-width: 601px) {
|
||||
padding-bottom: var(--spacing-vertical-large);
|
||||
}
|
||||
|
||||
@media (max-width: 600px) {
|
||||
padding-bottom: var(--spacing-vertical-medium);
|
||||
}
|
||||
|
||||
.media-group__header-title {
|
||||
background-image: linear-gradient(to right, $lbry-white 80%, transparent 100%);
|
||||
}
|
||||
|
@ -548,8 +543,6 @@
|
|||
}
|
||||
|
||||
&:not(:first-of-type) {
|
||||
padding-bottom: var(--spacing-vertical-large);
|
||||
|
||||
.media-group__header-title {
|
||||
background-image: linear-gradient(to right, $lbry-black 80%, transparent 100%);
|
||||
}
|
||||
|
@ -643,7 +636,15 @@
|
|||
|
||||
.media-scrollhouse {
|
||||
min-height: 200px;
|
||||
overflow: hidden;
|
||||
padding-bottom: var(--spacing-vertical-large);
|
||||
|
||||
// Show the scroll bar on hover
|
||||
// `overlay` doesn't take up any vertical space
|
||||
overflow-x: hidden;
|
||||
overflow-y: hidden;
|
||||
&:hover {
|
||||
overflow-x: overlay;
|
||||
}
|
||||
|
||||
// The media queries in this block ensure that a row of
|
||||
// content and its' child elements look good at certain breakpoints
|
||||
|
@ -666,35 +667,30 @@
|
|||
|
||||
@media (min-width: 601px) {
|
||||
width: calc((100% / 6) - 2.25rem);
|
||||
|
||||
&:not(:first-of-type) {
|
||||
margin-left: var(--spacing-vertical-large);
|
||||
}
|
||||
|
||||
&:first-of-type {
|
||||
margin-left: var(--spacing-vertical-large);
|
||||
}
|
||||
margin-left: var(--spacing-vertical-large);
|
||||
|
||||
&:last-of-type {
|
||||
margin-right: var(--spacing-vertical-large);
|
||||
// For some reason margin doesn't work here.
|
||||
padding-right: var(--spacing-vertical-large);
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 600px) {
|
||||
width: calc((100% / 3) - 3rem);
|
||||
|
||||
&:not(:first-of-type) {
|
||||
margin-left: var(--spacing-vertical-medium);
|
||||
}
|
||||
|
||||
&:first-of-type {
|
||||
margin-left: var(--spacing-vertical-large);
|
||||
}
|
||||
|
||||
&:last-of-type {
|
||||
margin-right: var(--spacing-vertical-large);
|
||||
}
|
||||
}
|
||||
// May be needed for mobile design
|
||||
// @media (max-width: 600px) {
|
||||
// width: calc((100% / 3) - 3rem);
|
||||
//
|
||||
// &:not(:first-of-type) {
|
||||
// margin-left: var(--spacing-vertical-medium);
|
||||
// }
|
||||
//
|
||||
// &:first-of-type {
|
||||
// margin-left: var(--spacing-vertical-large);
|
||||
// }
|
||||
//
|
||||
// &:last-of-type {
|
||||
// margin-right: var(--spacing-vertical-large);
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
.media__title {
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
.pagination {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
+ .form-field {
|
||||
margin-left: var(--spacing-vertical-medium);
|
||||
}
|
||||
|
@ -9,19 +12,19 @@
|
|||
height: 3rem;
|
||||
|
||||
border-radius: 50%;
|
||||
display: inline-block;
|
||||
text-align: center;
|
||||
|
||||
&:not(&--selected):not(&--break):not(.disabled):hover {
|
||||
&:not(.pagination__item--selected):not(.pagination__item--break):not(.disabled):hover {
|
||||
background-color: $lbry-gray-1;
|
||||
}
|
||||
|
||||
&:not(&--previous):not(&--next) {
|
||||
&:not(.pagination__item--previous):not(.pagination__item--next) {
|
||||
font-weight: 600;
|
||||
line-height: 3rem;
|
||||
margin: 0 0.5em;
|
||||
}
|
||||
|
||||
&:not(&--break):not(.disabled) {
|
||||
&:not(.pagination__item--break):not(.disabled) {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
|
@ -36,7 +39,6 @@
|
|||
|
||||
.pagination__item--previous,
|
||||
.pagination__item--next {
|
||||
bottom: -0.4rem;
|
||||
font-size: 2.5rem;
|
||||
line-height: 1;
|
||||
position: relative;
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
background-color: $lbry-teal-4;
|
||||
border-radius: 0.5rem;
|
||||
color: $lbry-white;
|
||||
max-width: var(--snack-bar-width);
|
||||
padding: var(--spacing-vertical-small) var(--spacing-vertical-large) var(--spacing-vertical-small)
|
||||
var(--spacing-vertical-medium);
|
||||
position: fixed;
|
||||
|
@ -19,7 +18,7 @@
|
|||
|
||||
.snack-bar__action {
|
||||
display: inline-block;
|
||||
margin-bottom: var(--spacing-vertical-small);
|
||||
margin: var(--spacing-vertical-small) 0;
|
||||
min-width: min-content;
|
||||
text-transform: uppercase;
|
||||
|
||||
|
|
|
@ -69,12 +69,6 @@ input {
|
|||
&:not(.input-copyable):not(.wunderbar__input) {
|
||||
border-bottom: var(--input-border-size) solid $lbry-gray-5;
|
||||
}
|
||||
|
||||
&:not(.input-copyable):not(.wunderbar__input):not(:placeholder-shown):not(:disabled) {
|
||||
&:hover {
|
||||
border-color: rgba($lbry-black, 0.8);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.input--price-amount {
|
||||
|
|
|
@ -19,7 +19,6 @@ $large-breakpoint: 1921px;
|
|||
--spacing-vertical-large: 2rem;
|
||||
|
||||
--video-aspect-ratio: 56.25%; // 9 x 16
|
||||
--snack-bar-width: 756px;
|
||||
|
||||
// Text
|
||||
--text-max-width: 660px;
|
||||
|
|
10
yarn.lock
10
yarn.lock
|
@ -105,6 +105,10 @@
|
|||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/@lbry/color/-/color-1.0.3.tgz#ec22b2c48b0e358759528fb3bbe7ba468d4e41ca"
|
||||
|
||||
"@lbry/components@^1.5.1":
|
||||
version "1.6.3"
|
||||
resolved "https://registry.yarnpkg.com/@lbry/components/-/components-1.6.3.tgz#5187736e8d51d24a4678f972d3c062d880d6d853"
|
||||
|
||||
"@mapbox/hast-util-table-cell-style@^0.1.3":
|
||||
version "0.1.3"
|
||||
resolved "https://registry.yarnpkg.com/@mapbox/hast-util-table-cell-style/-/hast-util-table-cell-style-0.1.3.tgz#5b7166ae01297d72216932b245e4b2f0b642dca6"
|
||||
|
@ -4074,9 +4078,9 @@ flatten@^1.0.2:
|
|||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/flatten/-/flatten-1.0.2.tgz#dae46a9d78fbe25292258cc1e780a41d95c03782"
|
||||
|
||||
flow-bin@^0.69.0:
|
||||
version "0.69.0"
|
||||
resolved "http://registry.npmjs.org/flow-bin/-/flow-bin-0.69.0.tgz#053159a684a6051fcbf0b71a2eb19a9679082da6"
|
||||
flow-bin@^0.89.0:
|
||||
version "0.89.0"
|
||||
resolved "https://registry.yarnpkg.com/flow-bin/-/flow-bin-0.89.0.tgz#6bd29c2af7e0f429797f820662f33749105c32fa"
|
||||
|
||||
flow-typed@^2.3.0:
|
||||
version "2.5.1"
|
||||
|
|
Loading…
Reference in a new issue