this got out of hand

This commit is contained in:
Sean Yesmunt 2019-07-23 04:05:51 -04:00
parent d557a37c01
commit bbd9591f3b
37 changed files with 290 additions and 270 deletions

View file

@ -160,7 +160,7 @@
"react-spring": "^8.0.20", "react-spring": "^8.0.20",
"react-sticky-box": "^0.8.0", "react-sticky-box": "^0.8.0",
"redux": "^3.6.0", "redux": "^3.6.0",
"redux-persist": "^4.8.0", "redux-persist": "^5.10.0",
"redux-persist-transform-compress": "^4.2.0", "redux-persist-transform-compress": "^4.2.0",
"redux-persist-transform-filter": "0.0.16", "redux-persist-transform-filter": "0.0.16",
"redux-thunk": "^2.2.0", "redux-thunk": "^2.2.0",

View file

@ -33,7 +33,7 @@ function ChannelContent(props: Props) {
</div> </div>
)} )}
{!channelIsMine && <HiddenNsfwClaims className="help" uri={uri} />} {!channelIsMine && <HiddenNsfwClaims className="card__subtitle" uri={uri} />}
{hasContent && <ClaimList header={false} uris={claimsInChannel.map(claim => claim.permanent_url)} />} {hasContent && <ClaimList header={false} uris={claimsInChannel.map(claim => claim.permanent_url)} />}

View file

@ -2,7 +2,7 @@
import React, { useState } from 'react'; import React, { useState } from 'react';
import { parseURI } from 'lbry-redux'; import { parseURI } from 'lbry-redux';
import { Form, FormField } from 'component/common/form'; import { Form, FormField } from 'component/common/form';
import Button from 'component/button';
import SelectAsset from 'component/selectAsset'; import SelectAsset from 'component/selectAsset';
import TagSelect from 'component/tagsSelect'; import TagSelect from 'component/tagsSelect';
@ -23,6 +23,7 @@ type Props = {
updateChannel: any => void, updateChannel: any => void,
updateThumb: string => void, updateThumb: string => void,
updateCover: string => void, updateCover: string => void,
setEditing: boolean => void,
}; };
function ChannelForm(props: Props) { function ChannelForm(props: Props) {
@ -38,6 +39,7 @@ function ChannelForm(props: Props) {
locations, locations,
languages, languages,
amount, amount,
setEditing,
updateChannel, updateChannel,
updateThumb, updateThumb,
updateCover, updateCover,
@ -99,11 +101,11 @@ function ChannelForm(props: Props) {
// TODO clear and bail after submit // TODO clear and bail after submit
return ( return (
<section className={'card--section'}> <section className={'card--section'}>
<div className="help"> <div className="card__subtitle">
<p>{__('We can explain...')}</p> <p>{__('We can explain...')}</p>
<p> <p>
{__( {__(
"We know this page won't win any design awards, we just wanted to release a very very very basic version that just barely kinda works so people can use it right now. There is a much nicer version being worked on." "We know this page won't win any design awards, we just wanted to release a very basic version that works so people can use it right now. There is a much nicer version being worked on."
)} )}
</p> </p>
</div> </div>

View file

@ -1,7 +1,7 @@
// @flow // @flow
import { MAIN_WRAPPER_CLASS } from 'component/app/view'; import { MAIN_WRAPPER_CLASS } from 'component/app/view';
import type { Node } from 'react'; import type { Node } from 'react';
import React, { useEffect } from 'react'; import React, { useEffect, useState } from 'react';
import classnames from 'classnames'; import classnames from 'classnames';
import ClaimPreview from 'component/claimPreview'; import ClaimPreview from 'component/claimPreview';
import Spinner from 'component/spinner'; import Spinner from 'component/spinner';
@ -23,6 +23,7 @@ type Props = {
onScrollBottom?: any => void, onScrollBottom?: any => void,
page?: number, page?: number,
pageSize?: number, pageSize?: number,
id?: string,
// If using the default header, this is a unique ID needed to persist the state of the filter setting // If using the default header, this is a unique ID needed to persist the state of the filter setting
persistedStorageKey?: string, persistedStorageKey?: string,
}; };
@ -40,7 +41,10 @@ export default function ClaimList(props: Props) {
header, header,
onScrollBottom, onScrollBottom,
pageSize, pageSize,
page,
id,
} = props; } = props;
const [scrollBottomCbMap, setScrollBottomCbMap] = useState({});
const [currentSort, setCurrentSort] = usePersistedState(persistedStorageKey, SORT_NEW); const [currentSort, setCurrentSort] = usePersistedState(persistedStorageKey, SORT_NEW);
const urisLength = (uris && uris.length) || 0; const urisLength = (uris && uris.length) || 0;
const sortedUris = (urisLength > 0 && (currentSort === SORT_NEW ? uris : uris.slice().reverse())) || []; const sortedUris = (urisLength > 0 && (currentSort === SORT_NEW ? uris : uris.slice().reverse())) || [];
@ -49,14 +53,21 @@ export default function ClaimList(props: Props) {
setCurrentSort(currentSort === SORT_NEW ? SORT_OLD : SORT_NEW); setCurrentSort(currentSort === SORT_NEW ? SORT_OLD : SORT_NEW);
} }
useEffect(() => {
setScrollBottomCbMap({});
}, [id]);
useEffect(() => { useEffect(() => {
function handleScroll(e) { function handleScroll(e) {
if (pageSize && onScrollBottom) { if (page && pageSize && onScrollBottom && !scrollBottomCbMap[page]) {
const x = document.querySelector(`.${MAIN_WRAPPER_CLASS}`); const x = document.querySelector(`.${MAIN_WRAPPER_CLASS}`);
if (x && window.scrollY + window.innerHeight >= x.offsetHeight) { if (x && window.scrollY + window.innerHeight >= x.offsetHeight) {
if (!loading && urisLength >= pageSize) { if (!loading && urisLength >= pageSize) {
onScrollBottom(); onScrollBottom();
// Save that we've fetched this page to avoid weird stuff happening with fast scrolling
setScrollBottomCbMap({ ...scrollBottomCbMap, [page]: true });
} }
} }
} }
@ -69,7 +80,7 @@ export default function ClaimList(props: Props) {
window.removeEventListener('scroll', handleScroll); window.removeEventListener('scroll', handleScroll);
}; };
} }
}, [loading, onScrollBottom, urisLength, pageSize]); }, [loading, onScrollBottom, urisLength, pageSize, page, setScrollBottomCbMap]);
return ( return (
<section <section
@ -103,7 +114,7 @@ export default function ClaimList(props: Props) {
{sortedUris.map((uri, index) => ( {sortedUris.map((uri, index) => (
<React.Fragment key={uri}> <React.Fragment key={uri}>
<ClaimPreview uri={uri} type={type} /> <ClaimPreview uri={uri} type={type} />
{index === 4 && injectedItem && <li className="claim-preview--injected">{injectedItem}</li>} {index === 4 && injectedItem && injectedItem}
</React.Fragment> </React.Fragment>
))} ))}
</ul> </ul>

View file

@ -105,7 +105,10 @@ function ClaimListDiscover(props: Props) {
const claimSearchCacheQuery = buildClaimSearchCacheQuery(options); const claimSearchCacheQuery = buildClaimSearchCacheQuery(options);
const uris = claimSearchByQuery[claimSearchCacheQuery] || []; const uris = claimSearchByQuery[claimSearchCacheQuery] || [];
const shouldPerformSearch = uris.length === 0 || didNavigateForward || (!loading && uris.length < PAGE_SIZE * page); const shouldPerformSearch =
uris.length === 0 ||
didNavigateForward ||
(!loading && uris.length < PAGE_SIZE * page && uris.length % PAGE_SIZE === 0);
// Don't use the query from buildClaimSearchCacheQuery for the effect since that doesn't include page & release_time // Don't use the query from buildClaimSearchCacheQuery for the effect since that doesn't include page & release_time
const optionsStringForEffect = JSON.stringify(options); const optionsStringForEffect = JSON.stringify(options);
@ -211,6 +214,7 @@ function ClaimListDiscover(props: Props) {
return ( return (
<div className="card"> <div className="card">
<ClaimList <ClaimList
id={claimSearchCacheQuery}
loading={loading} loading={loading}
uris={uris} uris={uris}
injectedItem={personalSort === SEARCH_SORT_YOU && injectedItem} injectedItem={personalSort === SEARCH_SORT_YOU && injectedItem}

View file

@ -64,7 +64,8 @@ function ClaimPreview(props: Props) {
const abandoned = !isResolvingUri && !claim; const abandoned = !isResolvingUri && !claim;
const claimsInChannel = (claim && claim.meta.claims_in_channel) || 0; const claimsInChannel = (claim && claim.meta.claims_in_channel) || 0;
const showPublishLink = abandoned && placeholder === 'publish'; const showPublishLink = abandoned && placeholder === 'publish';
const minimal = type === 'small' || type === 'tooltip'; const includeChannelTooltip = type !== 'inline' && type !== 'tooltip';
const hideActions = type === 'small' || type === 'tooltip';
let isValid; let isValid;
try { try {
@ -134,10 +135,11 @@ function ClaimPreview(props: Props) {
onClick={pending || type === 'inline' ? undefined : onClick} onClick={pending || type === 'inline' ? undefined : onClick}
onContextMenu={handleContextMenu} onContextMenu={handleContextMenu}
className={classnames('claim-preview', { className={classnames('claim-preview', {
'claim-preview--small': minimal, 'claim-preview--small': type === 'small' || type === 'tooltip',
'claim-preview--large': type === 'large', 'claim-preview--large': type === 'large',
'claim-preview--inline': type === 'inline', 'claim-preview--inline': type === 'inline',
'claim-preview--visited': !isChannel && hasVisitedUri, 'claim-preview--tooltip': type === 'tooltip',
'claim-preview--visited': !isChannel && !claimIsMine && hasVisitedUri,
'claim-preview--pending': pending, 'claim-preview--pending': pending,
})} })}
> >
@ -147,7 +149,7 @@ function ClaimPreview(props: Props) {
<div className="claim-preview-title"> <div className="claim-preview-title">
{claim ? <TruncatedText text={title || claim.name} lines={1} /> : <span>{__('Nothing here')}</span>} {claim ? <TruncatedText text={title || claim.name} lines={1} /> : <span>{__('Nothing here')}</span>}
</div> </div>
{!minimal && ( {!hideActions && (
<div> <div>
{isChannel && <SubscribeButton uri={uri.startsWith('lbry://') ? uri : `lbry://${uri}`} />} {isChannel && <SubscribeButton uri={uri.startsWith('lbry://') ? uri : `lbry://${uri}`} />}
{!isChannel && <FileProperties uri={uri} />} {!isChannel && <FileProperties uri={uri} />}
@ -161,7 +163,7 @@ function ClaimPreview(props: Props) {
{!isResolvingUri && ( {!isResolvingUri && (
<div> <div>
{claim ? ( {claim ? (
<UriIndicator uri={uri} link addTooltip={!minimal} /> <UriIndicator uri={uri} link addTooltip={includeChannelTooltip} />
) : ( ) : (
<Fragment> <Fragment>
<div>{__('Publish something and claim this spot!')}</div> <div>{__('Publish something and claim this spot!')}</div>

View file

@ -16,22 +16,17 @@ function Comment(props: Props) {
return ( return (
<li className="comment"> <li className="comment">
<div className="comment__meta"> <div className="comment__meta">
<Button className="button--uri-indicator truncated-text comment__author" navigate={authorUri} label={author} /> <Button
className="button--uri-indicator truncated-text comment__author"
navigate={authorUri}
label={author || __('Anonymous')}
/>
<time className="comment__time" dateTime={timePosted}> <time className="comment__time" dateTime={timePosted}>
{relativeDate(timePosted)} {relativeDate(timePosted)}
</time> </time>
</div> </div>
<p className={'comment__message'}>{message}</p> <p className={'comment__message'}>{message}</p>
{/* The following is for adding threaded replies, upvoting and downvoting */}
{/* <div className="comment__actions card__actions--between"> */}
{/* <button className={'button button--primary'}>Reply</button> */}
{/* <span className="comment__actions-wrap"> */}
{/* <button className="comment__action upvote">Up</button> */}
{/* <button className="comment__action downvote">Down</button> */}
{/* </span> */}
{/* </div> */}
</li> </li>
); );
} }

View file

@ -187,8 +187,8 @@ export const icons = {
), ),
[ICONS.COPY]: buildIcon( [ICONS.COPY]: buildIcon(
<g> <g>
<path d="M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2" /> <rect x="9" y="9" width="13" height="13" rx="2" ry="2" />
<rect x="8" y="2" width="8" height="4" rx="1" ry="1" /> <path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1" />
</g> </g>
), ),
[ICONS.REMOVE]: buildIcon( [ICONS.REMOVE]: buildIcon(

View file

@ -1,6 +1,7 @@
// @flow // @flow
import React from 'react'; import React from 'react';
import Button from 'component/button'; import Button from 'component/button';
import classnames from 'classnames';
type Props = { type Props = {
numberOfNsfwClaims: number, numberOfNsfwClaims: number,
@ -14,7 +15,7 @@ export default (props: Props) => {
return ( return (
obscureNsfw && obscureNsfw &&
Boolean(numberOfNsfwClaims) && ( Boolean(numberOfNsfwClaims) && (
<div className={className || 'help'}> <div className={classnames('card--section', className || 'help')}>
{numberOfNsfwClaims} {numberOfNsfwClaims > 1 ? __('files') : __('file')} {__('hidden due to your')}{' '} {numberOfNsfwClaims} {numberOfNsfwClaims > 1 ? __('files') : __('file')} {__('hidden due to your')}{' '}
<Button button="link" navigate="/$/settings" label={__('content viewing preferences')} />. <Button button="link" navigate="/$/settings" label={__('content viewing preferences')} />.
</div> </div>

View file

@ -24,7 +24,7 @@ function SideBar(props: Props) {
} }
return ( return (
<StickyBox offsetBottom={40} offsetTop={90}> <StickyBox offsetTop={100} offsetBottom={20}>
<nav className="navigation"> <nav className="navigation">
<ul className="navigation-links"> <ul className="navigation-links">
{[ {[

View file

@ -21,6 +21,7 @@ type Props = {
tagsChosen?: Array<Tag>, tagsChosen?: Array<Tag>,
onSelect?: Tag => void, onSelect?: Tag => void,
onRemove?: Tag => void, onRemove?: Tag => void,
className?: string,
}; };
const tagsAnimation = { const tagsAnimation = {
@ -41,6 +42,7 @@ export default function TagSelect(props: Props) {
onSelect, onSelect,
onRemove, onRemove,
suggestMature, suggestMature,
className,
} = props; } = props;
const [hasClosed, setHasClosed] = usePersistedState('tag-select:has-closed', false); const [hasClosed, setHasClosed] = usePersistedState('tag-select:has-closed', false);
const tagsToDisplay = tagsChosen || followedTags; const tagsToDisplay = tagsChosen || followedTags;
@ -65,7 +67,7 @@ export default function TagSelect(props: Props) {
return ( return (
((showClose && !hasClosed) || !showClose) && ( ((showClose && !hasClosed) || !showClose) && (
<div> <div className={className}>
{title !== false && ( {title !== false && (
<h2 className="card__title"> <h2 className="card__title">
{title} {title}

View file

@ -72,8 +72,9 @@ class TransactionListItem extends React.PureComponent<Props> {
<td className="table__item--actionable"> <td className="table__item--actionable">
<span>{this.capitalize(type)}</span> {isRevokeable && this.getLink(type)} <span>{this.capitalize(type)}</span> {isRevokeable && this.getLink(type)}
</td> </td>
<td className="table__item--actionable"> <td>
{reward ? <span>{reward.reward_title}</span> : <Button button="link" navigate={uri} label={claimName} />} {reward && <span>{reward.reward_title}</span>}
{name && claimId && <Button button="link" navigate={uri} label={claimName} />}
</td> </td>
<td> <td>

View file

@ -2,7 +2,7 @@
import * as icons from 'constants/icons'; import * as icons from 'constants/icons';
import * as MODALS from 'constants/modal_types'; import * as MODALS from 'constants/modal_types';
import * as React from 'react'; import * as React from 'react';
import { FormField, Form } from 'component/common/form'; import { FormField } from 'component/common/form';
import Button from 'component/button'; import Button from 'component/button';
import FileExporter from 'component/common/file-exporter'; import FileExporter from 'component/common/file-exporter';
import { TRANSACTIONS } from 'lbry-redux'; import { TRANSACTIONS } from 'lbry-redux';
@ -84,7 +84,7 @@ class TransactionList extends React.PureComponent<Props> {
</header> </header>
{!slim && !!transactions.length && ( {!slim && !!transactions.length && (
<header className="table__header"> <header className="table__header">
<div className="card__actions"> <div className="card__actions--between">
<FileExporter <FileExporter
data={transactionList} data={transactionList}
label={__('Export')} label={__('Export')}
@ -93,29 +93,27 @@ class TransactionList extends React.PureComponent<Props> {
defaultPath={__('lbry-transactions-history')} defaultPath={__('lbry-transactions-history')}
/> />
<Form> <FormField
<FormField type="select"
type="select" name="file-sort"
name="file-sort" value={filterSetting || TRANSACTIONS.ALL}
value={filterSetting || TRANSACTIONS.ALL} onChange={this.handleFilterChanged}
onChange={this.handleFilterChanged} label={__('Show')}
label={__('Show')} postfix={
postfix={ <Button
<Button button="link"
button="link" icon={icons.HELP}
icon={icons.HELP} href="https://lbry.com/faq/transaction-types"
href="https://lbry.com/faq/transaction-types" title={__('Help')}
title={__('Help')} />
/> }
} >
> {transactionTypes.map(tt => (
{transactionTypes.map(tt => ( <option key={tt} value={tt}>
<option key={tt} value={tt}> {__(`${this.capitalize(tt)}`)}
{__(`${this.capitalize(tt)}`)} </option>
</option> ))}
))} </FormField>
</FormField>
</Form>
</div> </div>
</header> </header>
)} )}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 23 KiB

View file

@ -78,7 +78,7 @@ class WalletSend extends React.PureComponent<Props> {
</fieldset-group> </fieldset-group>
<div className="card__actions"> <div className="card__actions">
<Button <Button
button="inverse" button="primary"
type="submit" type="submit"
label={__('Send')} label={__('Send')}
disabled={ disabled={

View file

@ -8,7 +8,7 @@ import { ipcRenderer, remote, shell } from 'electron';
import * as ACTIONS from 'constants/action_types'; import * as ACTIONS from 'constants/action_types';
// @endif // @endif
import * as MODALS from 'constants/modal_types'; import * as MODALS from 'constants/modal_types';
import React from 'react'; import React, { useState, useEffect } from 'react';
import ReactDOM from 'react-dom'; import ReactDOM from 'react-dom';
import { Provider } from 'react-redux'; import { Provider } from 'react-redux';
import { doConditionalAuthNavigate, doDaemonReady, doAutoUpdate, doOpenModal, doHideModal } from 'redux/actions/app'; import { doConditionalAuthNavigate, doDaemonReady, doAutoUpdate, doOpenModal, doHideModal } from 'redux/actions/app';
@ -21,13 +21,14 @@ import {
doBlackListedOutpointsSubscribe, doBlackListedOutpointsSubscribe,
doFilteredOutpointsSubscribe, doFilteredOutpointsSubscribe,
} from 'lbryinc'; } from 'lbryinc';
import { store, history } from 'store'; import { store, persistor, history } from 'store';
import pjson from 'package.json'; import pjson from 'package.json';
import app from './app'; import app from './app';
import doLogWarningConsoleMessage from './logWarningConsoleMessage'; import doLogWarningConsoleMessage from './logWarningConsoleMessage';
import { ConnectedRouter, push } from 'connected-react-router'; import { ConnectedRouter, push } from 'connected-react-router';
import cookie from 'cookie'; import cookie from 'cookie';
import { formatLbryUriForWeb } from 'util/uri'; import { formatLbryUriForWeb } from 'util/uri';
import { PersistGate } from 'redux-persist/integration/react';
// Import our app styles // Import our app styles
// If a style is not necessary for the initial page load, it should be removed from `all.scss` // If a style is not necessary for the initial page load, it should be removed from `all.scss`
@ -196,71 +197,64 @@ document.addEventListener('click', event => {
} }
}); });
const init = () => { function AppWrapper() {
// @if TARGET='app' const haveLaunched = window.sessionStorage.getItem('loaded') === 'y';
moment.locale(remote.app.getLocale()); const [readyToLaunch, setReadyToLaunch] = useState(haveLaunched || IS_WEB);
autoUpdater.on('error', error => { useEffect(() => {
console.error(error.message); moment.locale(remote.app.getLocale());
});
if (['win32', 'darwin'].includes(process.platform)) { autoUpdater.on('error', error => {
autoUpdater.on('update-available', () => { console.error(error.message); // eslint-disable-line no-console
console.log('Update available');
}); });
autoUpdater.on('update-not-available', () => {
console.log('Update not available');
});
autoUpdater.on('update-downloaded', () => {
console.log('Update downloaded');
app.store.dispatch(doAutoUpdate());
});
}
app.store.dispatch(doUpdateIsNightAsync()); if (['win32', 'darwin'].includes(process.platform)) {
// @endif autoUpdater.on('update-available', () => {
console.log('Update available'); // eslint-disable-line no-console
});
autoUpdater.on('update-not-available', () => {
console.log('Update not available'); // eslint-disable-line no-console
});
autoUpdater.on('update-downloaded', () => {
console.log('Update downloaded'); // eslint-disable-line no-console
app.store.dispatch(doAutoUpdate());
});
}
}, []);
app.store.dispatch(doInitLanguage()); useEffect(() => {
app.store.dispatch(doBlackListedOutpointsSubscribe()); if (readyToLaunch) {
app.store.dispatch(doFilteredOutpointsSubscribe()); app.store.dispatch(doUpdateIsNightAsync());
app.store.dispatch(doDaemonReady());
app.store.dispatch(doInitLanguage());
app.store.dispatch(doBlackListedOutpointsSubscribe());
app.store.dispatch(doFilteredOutpointsSubscribe());
}
function onDaemonReady() { window.sessionStorage.setItem('loaded', 'y');
// @if TARGET='app' }, [readyToLaunch, haveLaunched]);
window.sessionStorage.setItem('loaded', 'y'); // once we've made it here once per session, we don't need to show splash again
// @endif
app.store.dispatch(doDaemonReady()); return (
ReactDOM.render( <Provider store={store}>
<Provider store={store}> <PersistGate persistor={persistor} loading={<div className="main--launching" />}>
<ConnectedRouter history={history}> <div>
<ErrorBoundary> {readyToLaunch ? (
<App /> <ConnectedRouter history={history}>
<SnackBar /> <ErrorBoundary>
</ErrorBoundary> <App />
</ConnectedRouter> <SnackBar />
</Provider>, </ErrorBoundary>
document.getElementById('app') </ConnectedRouter>
); ) : (
} <SplashScreen
authenticate={() => app.store.dispatch(doAuthenticate(pjson.version))}
onReadyToLaunch={() => setReadyToLaunch(true)}
/>
)}
</div>
</PersistGate>
</Provider>
);
}
// @if TARGET='app' ReactDOM.render(<AppWrapper />, document.getElementById('app'));
if (window.sessionStorage.getItem('loaded') === 'y') {
onDaemonReady();
} else {
ReactDOM.render(
<Provider store={store}>
<SplashScreen
authenticate={() => app.store.dispatch(doAuthenticate(pjson.version))}
onReadyToLaunch={onDaemonReady}
/>
</Provider>,
document.getElementById('app')
);
}
// @endif
// @if TARGET='web'
onDaemonReady();
// @endif
};
init();

View file

@ -19,7 +19,9 @@ function DiscoverPage(props: Props) {
personalView personalView
tags={followedTags.map(tag => tag.name)} tags={followedTags.map(tag => tag.name)}
meta={<Button button="link" label={__('Customize')} navigate={`/$/${PAGES.FOLLOWING}`} />} meta={<Button button="link" label={__('Customize')} navigate={`/$/${PAGES.FOLLOWING}`} />}
injectedItem={<TagsSelect showClose title={__('Customize Your Homepage')} />} injectedItem={
<TagsSelect showClose title={__('Customize Your Homepage')} className="claim-preview--injected" />
}
/> />
</Page> </Page>
); );

View file

@ -30,8 +30,8 @@ type Props = {
showNsfw: boolean, showNsfw: boolean,
instantPurchaseEnabled: boolean, instantPurchaseEnabled: boolean,
instantPurchaseMax: Price, instantPurchaseMax: Price,
currentLanguage: string, // currentLanguage: string,
languages: {}, // languages: {},
currentTheme: string, currentTheme: string,
themes: Array<string>, themes: Array<string>,
automaticDarkModeEnabled: boolean, automaticDarkModeEnabled: boolean,
@ -140,8 +140,8 @@ class SettingsPage extends React.PureComponent<Props, State> {
instantPurchaseEnabled, instantPurchaseEnabled,
instantPurchaseMax, instantPurchaseMax,
currentTheme, currentTheme,
currentLanguage, // currentLanguage,
languages, // languages,
themes, themes,
automaticDarkModeEnabled, automaticDarkModeEnabled,
autoplay, autoplay,
@ -409,7 +409,7 @@ class SettingsPage extends React.PureComponent<Props, State> {
)} )}
/> />
<FormField {/* <FormField
name="language_select" name="language_select"
type="select" type="select"
label={__('Language')} label={__('Language')}
@ -424,7 +424,7 @@ class SettingsPage extends React.PureComponent<Props, State> {
{languages[language]} {languages[language]}
</option> </option>
))} ))}
</FormField> </FormField> */}
</Form> </Form>
</section> </section>

View file

@ -24,7 +24,6 @@ import {
import { doAuthenticate } from 'lbryinc'; import { doAuthenticate } from 'lbryinc';
import { lbrySettings as config, version as appVersion } from 'package.json'; import { lbrySettings as config, version as appVersion } from 'package.json';
import { push } from 'connected-react-router'; import { push } from 'connected-react-router';
import { whiteListedReducers } from 'store';
// @if TARGET='app' // @if TARGET='app'
const { autoUpdater } = remote.require('electron-updater'); const { autoUpdater } = remote.require('electron-updater');
@ -188,7 +187,7 @@ export function doCancelUpgrade() {
try { try {
upgradeDownloadItem.cancel(); upgradeDownloadItem.cancel();
} catch (err) { } catch (err) {
console.error(err); console.error(err); // eslint-disable-line no-console
} }
} }
@ -328,10 +327,11 @@ export function doDaemonReady() {
export function doClearCache() { export function doClearCache() {
return () => { return () => {
const reducersToClear = whiteListedReducers.filter(reducerKey => reducerKey !== 'tags'); // Need to update this to work with new version of redux-persist
window.cacheStore.purge(reducersToClear); // Leaving for now
// const reducersToClear = whiteListedReducers.filter(reducerKey => reducerKey !== 'tags');
return Promise.resolve(); // window.cacheStore.purge(reducersToClear);
return window.persistor.purge();
}; };
} }

View file

@ -200,7 +200,7 @@ export const doPrepareEdit = (claim: StreamClaim, uri: string, fileInfo: FileLis
fs.accessSync(fileInfo.download_path, fs.constants.R_OK); fs.accessSync(fileInfo.download_path, fs.constants.R_OK);
publishData.filePath = fileInfo.download_path; publishData.filePath = fileInfo.download_path;
} catch (e) { } catch (e) {
console.error(e.name, e.message); console.error(e.name, e.message); // eslint-disable-line no-console
} }
} }
@ -282,8 +282,13 @@ export const doPublish = () => (dispatch: Dispatch, getState: () => {}) => {
publishPayload.license_url = licenseUrl; publishPayload.license_url = licenseUrl;
} }
// Set release time to curret date. On edits, keep original release/transaction time as release_time
if (myClaimForUri && myClaimForUri.value.release_time) { if (myClaimForUri && myClaimForUri.value.release_time) {
publishPayload.release_time = Number(myClaimForUri.value.release_time); publishPayload.release_time = Number(myClaimForUri.value.release_time);
} else if (myClaimForUri && myClaimForUri.timestamp) {
publishPayload.release_time = Number(myClaimForUri.timestamp);
} else {
publishPayload.release_time = Number(Math.round(Date.now() / 1000));
} }
if (channelId) { if (channelId) {

View file

@ -71,7 +71,7 @@ const defaultState: AppState = {
// This action is dispatched any time a user navigates forward or back // This action is dispatched any time a user navigates forward or back
reducers['@@router/LOCATION_CHANGE'] = (state, action) => { reducers['@@router/LOCATION_CHANGE'] = (state, action) => {
const { currentScroll } = state; const { currentScroll } = state;
const scrollHistory = state.scrollHistory.slice(); const scrollHistory = (state.scrollHistory && state.scrollHistory.slice()) || [];
const { action: name } = action.payload; const { action: name } = action.payload;
let newCurrentScroll = currentScroll; let newCurrentScroll = currentScroll;

View file

@ -18,10 +18,6 @@
&:hover { &:hover {
background-color: $lbry-teal-4; background-color: $lbry-teal-4;
} }
svg {
stroke: $lbry-teal-4;
}
} }
// Play/View button that is overlayed ontop of the video player // Play/View button that is overlayed ontop of the video player
@ -62,7 +58,7 @@
.button--link { .button--link {
[data-mode='dark'] & { [data-mode='dark'] & {
color: $lbry-teal-5; color: $lbry-teal-3;
} }
} }

View file

@ -1,3 +1,6 @@
$border-color: rgba($lbry-teal-5, 0.1);
$border-color--dark: var(--dm-color-04);
.claim-list__header { .claim-list__header {
display: flex; display: flex;
align-items: center; align-items: center;
@ -13,7 +16,8 @@
} }
fieldset-section { fieldset-section {
margin: 0; margin-top: 0;
margin-bottom: 0;
} }
// Normal link buttons are too dark on the black file list background // Normal link buttons are too dark on the black file list background
@ -105,7 +109,7 @@
.claim-preview--injected, .claim-preview--injected,
.claim-preview { .claim-preview {
border-bottom: 1px solid rgba($lbry-teal-5, 0.1); border-bottom: 1px solid $border-color;
&:only-of-type { &:only-of-type {
border: none; border: none;
@ -113,7 +117,15 @@
[data-mode='dark'] & { [data-mode='dark'] & {
color: $lbry-white; color: $lbry-white;
border-color: var(--dm-color-04); border-color: $border-color--dark;
}
}
.claim-preview--injected + .claim-preview {
border-top: 1px solid $border-color;
[data-mode='dark'] & {
border-color: $border-color--dark;
} }
} }
@ -190,6 +202,12 @@
} }
} }
.claim-preview--tooltip {
[data-mode='dark'] & {
background-color: $lbry-black;
}
}
.claim-preview-title { .claim-preview-title {
font-weight: 600; font-weight: 600;
margin-right: auto; margin-right: auto;

View file

@ -4,7 +4,11 @@
} }
.comment { .comment {
padding: var(--spacing-medium) 0; display: flex;
flex-direction: column;
padding: 0;
font-size: var(--font-multiplier-small);
padding: var(--spacing-small) 0;
&:not(:last-of-type) { &:not(:last-of-type) {
border-bottom: 1px solid var(--lbry-gray-1); border-bottom: 1px solid var(--lbry-gray-1);
@ -13,58 +17,20 @@
border-color: rgba($lbry-gray-5, 0.2); border-color: rgba($lbry-gray-5, 0.2);
} }
} }
display: flex;
flex-direction: column;
padding: 0;
} }
// .comment__actions-wrap {
// align-items: center;
// display: flex;
// justify-content: space-between;
// width: 4.5rem;
// }
// .comment__action {
// @include hide-text;
// width: 0;
// height: 0;
// transition: border-color 0.2s;
// &.downvote {
// border-top: 2rem solid var(--lbry-orange-3);
// border-right: 1rem solid transparent;
// border-left: 1rem solid transparent;
// &:hover {
// border-top-color: var(--lbry-yellow-3);
// }
// }
// &.upvote {
// border-right: 1rem solid transparent;
// border-bottom: 2rem solid var(--lbry-teal-4);
// border-left: 1rem solid transparent;
// &:hover {
// border-bottom-color: var(--lbry-green-2);
// }
// }
// }
.comment__meta { .comment__meta {
time {
opacity: 0.3;
}
text-overflow: ellipsis; text-overflow: ellipsis;
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
margin-bottom: 1rem;
time {
opacity: 0.3;
}
} }
.comment__message { .comment__message {
white-space: pre-line; white-space: pre-line;
margin-bottom: 1rem;
} }
.comment__author { .comment__author {

View file

@ -83,6 +83,14 @@ radio-element {
margin-bottom: 0; margin-bottom: 0;
margin-left: var(--spacing-miniscule); margin-left: var(--spacing-miniscule);
font-size: var(--font-body); font-size: var(--font-body);
[data-mode='dark'] & {
color: $lbry-gray-1;
&:hover {
color: $lbry-teal-4;
}
}
} }
} }
@ -229,11 +237,8 @@ fieldset-section {
.button, .button,
// specificity needed because of @lbry/component rules // specificity needed because of @lbry/component rules
// @lbry/componentsfixme // @lbry/componentfixme
.button[type='submit']:not(:hover), .button[type='submit']:not(:hover) {
.button[type='submit']:hover {
border-color: $lbry-black;
border-radius: var(--button-radius);
border-top-left-radius: 0; border-top-left-radius: 0;
border-bottom-left-radius: 0; border-bottom-left-radius: 0;
border-color: $lbry-black; border-color: $lbry-black;

View file

@ -3,7 +3,6 @@
position: fixed; position: fixed;
top: 0; top: 0;
width: 100%; width: 100%;
padding: 0 var(--spacing-large);
background-color: $lbry-white; background-color: $lbry-white;
border-bottom: 1px solid $lbry-gray-1; border-bottom: 1px solid $lbry-gray-1;
box-shadow: var(--card-box-shadow) $lbry-gray-1; box-shadow: var(--card-box-shadow) $lbry-gray-1;
@ -27,6 +26,7 @@
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
margin: auto; margin: auto;
padding: 0 var(--spacing-large);
} }
.header__navigation { .header__navigation {
@ -34,7 +34,8 @@
justify-content: space-between; justify-content: space-between;
&:last-of-type { &:last-of-type {
width: calc(var(--side-nav-width) + var(--spacing-medium)); width: var(--side-nav-width);
@media (max-width: 600px) { @media (max-width: 600px) {
display: none; display: none;
} }

View file

@ -1,4 +1,6 @@
.main-wrapper { .main-wrapper {
position: relative;
[data-mode='dark'] & { [data-mode='dark'] & {
background-color: var(--dm-color-08); background-color: var(--dm-color-08);
} }
@ -7,20 +9,16 @@
.main-wrapper__inner { .main-wrapper__inner {
display: flex; display: flex;
align-items: flex-start; align-items: flex-start;
min-height: 100vh; justify-content: space-between;
max-width: var(--page-max-width); max-width: var(--page-max-width);
margin-left: auto; margin-left: auto;
margin-right: auto; margin-right: auto;
padding: 0 var(--spacing-large); margin-top: var(--header-height);
padding-bottom: var(--spacing-main-padding); padding: var(--spacing-large);
} }
.main { .main {
min-width: 0;
position: relative;
width: calc(100% - var(--side-nav-width) - var(--spacing-main-padding)); width: calc(100% - var(--side-nav-width) - var(--spacing-main-padding));
margin-top: calc(var(--header-height) + var(--spacing-large));
margin-right: var(--spacing-main-padding);
@media (max-width: 600px) { @media (max-width: 600px) {
width: 100%; width: 100%;
@ -51,8 +49,14 @@
text-align: center; text-align: center;
} }
.main--launching {
width: 100vw;
height: 100vh;
background-color: var(--color-background);
}
.main__status { .main__status {
@extend .help; @extend .card__subtitle;
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
background-color: $lbry-teal-4; background-color: $lbry-teal-4;
@ -64,5 +68,6 @@
[data-mode='dark'] & { [data-mode='dark'] & {
background-color: $lbry-teal-5; background-color: $lbry-teal-5;
color: $lbry-white;
} }
} }

View file

@ -1,6 +1,7 @@
.navigation { .navigation {
width: var(--side-nav-width); width: var(--side-nav-width);
font-size: var(--font-body); font-size: var(--font-body);
// padding-top: 100px;
@media (max-width: 600px) { @media (max-width: 600px) {
display: none; display: none;
@ -11,7 +12,6 @@
@extend .ul--no-style; @extend .ul--no-style;
flex-direction: column; flex-direction: column;
align-items: flex-start; align-items: flex-start;
position: relative;
list-style: none; list-style: none;
} }

View file

@ -28,8 +28,8 @@ td {
} }
.table__item--actionable { .table__item--actionable {
.button svg { span {
top: 3px; vertical-align: top;
} }
} }

View file

@ -7,7 +7,7 @@
flex: 1; flex: 1;
position: relative; position: relative;
z-index: 1; z-index: 1;
margin-right: calc(var(--spacing-large)); margin-right: var(--spacing-main-padding);
font-size: var(--font-label); font-size: var(--font-label);
@media (max-width: 600px) { @media (max-width: 600px) {

View file

@ -70,9 +70,11 @@
} }
.menu__title { .menu__title {
padding: var(--spacing-large) 0; // padding: var(--spacing-large) 0;
padding-left: var(--spacing-medium); &:not(:last-of-type) {
padding-right: 0; margin-right: var(--spacing-medium);
}
// padding-right: 0;
span { span {
margin-left: var(--spacing-small); margin-left: var(--spacing-small);

View file

@ -28,7 +28,7 @@
@extend .button--link; @extend .button--link;
margin-right: var(--spacing-large); margin-right: var(--spacing-large);
padding: 5px 0; padding: 5px 0;
font-size: var(--font-title); font-size: var(--font-multiplier-large);
color: $lbry-white; color: $lbry-white;
position: relative; position: relative;

View file

@ -84,7 +84,7 @@ $large-breakpoint: 1921px;
// Image // Image
--thumbnail-preview-height: 100px; --thumbnail-preview-height: 100px;
--thumbnail-preview-width: 177px; --thumbnail-preview-width: 177px;
--cover-photo-height: 160px; --cover-photo-height: 180px;
--channel-thumbnail-width: 10rem; --channel-thumbnail-width: 10rem;
--channel-thumbnail-width--small: 4rem; --channel-thumbnail-width--small: 4rem;
--file-list-thumbnail-width: 10rem; --file-list-thumbnail-width: 10rem;

View file

@ -1,4 +1,5 @@
import { persistStore, autoRehydrate } from 'redux-persist'; import { persistStore, persistReducer } from 'redux-persist';
import autoMergeLevel2 from 'redux-persist/lib/stateReconciler/autoMergeLevel2';
import createCompressor from 'redux-persist-transform-compress'; import createCompressor from 'redux-persist-transform-compress';
import createFilter from 'redux-persist-transform-filter'; import createFilter from 'redux-persist-transform-filter';
import localForage from 'localforage'; import localForage from 'localforage';
@ -36,34 +37,6 @@ function enableBatching(reducer) {
}; };
} }
let history;
// @if TARGET='app'
history = createHashHistory();
// @endif
// @if TARGET='web'
history = createBrowserHistory();
// @endif
const bulkThunk = createBulkThunkMiddleware();
const middleware = [routerMiddleware(history), thunk, bulkThunk];
const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
const store = createStore(
enableBatching(createRootReducer(history)),
{}, // initial state
composeEnhancers(
autoRehydrate({
log: app.env === 'development',
}),
applyMiddleware(...middleware)
)
);
const compressor = createCompressor();
// Removing claims from redux-persist to see if it solves https://github.com/lbryio/lbry-desktop/issues/1983
// We were caching so much data the app was locking up
// We can't add this back until we can perform this in a non-blocking way
// const saveClaimsFilter = createFilter('claims', ['byId', 'claimsByUri']);
const contentFilter = createFilter('content', ['positions', 'history']); const contentFilter = createFilter('content', ['positions', 'history']);
const fileInfoFilter = createFilter('fileInfo', [ const fileInfoFilter = createFilter('fileInfo', [
'fileListPublishedSort', 'fileListPublishedSort',
@ -79,7 +52,7 @@ const whiteListedReducers = [
// @if TARGET='app' // @if TARGET='app'
'publish', 'publish',
'wallet', 'wallet',
'fileInfo', // 'fileInfo',
// @endif // @endif
'content', 'content',
'subscriptions', 'subscriptions',
@ -88,29 +61,48 @@ const whiteListedReducers = [
'tags', 'tags',
]; ];
const transforms = [
// @if TARGET='app'
walletFilter,
contentFilter,
fileInfoFilter,
// @endif
appFilter,
searchFilter,
tagsFilter,
createCompressor(),
];
const persistOptions = { const persistOptions = {
key: 'v0',
storage: localForage,
stateReconciler: autoMergeLevel2,
whitelist: whiteListedReducers, whitelist: whiteListedReducers,
// Order is important. Needs to be compressed last or other transforms can't // Order is important. Needs to be compressed last or other transforms can't
// read the data // read the data
transforms: [ transforms,
// @if TARGET='app'
walletFilter,
contentFilter,
fileInfoFilter,
// @endif
appFilter,
searchFilter,
tagsFilter,
compressor,
],
debounce: 5000,
storage: localForage,
}; };
window.cacheStore = persistStore(store, persistOptions, err => { let history;
if (err) { // @if TARGET='app'
console.error('Unable to load saved settings'); history = createHashHistory();
} // @endif
}); // @if TARGET='web'
history = createBrowserHistory();
// @endif
export { store, history, whiteListedReducers }; const rootReducer = createRootReducer(history);
const persistedReducer = persistReducer(persistOptions, rootReducer);
const bulkThunk = createBulkThunkMiddleware();
const middleware = [routerMiddleware(history), thunk, bulkThunk];
const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
const store = createStore(
enableBatching(persistedReducer),
{}, // initial state
composeEnhancers(applyMiddleware(...middleware))
);
const persistor = persistStore(store);
window.persistor = persistor;
export { store, persistor, history, whiteListedReducers };

View file

@ -291,5 +291,27 @@
"Tags You Follow": "Tags You Follow", "Tags You Follow": "Tags You Follow",
"Channels You Follow": "Channels You Follow", "Channels You Follow": "Channels You Follow",
"Everyone": "Everyone", "Everyone": "Everyone",
"View tag": "View tag" "View tag": "View tag",
"Customize Your Tags": "Customize Your Tags",
"Find New Channels": "Find New Channels",
"The tags you follow will change what's trending for you.": "The tags you follow will change what's trending for you.",
"Remove tag": "Remove tag",
"Find New Tags": "Find New Tags",
"Search for more tags": "Search for more tags",
"Add tag": "Add tag",
"publishes": "publishes",
"Following": "Following",
"This file is downloaded.": "This file is downloaded.",
"Featured content. Earn rewards for watching.": "Featured content. Earn rewards for watching.",
"You are subscribed to this channel.": "You are subscribed to this channel.",
"Follow": "Follow",
"Show mature content": "Show mature content",
"Mature content may include nudity, intense sexuality, profanity, or other adult content. By displaying NSFW content, you are affirming you are of legal age to view mature content in your country or jurisdiction. ": "Mature content may include nudity, intense sexuality, profanity, or other adult content. By displaying NSFW content, you are affirming you are of legal age to view mature content in your country or jurisdiction. ",
"Share Channel": "Share Channel",
"This channel hasn't uploaded anything.": "This channel hasn't uploaded anything.",
"Go to page:": "Go to page:",
"Contact": "Contact",
"Site": "Site",
"Claim sequence must be a number.": "Claim sequence must be a number.",
"No modifier provided after separator %s.": "No modifier provided after separator %s."
} }

View file

@ -23,7 +23,7 @@ console.log(ifProduction('production', 'development'));
let baseConfig = { let baseConfig = {
mode: ifProduction('production', 'development'), mode: ifProduction('production', 'development'),
devtool: ifProduction(false, 'inline-cheap-source-map'), devtool: ifProduction(false, 'cheap-module-eval-source-map'),
optimization: { optimization: {
minimizer: [ minimizer: [
new TerserPlugin({ new TerserPlugin({

View file

@ -6851,7 +6851,7 @@ locate-path@^3.0.0:
p-locate "^3.0.0" p-locate "^3.0.0"
path-exists "^3.0.0" path-exists "^3.0.0"
lodash-es@^4.17.14, lodash-es@^4.17.4, lodash-es@^4.2.1: lodash-es@^4.17.14, lodash-es@^4.2.1:
version "4.17.14" version "4.17.14"
resolved "https://registry.yarnpkg.com/lodash-es/-/lodash-es-4.17.14.tgz#12a95a963cc5955683cee3b74e85458954f37ecc" resolved "https://registry.yarnpkg.com/lodash-es/-/lodash-es-4.17.14.tgz#12a95a963cc5955683cee3b74e85458954f37ecc"
integrity sha512-7zchRrGa8UZXjD/4ivUWP1867jDkhzTG2c/uj739utSd7O/pFFdxspCemIFKEEjErbcqRzn8nKnGsi7mvTgRPA== integrity sha512-7zchRrGa8UZXjD/4ivUWP1867jDkhzTG2c/uj739utSd7O/pFFdxspCemIFKEEjErbcqRzn8nKnGsi7mvTgRPA==
@ -9745,14 +9745,10 @@ redux-persist-transform-filter@0.0.16:
lodash.set "^4.3.2" lodash.set "^4.3.2"
lodash.unset "^4.5.2" lodash.unset "^4.5.2"
redux-persist@^4.8.0: redux-persist@^5.10.0:
version "4.10.2" version "5.10.0"
resolved "https://registry.yarnpkg.com/redux-persist/-/redux-persist-4.10.2.tgz#8efdb16cfe882c521a78a6d0bfdfef2437f49f96" resolved "https://registry.yarnpkg.com/redux-persist/-/redux-persist-5.10.0.tgz#5d8d802c5571e55924efc1c3a9b23575283be62b"
integrity sha512-U+e0ieMGC69Zr72929iJW40dEld7Mflh6mu0eJtVMLGfMq/aJqjxUM1hzyUWMR1VUyAEEdPHuQmeq5ti9krIgg== integrity sha512-sSJAzNq7zka3qVHKce1hbvqf0Vf5DuTVm7dr4GtsqQVOexnrvbV47RWFiPxQ8fscnyiuWyD2O92DOxPl0tGCRg==
dependencies:
json-stringify-safe "^5.0.1"
lodash "^4.17.4"
lodash-es "^4.17.4"
redux-thunk@^2.2.0: redux-thunk@^2.2.0:
version "2.3.0" version "2.3.0"