Merge 'relase' into 'master' (#2289)

* v0.29.0-rc.1

* bump daemon

* v0.29.0-rc.2

* bump lbry/components

* v0.29.0-rc.3

* fix: remember if search options were open

* fix: scrollable list on subscriptions

* fix: icon alignment on file page

* fix: button color in publish form

* fix: select option color for windows/linux

* fix: don't break app when navigating to abaondoned claims

* fix: thumbnail size on related content

* maint: rc4

with UI fixes

* fix: ... buttons ... again

* fix: file percentage on pending downloads

Changed to DidMount (did update seemed to trigger the file list too many times) - this will show the percentage if it's not completed and currently downloading. Typical cases are if a person refreshed or navigated away/back. This way if a download is stuck, a user will see the percentage and can try to delete/redownload (we should add a start/stop feature later on).

* fix: name input text wrapping

* change: use select drop down for search results

* add search analytics

* v0.29.0-rc.5

* v0.29.0-rc.6

* fix: name input alignment

* fix: metadata

* bump sdk

* v0.29.0-rc.7

* fix: line-height

* v0.29.0-rc.8

* v0.29.0
This commit is contained in:
Sean Yesmunt 2019-02-21 17:45:17 -05:00 committed by GitHub
parent f0389221f2
commit 7577586ea9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
23 changed files with 272 additions and 140 deletions

View file

@ -1,6 +1,6 @@
{ {
"name": "LBRY", "name": "LBRY",
"version": "0.29.0-rc.0", "version": "0.29.0",
"description": "A browser for the LBRY network, a digital marketplace controlled by its users.", "description": "A browser for the LBRY network, a digital marketplace controlled by its users.",
"keywords": [ "keywords": [
"lbry" "lbry"
@ -34,7 +34,7 @@
"postinstall": "electron-builder install-app-deps && node build/downloadDaemon.js" "postinstall": "electron-builder install-app-deps && node build/downloadDaemon.js"
}, },
"dependencies": { "dependencies": {
"@lbry/components": "^2.2.1", "@lbry/components": "^2.2.4",
"@types/three": "^0.93.1", "@types/three": "^0.93.1",
"bluebird": "^3.5.1", "bluebird": "^3.5.1",
"breakdance": "^3.0.1", "breakdance": "^3.0.1",
@ -134,7 +134,7 @@
"yarn": "^1.3" "yarn": "^1.3"
}, },
"lbrySettings": { "lbrySettings": {
"lbrynetDaemonVersion": "0.32.0", "lbrynetDaemonVersion": "0.32.2",
"lbrynetDaemonUrlTemplate": "https://github.com/lbryio/lbry/releases/download/vDAEMONVER/lbrynet-OSNAME.zip", "lbrynetDaemonUrlTemplate": "https://github.com/lbryio/lbry/releases/download/vDAEMONVER/lbrynet-OSNAME.zip",
"lbrynetDaemonDir": "static/daemon", "lbrynetDaemonDir": "static/daemon",
"lbrynetDaemonFileName": "lbrynet" "lbrynetDaemonFileName": "lbrynet"

View file

@ -80,6 +80,10 @@ const analytics: Analytics = {
Lbryio.call('event', 'publish'); Lbryio.call('event', 'publish');
} }
}, },
apiSearchFeedback: (query, vote) => {
// We don't need to worry about analytics enabled here because users manually click on the button to provide feedback
Lbryio.call('feedback', 'search', { query, vote });
},
}; };
export default analytics; export default analytics;

View file

@ -57,21 +57,21 @@ class CategoryList extends PureComponent<Props, State> {
fetchChannel(categoryLink); fetchChannel(categoryLink);
} }
if (!urisInList) { const scrollWrapper = this.scrollWrapper.current;
return; if (scrollWrapper) {
} scrollWrapper.addEventListener('scroll', throttle(this.handleArrowButtonsOnScroll, 500));
if (lazyLoad) { if (!urisInList) {
const scrollWrapper = this.scrollWrapper.current; return;
if (scrollWrapper) { }
scrollWrapper.addEventListener('scroll', throttle(this.handleArrowButtonsOnScroll, 500));
if (urisInList && window.innerHeight > scrollWrapper.offsetTop) { if (lazyLoad) {
if (window.innerHeight > scrollWrapper.offsetTop) {
resolveUris(urisInList); resolveUris(urisInList);
} }
} else {
resolveUris(urisInList);
} }
} else {
resolveUris(urisInList);
} }
} }

View file

@ -168,11 +168,9 @@ export class FormField extends React.PureComponent<Props> {
input = ( input = (
<React.Fragment> <React.Fragment>
<fieldset-section> <fieldset-section>
{(label || errorMessage) && ( <label htmlFor={name}>
<label htmlFor={name}> {errorMessage ? <span className="error-text">{errorMessage}</span> : label}
{errorMessage ? <span className="error-text">{errorMessage}</span> : label} </label>
</label>
)}
{prefix && ( {prefix && (
<label className="form-field--inline-prefix" htmlFor={name}> <label className="form-field--inline-prefix" htmlFor={name}>
{prefix} {prefix}

View file

@ -7,7 +7,7 @@ type Props = {
title: string, title: string,
subtitle: string | React.Node, subtitle: string | React.Node,
type: string, type: string,
className: ?string, className?: string,
}; };
const yrblTypes = { const yrblTypes = {
@ -30,7 +30,7 @@ export default class extends React.PureComponent<Props> {
<img alt="Friendly gerbil" className="yrbl" src={Native.imagePath(image)} /> <img alt="Friendly gerbil" className="yrbl" src={Native.imagePath(image)} />
<div className="card__content"> <div className="card__content">
<h2 className="card__title">{title}</h2> <h2 className="card__title">{title}</h2>
<p className="card__subtitle">{subtitle}</p> <div className="card__subtitle">{subtitle}</div>
</div> </div>
</div> </div>
); );

View file

@ -16,6 +16,7 @@ type Props = {
outpoint: number, outpoint: number,
download_path: string, download_path: string,
completed: boolean, completed: boolean,
status: string,
}, },
loading: boolean, loading: boolean,
costInfo: ?{}, costInfo: ?{},
@ -26,15 +27,16 @@ type Props = {
}; };
class FileDownloadLink extends React.PureComponent<Props> { class FileDownloadLink extends React.PureComponent<Props> {
componentWillUpdate() { componentDidMount() {
const { downloading, fileInfo, uri, restartDownload } = this.props; const { fileInfo, uri, restartDownload } = this.props;
if ( if (
!downloading &&
fileInfo && fileInfo &&
!fileInfo.completed && !fileInfo.completed &&
fileInfo.status === 'running' &&
fileInfo.written_bytes !== false && fileInfo.written_bytes !== false &&
fileInfo.written_bytes < fileInfo.total_bytes fileInfo.written_bytes < fileInfo.total_bytes
) { ) {
// This calls file list to show the percentage
restartDownload(uri, fileInfo.outpoint); restartDownload(uri, fileInfo.outpoint);
} }
} }

View file

@ -38,6 +38,68 @@ class MediaPlayer extends React.PureComponent {
} }
componentDidMount() { componentDidMount() {
this.playMedia();
// Temp hack to force the video to play if the metadataloaded event was never fired
// Will be removed with the new video player
setTimeout(() => {
const { hasMetadata } = this.state;
if (!hasMetadata) {
this.refreshMetadata();
this.playMedia();
}
}, 5000);
}
componentWillReceiveProps(next) {
const el = this.media.children[0];
if (!this.props.paused && next.paused && !el.paused) el.pause();
}
componentDidUpdate() {
const { contentType, downloadCompleted } = this.props;
const { startedPlaying, fileSource } = this.state;
if (this.playableType() && !startedPlaying && downloadCompleted) {
const container = this.media.children[0];
if (MediaPlayer.MP3_CONTENT_TYPES.indexOf(contentType) > -1) {
this.renderAudio(this.media, true);
} else {
player.append(
this.file(),
container,
{ autoplay: true, controls: true },
renderMediaCallback.bind(this)
);
}
} else if (this.fileType() && !fileSource && downloadCompleted) {
this.renderFile();
}
}
componentWillUnmount() {
document.removeEventListener('keydown', this.togglePlayListener);
const mediaElement = this.media.children[0];
if (mediaElement) {
mediaElement.removeEventListener('click', this.togglePlayListener);
}
}
toggleFullScreen(event) {
const mediaElement = this.media.children[0];
if (mediaElement) {
if (document.webkitIsFullScreen) {
document.webkitExitFullscreen();
} else {
mediaElement.webkitRequestFullScreen();
}
}
}
playMedia() {
const { hasMetadata } = this.state;
const container = this.media; const container = this.media;
const { const {
downloadCompleted, downloadCompleted,
@ -51,15 +113,6 @@ class MediaPlayer extends React.PureComponent {
savePosition, savePosition,
} = this.props; } = this.props;
const loadedMetadata = () => {
this.setState({ hasMetadata: true, startedPlaying: true });
if (onStartCb) {
onStartCb();
}
this.media.children[0].play();
};
const renderMediaCallback = error => { const renderMediaCallback = error => {
if (error) this.setState({ unplayable: true }); if (error) this.setState({ unplayable: true });
}; };
@ -91,16 +144,15 @@ class MediaPlayer extends React.PureComponent {
} }
document.addEventListener('keydown', this.togglePlayListener); document.addEventListener('keydown', this.togglePlayListener);
const mediaElement = this.media.children[0]; const mediaElement = container.children[0];
if (mediaElement) { if (mediaElement) {
if (position) { if (position) {
mediaElement.currentTime = position; mediaElement.currentTime = position;
} }
mediaElement.addEventListener('loadedmetadata', () => this.refreshMetadata());
mediaElement.addEventListener('timeupdate', () => savePosition(mediaElement.currentTime)); mediaElement.addEventListener('timeupdate', () => savePosition(mediaElement.currentTime));
mediaElement.addEventListener('click', this.togglePlayListener); mediaElement.addEventListener('click', this.togglePlayListener);
mediaElement.addEventListener('loadedmetadata', loadedMetadata.bind(this), {
once: true,
});
mediaElement.addEventListener('ended', () => { mediaElement.addEventListener('ended', () => {
if (onFinishCb) { if (onFinishCb) {
onFinishCb(); onFinishCb();
@ -116,48 +168,18 @@ class MediaPlayer extends React.PureComponent {
} }
} }
componentWillReceiveProps(next) { refreshMetadata() {
const el = this.media.children[0]; const { onStartCb } = this.props;
if (!this.props.paused && next.paused && !el.paused) el.pause(); this.setState({ hasMetadata: true, startedPlaying: true });
if (onStartCb) {
onStartCb();
}
this.media.children[0].play();
} }
componentDidUpdate() { setReady() {
const { contentType, downloadCompleted } = this.props; this.setState({ ready: true });
const { startedPlaying, fileSource } = this.state;
if (this.playableType() && !startedPlaying && downloadCompleted) {
const container = this.media.children[0];
if (MediaPlayer.MP3_CONTENT_TYPES.indexOf(contentType) > -1) {
this.renderAudio(this.media, true);
} else {
player.render(this.file(), container, {
autoplay: true,
controls: true,
});
}
} else if (this.fileType() && !fileSource && downloadCompleted) {
this.renderFile();
}
}
componentWillUnmount() {
document.removeEventListener('keydown', this.togglePlayListener);
const mediaElement = this.media.children[0];
if (mediaElement) {
mediaElement.removeEventListener('click', this.togglePlayListener);
}
}
toggleFullScreen(event) {
const mediaElement = this.media.children[0];
if (mediaElement) {
if (document.webkitIsFullScreen) {
document.webkitExitFullscreen();
} else {
mediaElement.webkitRequestFullScreen();
}
}
} }
togglePlay(event) { togglePlay(event) {

View file

@ -1,13 +1,42 @@
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { selectSearchOptions, doUpdateSearchOptions } from 'lbry-redux'; import {
selectSearchOptions,
doUpdateSearchOptions,
makeSelectQueryWithOptions,
doToast,
} from 'lbry-redux';
import { doToggleSearchExpanded } from 'redux/actions/app';
import { selectSearchOptionsExpanded } from 'redux/selectors/app';
import analytics from 'analytics';
import SearchOptions from './view'; import SearchOptions from './view';
const select = state => ({ const select = state => ({
options: selectSearchOptions(state), options: selectSearchOptions(state),
expanded: selectSearchOptionsExpanded(state),
query: makeSelectQueryWithOptions()(state),
}); });
const perform = dispatch => ({ const perform = dispatch => ({
setSearchOption: (option, value) => dispatch(doUpdateSearchOptions({ [option]: value })), setSearchOption: (option, value) => dispatch(doUpdateSearchOptions({ [option]: value })),
toggleSearchExpanded: () => dispatch(doToggleSearchExpanded()),
onFeedbackPositive: query => {
analytics.apiSearchFeedback(query, 1);
dispatch(
doToast({
message: __('Thanks for the feedback! You help make the app better for everyone.'),
})
);
},
onFeedbackNegative: query => {
analytics.apiSearchFeedback(query, 0);
dispatch(
doToast({
message: __(
'Thanks for the feedback. Mark has been notified and is currently walking over to his computer to work on this.'
),
})
);
},
}); });
export default connect( export default connect(

View file

@ -1,6 +1,6 @@
// @flow // @flow
import * as ICONS from 'constants/icons'; import * as ICONS from 'constants/icons';
import React, { useState } from 'react'; import React from 'react';
import { SEARCH_OPTIONS } from 'lbry-redux'; import { SEARCH_OPTIONS } from 'lbry-redux';
import { Form, FormField } from 'component/common/form'; import { Form, FormField } from 'component/common/form';
import posed from 'react-pose'; import posed from 'react-pose';
@ -14,28 +14,50 @@ const ExpandableOptions = posed.div({
type Props = { type Props = {
setSearchOption: (string, boolean | string | number) => void, setSearchOption: (string, boolean | string | number) => void,
options: {}, options: {},
expanded: boolean,
toggleSearchExpanded: () => void,
query: string,
onFeedbackPositive: string => void,
onFeedbackNegative: string => void,
}; };
const SearchOptions = (props: Props) => { const SearchOptions = (props: Props) => {
const { options, setSearchOption } = props; const {
const [expanded, setExpanded] = useState(false); options,
setSearchOption,
expanded,
toggleSearchExpanded,
query,
onFeedbackPositive,
onFeedbackNegative,
} = props;
const resultCount = options[SEARCH_OPTIONS.RESULT_COUNT]; const resultCount = options[SEARCH_OPTIONS.RESULT_COUNT];
return ( return (
<div className="card card--section search__options-wrapper"> <div className="card card--section search__options-wrapper">
<div className="card--space-between"> <div className="card--space-between">
<Button <Button
label={__('SEARCH OPTIONS')} button="alt"
icon={ICONS.OPTIONS} label={__('ADVANCED SEARCH')}
onClick={() => setExpanded(!expanded)} iconRight={expanded ? ICONS.UP : ICONS.DOWN}
onClick={toggleSearchExpanded}
/> />
{/*
Will be added back when api is ready <div className="media__action-group">
<div className="media__action-group">
<span>{__('Find what you were looking for?')}</span> <span>{__('Find what you were looking for?')}</span>
<Button description={__('Yes')} icon={ICONS.YES} /> <Button
<Button description={__('No')} icon={ICONS.NO} /> button="alt"
</div> */} description={__('Yes')}
onClick={() => onFeedbackPositive(query)}
icon={ICONS.YES}
/>
<Button
button="alt"
description={__('No')}
onClick={() => onFeedbackNegative(query)}
icon={ICONS.NO}
/>
</div>
</div> </div>
<ExpandableOptions pose={expanded ? 'show' : 'hide'}> <ExpandableOptions pose={expanded ? 'show' : 'hide'}>
{expanded && ( {expanded && (
@ -77,7 +99,7 @@ const SearchOptions = (props: Props) => {
}, },
{ {
option: SEARCH_OPTIONS.MEDIA_AUDIO, option: SEARCH_OPTIONS.MEDIA_AUDIO,
label: __('Sounds'), label: __('Audio'),
}, },
{ {
option: SEARCH_OPTIONS.MEDIA_IMAGE, option: SEARCH_OPTIONS.MEDIA_IMAGE,
@ -108,13 +130,18 @@ const SearchOptions = (props: Props) => {
<fieldset> <fieldset>
<legend className="search__legend--3">{__('Other Options')}</legend> <legend className="search__legend--3">{__('Other Options')}</legend>
<FormField <FormField
type="number" type="select"
name="result-count" name="result-count"
value={resultCount} value={resultCount}
onChange={e => setSearchOption(SEARCH_OPTIONS.RESULT_COUNT, e.target.value)} onChange={e => setSearchOption(SEARCH_OPTIONS.RESULT_COUNT, e.target.value)}
blockWrap={false} blockWrap={false}
label={__('Returned Results')} label={__('Returned Results')}
/> >
<option value={10}>10</option>
<option value={30}>30</option>
<option value={50}>50</option>
<option value={100}>100</option>
</FormField>
</fieldset> </fieldset>
</Form> </Form>
)} )}

View file

@ -16,6 +16,7 @@ export const VOLUME_CHANGED = 'VOLUME_CHANGED';
export const ADD_COMMENT = 'ADD_COMMENT'; export const ADD_COMMENT = 'ADD_COMMENT';
export const SHOW_MODAL = 'SHOW_MODAL'; export const SHOW_MODAL = 'SHOW_MODAL';
export const HIDE_MODAL = 'HIDE_MODAL'; export const HIDE_MODAL = 'HIDE_MODAL';
export const TOGGLE_SEARCH_EXPANDED = 'TOGGLE_SEARCH_EXPANDED';
export const ENNNHHHAAANNNCEEE = 'ENNNHHHAAANNNCEEE'; export const ENNNHHHAAANNNCEEE = 'ENNNHHHAAANNNCEEE';
// Navigation // Navigation

View file

@ -44,3 +44,5 @@ export const FILE = 'File';
export const OPTIONS = 'Sliders'; export const OPTIONS = 'Sliders';
export const YES = 'ThumbsUp'; export const YES = 'ThumbsUp';
export const NO = 'ThumbsDown'; export const NO = 'ThumbsDown';
export const UP = 'ChevronUp';
export const DOWN = 'ChevronDown';

View file

@ -129,7 +129,7 @@ class RewardsPage extends PureComponent<Props> {
<Fragment> <Fragment>
<section className="card card--section"> <section className="card card--section">
<h2 className="card__title">{__('No Rewards Available')}</h2> <h2 className="card__title">{__('No Rewards Available')}</h2>
<p> <p className="card__content">
{claimed && claimed.length {claimed && claimed.length
? __( ? __(
"You have claimed all available rewards! We're regularly adding more so be sure to check back later." "You have claimed all available rewards! We're regularly adding more so be sure to check back later."

View file

@ -31,7 +31,7 @@ class ShowPage extends React.PureComponent<Props> {
if ( if (
!isResolvingUri && !isResolvingUri &&
uri && uri &&
(claim === undefined || (claim.name[0] === '@' && totalPages === undefined)) (claim === undefined || (claim && claim.name[0] === '@' && totalPages === undefined))
) { ) {
resolveUri(uri); resolveUri(uri);
} }

View file

@ -380,3 +380,9 @@ export function doToggleEnhancedLayout() {
type: ACTIONS.ENNNHHHAAANNNCEEE, type: ACTIONS.ENNNHHHAAANNNCEEE,
}; };
} }
export function doToggleSearchExpanded() {
return {
type: ACTIONS.TOGGLE_SEARCH_EXPANDED,
};
}

View file

@ -35,6 +35,7 @@ export type AppState = {
isUpgradeSkipped: ?boolean, isUpgradeSkipped: ?boolean,
hasClickedComment: boolean, hasClickedComment: boolean,
enhancedLayout: boolean, enhancedLayout: boolean,
searchOptionsExpanded: boolean,
}; };
const defaultState: AppState = { const defaultState: AppState = {
@ -59,6 +60,7 @@ const defaultState: AppState = {
isUpgradeAvailable: undefined, isUpgradeAvailable: undefined,
isUpgradeSkipped: undefined, isUpgradeSkipped: undefined,
enhancedLayout: false, enhancedLayout: false,
searchOptionsExpanded: false,
}; };
reducers[ACTIONS.DAEMON_READY] = state => reducers[ACTIONS.DAEMON_READY] = state =>
@ -220,6 +222,11 @@ reducers[ACTIONS.ENNNHHHAAANNNCEEE] = state =>
enhancedLayout: !state.enhancedLayout, enhancedLayout: !state.enhancedLayout,
}); });
reducers[ACTIONS.TOGGLE_SEARCH_EXPANDED] = state =>
Object.assign({}, state, {
searchOptionsExpanded: !state.searchOptionsExpanded,
});
export default function reducer(state: AppState = defaultState, action: any) { export default function reducer(state: AppState = defaultState, action: any) {
const handler = reducers[action.type]; const handler = reducers[action.type];
if (handler) return handler(state, action); if (handler) return handler(state, action);

View file

@ -248,3 +248,8 @@ export const selectModal = createSelector(selectState, state => {
}); });
export const selectEnhancedLayout = createSelector(selectState, state => state.enhancedLayout); export const selectEnhancedLayout = createSelector(selectState, state => state.enhancedLayout);
export const selectSearchOptionsExpanded = createSelector(
selectState,
state => state.searchOptionsExpanded
);

View file

@ -17,11 +17,12 @@
stroke-opacity: 1; stroke-opacity: 1;
width: 1.4rem; width: 1.4rem;
height: 1.4rem; height: 1.4rem;
top: 0; top: 0.1em;
} }
} }
svg + .button__label { svg + .button__label,
.button__label + svg {
margin-left: var(--spacing-vertical-small); margin-left: var(--spacing-vertical-small);
} }
@ -52,35 +53,45 @@
} }
} }
.button--inverse { // This is a hack and the extra styles are just so this is more specific than the @lbry/components styling
// Will make a PR there, but just doing it now for the release - Sean
[type='button'].button--inverse {
font-size: 1rem; font-size: 1rem;
transition: background-color 0.2s; transition: background-color 0.2s;
border-radius: 0;
html[data-mode='dark'] & { html[data-mode='dark'] & {
border-color: rgba($lbry-white, 0.1); &:not(:hover) {
background-color: rgba($lbry-black, 0.3); border-color: rgba($lbry-white, 0.1);
} background-color: rgba($lbry-black, 0.3);
}
&:not(:hover) { &:hover {
background-color: $lbry-white; border-color: rgba($lbry-white, 0.1);
}
&:hover {
background-color: $lbry-gray-1;
color: $lbry-black;
html[data-mode='dark'] & {
background-color: rgba($lbry-white, 0.1); background-color: rgba($lbry-white, 0.1);
color: $lbry-white; color: $lbry-white;
} }
} }
html[data-mode='light'] & {
&:not(:hover) {
background-color: $lbry-white;
color: $lbry-black;
}
&:hover {
background-color: $lbry-gray-1;
color: $lbry-black;
}
}
.button__content { .button__content {
svg { svg {
color: $lbry-gray-4; color: $lbry-gray-4;
} }
} }
} }
.button--link:not(:disabled) { .button--link:not(:disabled) {
html[data-mode='dark'] & { html[data-mode='dark'] & {
&:not(:hover) { &:not(:hover) {

View file

@ -192,6 +192,10 @@
.card__title { .card__title {
font-size: 2rem; font-size: 2rem;
font-weight: 600; font-weight: 600;
.button {
font-size: 1.2rem;
}
} }
.card__title--flex { .card__title--flex {

View file

@ -9,7 +9,7 @@ input[type='number'] {
input[type='text'], input[type='text'],
input[type='number'], input[type='number'],
select { select {
padding-bottom: 0.2em; padding-bottom: 0.1em;
[data-mode='dark'] & { [data-mode='dark'] & {
&::placeholder { &::placeholder {
@ -99,6 +99,10 @@ fieldset-group {
&.fieldset-group--disabled-prefix { &.fieldset-group--disabled-prefix {
align-items: flex-end; align-items: flex-end;
label {
min-height: 18px;
}
fieldset-section:first-child .form-field__prefix, fieldset-section:first-child .form-field__prefix,
fieldset-section:last-child input { fieldset-section:last-child input {
border-color: $lbry-black; border-color: $lbry-black;
@ -110,6 +114,7 @@ fieldset-group {
fieldset-section:first-child { fieldset-section:first-child {
.form-field__prefix { .form-field__prefix {
white-space: nowrap;
padding: 0.15em var(--spacing-s); padding: 0.15em var(--spacing-s);
padding-right: 0; padding-right: 0;
border: 1px solid; border: 1px solid;
@ -142,14 +147,22 @@ fieldset-group {
// form buttons are black by default // form buttons are black by default
form { form {
// [data-mode='dark'] & { [type='button'],
.button--primary:not(:hover) { [type='submit'] {
background-color: $lbry-teal-5; &.button--primary {
border-color: $lbry-teal-5; &:not(:hover) {
background-color: $lbry-teal-5;
border-color: $lbry-teal-5;
}
&:hover { &:hover {
background-color: $lbry-teal-3; background-color: $lbry-teal-3;
border-color: $lbry-teal-3; border-color: $lbry-teal-3;
}
}
&.button--inverse {
@extend .button--inverse;
} }
} }
} }
@ -175,6 +188,10 @@ fieldset-section {
[data-mode='dark'] & { [data-mode='dark'] & {
background-color: transparent; background-color: transparent;
option {
background-color: $lbry-gray-5;
}
} }
} }
@ -215,17 +232,6 @@ label + .react-toggle,
margin-left: var(--spacing-vertical-small); margin-left: var(--spacing-vertical-small);
} }
.form-field--inline-prefix {
position: absolute;
top: 9.5em;
left: 2.75em;
width: auto;
& + input {
padding-left: 4em;
}
}
.form-field__help { .form-field__help {
@extend .help; @extend .help;
margin-top: var(--spacing-vertical-medium); margin-top: var(--spacing-vertical-medium);

View file

@ -144,8 +144,8 @@
.media__actions { .media__actions {
display: flex; display: flex;
flex-wrap: wrap; flex-wrap: wrap;
padding-top: var(--spacing-vertical-large); margin-top: var(--spacing-vertical-small);
padding-bottom: var(--spacing-vertical-large); margin-bottom: var(--spacing-vertical-small);
} }
.media__actions--between { .media__actions--between {
@ -160,6 +160,8 @@
.media__action-group--large { .media__action-group--large {
display: flex; display: flex;
margin-top: var(--spacing-vertical-small);
margin-bottom: var(--spacing-vertical-small);
> * { > * {
font-size: 1.15rem; font-size: 1.15rem;
@ -168,6 +170,10 @@
margin-right: var(--spacing-vertical-large); margin-right: var(--spacing-vertical-large);
} }
} }
&:not(:last-child) {
margin-right: var(--spacing-vertical-large);
}
} }
// M E D I A // M E D I A

View file

@ -89,6 +89,7 @@ code {
display: -webkit-box; display: -webkit-box;
overflow: hidden; overflow: hidden;
-webkit-box-orient: vertical; -webkit-box-orient: vertical;
word-break: break-word;
} }
.busy-indicator__loader { .busy-indicator__loader {

View file

@ -99,7 +99,7 @@ const fileInfoFilter = createFilter('fileInfo', [
'fileListDownloadedSort', 'fileListDownloadedSort',
'fileListSubscriptionSort', 'fileListSubscriptionSort',
]); ]);
const appFilter = createFilter('app', ['hasClickedComment']); const appFilter = createFilter('app', ['hasClickedComment', 'searchOptionsExpanded']);
// We only need to persist the receiveAddress for the wallet // We only need to persist the receiveAddress for the wallet
const walletFilter = createFilter('wallet', ['receiveAddress']); const walletFilter = createFilter('wallet', ['receiveAddress']);
const searchFilter = createFilter('search', ['options']); const searchFilter = createFilter('search', ['options']);

View file

@ -111,10 +111,10 @@
version "0.7.1" version "0.7.1"
resolved "https://registry.yarnpkg.com/@emotion/memoize/-/memoize-0.7.1.tgz#e93c13942592cf5ef01aa8297444dc192beee52f" resolved "https://registry.yarnpkg.com/@emotion/memoize/-/memoize-0.7.1.tgz#e93c13942592cf5ef01aa8297444dc192beee52f"
"@lbry/components@^2.2.1": "@lbry/components@^2.2.4":
version "2.2.1" version "2.2.4"
resolved "https://registry.yarnpkg.com/@lbry/components/-/components-2.2.1.tgz#3fc67e807796e9dc8cd1d5cd86a719849c4710d5" resolved "https://registry.yarnpkg.com/@lbry/components/-/components-2.2.4.tgz#ee2c91788de447ed33185daa7a747ba684e5143f"
integrity sha512-k8bdSjr0Hq3+ZlvAKRuPea4LTEvXx4zF7+IOb1RmFWfMIk8jBNZi02LmvLoj4VuCa3mKoVfECeaYyXg6vwmY3w== integrity sha512-SF0g4JROwYsvJc9fEFmAYAj9cITJ9L2MTkWCs9vfPhDS4iXE6ZW5VNtcxI5JOVAvsZMRHq5oX9EtjxHs1pIIdg==
"@mapbox/hast-util-table-cell-style@^0.1.3": "@mapbox/hast-util-table-cell-style@^0.1.3":
version "0.1.3" version "0.1.3"
@ -5668,19 +5668,20 @@ lbry-redux@lbryio/lbry-redux#3ab065b11a52d3e2e6a50a25459f9ff0aac03b13:
reselect "^3.0.0" reselect "^3.0.0"
uuid "^3.3.2" uuid "^3.3.2"
lbry-redux@lbryio/lbry-redux#84b7d396934d57a37802aadbef71db91230a9404: lbry-redux@lbryio/lbry-redux#76d8bbef9640bf8ea5c4f45550e55b77d3944ee3:
version "0.0.1" version "0.0.1"
resolved "https://codeload.github.com/lbryio/lbry-redux/tar.gz/84b7d396934d57a37802aadbef71db91230a9404" resolved "https://codeload.github.com/lbryio/lbry-redux/tar.gz/76d8bbef9640bf8ea5c4f45550e55b77d3944ee3"
dependencies: dependencies:
proxy-polyfill "0.1.6" proxy-polyfill "0.1.6"
reselect "^3.0.0" reselect "^3.0.0"
uuid "^3.3.2" uuid "^3.3.2"
lbryinc@lbryio/lbryinc#60d80401891743f991c040bafa8e51da7e939777: lbryinc@lbryio/lbryinc#2334ad53e82c22d6291899785d5292347008f2a9:
version "0.0.1" version "0.0.1"
resolved "https://codeload.github.com/lbryio/lbryinc/tar.gz/60d80401891743f991c040bafa8e51da7e939777" resolved "https://codeload.github.com/lbryio/lbryinc/tar.gz/2334ad53e82c22d6291899785d5292347008f2a9"
dependencies: dependencies:
lbry-redux lbryio/lbry-redux#84b7d396934d57a37802aadbef71db91230a9404 bluebird "^3.5.1"
lbry-redux lbryio/lbry-redux#76d8bbef9640bf8ea5c4f45550e55b77d3944ee3
reselect "^3.0.0" reselect "^3.0.0"
lcid@^1.0.0: lcid@^1.0.0: