this got out of hand
This commit is contained in:
parent
d557a37c01
commit
bbd9591f3b
37 changed files with 290 additions and 270 deletions
|
@ -160,7 +160,7 @@
|
|||
"react-spring": "^8.0.20",
|
||||
"react-sticky-box": "^0.8.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-filter": "0.0.16",
|
||||
"redux-thunk": "^2.2.0",
|
||||
|
|
|
@ -33,7 +33,7 @@ function ChannelContent(props: Props) {
|
|||
</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)} />}
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
import React, { useState } from 'react';
|
||||
import { parseURI } from 'lbry-redux';
|
||||
import { Form, FormField } from 'component/common/form';
|
||||
|
||||
import Button from 'component/button';
|
||||
import SelectAsset from 'component/selectAsset';
|
||||
import TagSelect from 'component/tagsSelect';
|
||||
|
||||
|
@ -23,6 +23,7 @@ type Props = {
|
|||
updateChannel: any => void,
|
||||
updateThumb: string => void,
|
||||
updateCover: string => void,
|
||||
setEditing: boolean => void,
|
||||
};
|
||||
|
||||
function ChannelForm(props: Props) {
|
||||
|
@ -38,6 +39,7 @@ function ChannelForm(props: Props) {
|
|||
locations,
|
||||
languages,
|
||||
amount,
|
||||
setEditing,
|
||||
updateChannel,
|
||||
updateThumb,
|
||||
updateCover,
|
||||
|
@ -99,11 +101,11 @@ function ChannelForm(props: Props) {
|
|||
// TODO clear and bail after submit
|
||||
return (
|
||||
<section className={'card--section'}>
|
||||
<div className="help">
|
||||
<div className="card__subtitle">
|
||||
<p>{__('We can explain...')}</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>
|
||||
</div>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// @flow
|
||||
import { MAIN_WRAPPER_CLASS } from 'component/app/view';
|
||||
import type { Node } from 'react';
|
||||
import React, { useEffect } from 'react';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import classnames from 'classnames';
|
||||
import ClaimPreview from 'component/claimPreview';
|
||||
import Spinner from 'component/spinner';
|
||||
|
@ -23,6 +23,7 @@ type Props = {
|
|||
onScrollBottom?: any => void,
|
||||
page?: number,
|
||||
pageSize?: number,
|
||||
id?: string,
|
||||
// If using the default header, this is a unique ID needed to persist the state of the filter setting
|
||||
persistedStorageKey?: string,
|
||||
};
|
||||
|
@ -40,7 +41,10 @@ export default function ClaimList(props: Props) {
|
|||
header,
|
||||
onScrollBottom,
|
||||
pageSize,
|
||||
page,
|
||||
id,
|
||||
} = props;
|
||||
const [scrollBottomCbMap, setScrollBottomCbMap] = useState({});
|
||||
const [currentSort, setCurrentSort] = usePersistedState(persistedStorageKey, SORT_NEW);
|
||||
const urisLength = (uris && uris.length) || 0;
|
||||
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);
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
setScrollBottomCbMap({});
|
||||
}, [id]);
|
||||
|
||||
useEffect(() => {
|
||||
function handleScroll(e) {
|
||||
if (pageSize && onScrollBottom) {
|
||||
if (page && pageSize && onScrollBottom && !scrollBottomCbMap[page]) {
|
||||
const x = document.querySelector(`.${MAIN_WRAPPER_CLASS}`);
|
||||
|
||||
if (x && window.scrollY + window.innerHeight >= x.offsetHeight) {
|
||||
if (!loading && urisLength >= pageSize) {
|
||||
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);
|
||||
};
|
||||
}
|
||||
}, [loading, onScrollBottom, urisLength, pageSize]);
|
||||
}, [loading, onScrollBottom, urisLength, pageSize, page, setScrollBottomCbMap]);
|
||||
|
||||
return (
|
||||
<section
|
||||
|
@ -103,7 +114,7 @@ export default function ClaimList(props: Props) {
|
|||
{sortedUris.map((uri, index) => (
|
||||
<React.Fragment key={uri}>
|
||||
<ClaimPreview uri={uri} type={type} />
|
||||
{index === 4 && injectedItem && <li className="claim-preview--injected">{injectedItem}</li>}
|
||||
{index === 4 && injectedItem && injectedItem}
|
||||
</React.Fragment>
|
||||
))}
|
||||
</ul>
|
||||
|
|
|
@ -105,7 +105,10 @@ function ClaimListDiscover(props: Props) {
|
|||
|
||||
const claimSearchCacheQuery = buildClaimSearchCacheQuery(options);
|
||||
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
|
||||
const optionsStringForEffect = JSON.stringify(options);
|
||||
|
||||
|
@ -211,6 +214,7 @@ function ClaimListDiscover(props: Props) {
|
|||
return (
|
||||
<div className="card">
|
||||
<ClaimList
|
||||
id={claimSearchCacheQuery}
|
||||
loading={loading}
|
||||
uris={uris}
|
||||
injectedItem={personalSort === SEARCH_SORT_YOU && injectedItem}
|
||||
|
|
|
@ -64,7 +64,8 @@ function ClaimPreview(props: Props) {
|
|||
const abandoned = !isResolvingUri && !claim;
|
||||
const claimsInChannel = (claim && claim.meta.claims_in_channel) || 0;
|
||||
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;
|
||||
try {
|
||||
|
@ -134,10 +135,11 @@ function ClaimPreview(props: Props) {
|
|||
onClick={pending || type === 'inline' ? undefined : onClick}
|
||||
onContextMenu={handleContextMenu}
|
||||
className={classnames('claim-preview', {
|
||||
'claim-preview--small': minimal,
|
||||
'claim-preview--small': type === 'small' || type === 'tooltip',
|
||||
'claim-preview--large': type === 'large',
|
||||
'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,
|
||||
})}
|
||||
>
|
||||
|
@ -147,7 +149,7 @@ function ClaimPreview(props: Props) {
|
|||
<div className="claim-preview-title">
|
||||
{claim ? <TruncatedText text={title || claim.name} lines={1} /> : <span>{__('Nothing here')}</span>}
|
||||
</div>
|
||||
{!minimal && (
|
||||
{!hideActions && (
|
||||
<div>
|
||||
{isChannel && <SubscribeButton uri={uri.startsWith('lbry://') ? uri : `lbry://${uri}`} />}
|
||||
{!isChannel && <FileProperties uri={uri} />}
|
||||
|
@ -161,7 +163,7 @@ function ClaimPreview(props: Props) {
|
|||
{!isResolvingUri && (
|
||||
<div>
|
||||
{claim ? (
|
||||
<UriIndicator uri={uri} link addTooltip={!minimal} />
|
||||
<UriIndicator uri={uri} link addTooltip={includeChannelTooltip} />
|
||||
) : (
|
||||
<Fragment>
|
||||
<div>{__('Publish something and claim this spot!')}</div>
|
||||
|
|
|
@ -16,22 +16,17 @@ function Comment(props: Props) {
|
|||
return (
|
||||
<li className="comment">
|
||||
<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}>
|
||||
{relativeDate(timePosted)}
|
||||
</time>
|
||||
</div>
|
||||
|
||||
<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>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -187,8 +187,8 @@ export const icons = {
|
|||
),
|
||||
[ICONS.COPY]: buildIcon(
|
||||
<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="8" y="2" width="8" height="4" rx="1" ry="1" />
|
||||
<rect x="9" y="9" width="13" height="13" rx="2" ry="2" />
|
||||
<path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1" />
|
||||
</g>
|
||||
),
|
||||
[ICONS.REMOVE]: buildIcon(
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
// @flow
|
||||
import React from 'react';
|
||||
import Button from 'component/button';
|
||||
import classnames from 'classnames';
|
||||
|
||||
type Props = {
|
||||
numberOfNsfwClaims: number,
|
||||
|
@ -14,7 +15,7 @@ export default (props: Props) => {
|
|||
return (
|
||||
obscureNsfw &&
|
||||
Boolean(numberOfNsfwClaims) && (
|
||||
<div className={className || 'help'}>
|
||||
<div className={classnames('card--section', className || 'help')}>
|
||||
{numberOfNsfwClaims} {numberOfNsfwClaims > 1 ? __('files') : __('file')} {__('hidden due to your')}{' '}
|
||||
<Button button="link" navigate="/$/settings" label={__('content viewing preferences')} />.
|
||||
</div>
|
||||
|
|
|
@ -24,7 +24,7 @@ function SideBar(props: Props) {
|
|||
}
|
||||
|
||||
return (
|
||||
<StickyBox offsetBottom={40} offsetTop={90}>
|
||||
<StickyBox offsetTop={100} offsetBottom={20}>
|
||||
<nav className="navigation">
|
||||
<ul className="navigation-links">
|
||||
{[
|
||||
|
|
|
@ -21,6 +21,7 @@ type Props = {
|
|||
tagsChosen?: Array<Tag>,
|
||||
onSelect?: Tag => void,
|
||||
onRemove?: Tag => void,
|
||||
className?: string,
|
||||
};
|
||||
|
||||
const tagsAnimation = {
|
||||
|
@ -41,6 +42,7 @@ export default function TagSelect(props: Props) {
|
|||
onSelect,
|
||||
onRemove,
|
||||
suggestMature,
|
||||
className,
|
||||
} = props;
|
||||
const [hasClosed, setHasClosed] = usePersistedState('tag-select:has-closed', false);
|
||||
const tagsToDisplay = tagsChosen || followedTags;
|
||||
|
@ -65,7 +67,7 @@ export default function TagSelect(props: Props) {
|
|||
|
||||
return (
|
||||
((showClose && !hasClosed) || !showClose) && (
|
||||
<div>
|
||||
<div className={className}>
|
||||
{title !== false && (
|
||||
<h2 className="card__title">
|
||||
{title}
|
||||
|
|
|
@ -72,8 +72,9 @@ class TransactionListItem extends React.PureComponent<Props> {
|
|||
<td className="table__item--actionable">
|
||||
<span>{this.capitalize(type)}</span> {isRevokeable && this.getLink(type)}
|
||||
</td>
|
||||
<td className="table__item--actionable">
|
||||
{reward ? <span>{reward.reward_title}</span> : <Button button="link" navigate={uri} label={claimName} />}
|
||||
<td>
|
||||
{reward && <span>{reward.reward_title}</span>}
|
||||
{name && claimId && <Button button="link" navigate={uri} label={claimName} />}
|
||||
</td>
|
||||
|
||||
<td>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
import * as icons from 'constants/icons';
|
||||
import * as MODALS from 'constants/modal_types';
|
||||
import * as React from 'react';
|
||||
import { FormField, Form } from 'component/common/form';
|
||||
import { FormField } from 'component/common/form';
|
||||
import Button from 'component/button';
|
||||
import FileExporter from 'component/common/file-exporter';
|
||||
import { TRANSACTIONS } from 'lbry-redux';
|
||||
|
@ -84,7 +84,7 @@ class TransactionList extends React.PureComponent<Props> {
|
|||
</header>
|
||||
{!slim && !!transactions.length && (
|
||||
<header className="table__header">
|
||||
<div className="card__actions">
|
||||
<div className="card__actions--between">
|
||||
<FileExporter
|
||||
data={transactionList}
|
||||
label={__('Export')}
|
||||
|
@ -93,29 +93,27 @@ class TransactionList extends React.PureComponent<Props> {
|
|||
defaultPath={__('lbry-transactions-history')}
|
||||
/>
|
||||
|
||||
<Form>
|
||||
<FormField
|
||||
type="select"
|
||||
name="file-sort"
|
||||
value={filterSetting || TRANSACTIONS.ALL}
|
||||
onChange={this.handleFilterChanged}
|
||||
label={__('Show')}
|
||||
postfix={
|
||||
<Button
|
||||
button="link"
|
||||
icon={icons.HELP}
|
||||
href="https://lbry.com/faq/transaction-types"
|
||||
title={__('Help')}
|
||||
/>
|
||||
}
|
||||
>
|
||||
{transactionTypes.map(tt => (
|
||||
<option key={tt} value={tt}>
|
||||
{__(`${this.capitalize(tt)}`)}
|
||||
</option>
|
||||
))}
|
||||
</FormField>
|
||||
</Form>
|
||||
<FormField
|
||||
type="select"
|
||||
name="file-sort"
|
||||
value={filterSetting || TRANSACTIONS.ALL}
|
||||
onChange={this.handleFilterChanged}
|
||||
label={__('Show')}
|
||||
postfix={
|
||||
<Button
|
||||
button="link"
|
||||
icon={icons.HELP}
|
||||
href="https://lbry.com/faq/transaction-types"
|
||||
title={__('Help')}
|
||||
/>
|
||||
}
|
||||
>
|
||||
{transactionTypes.map(tt => (
|
||||
<option key={tt} value={tt}>
|
||||
{__(`${this.capitalize(tt)}`)}
|
||||
</option>
|
||||
))}
|
||||
</FormField>
|
||||
</div>
|
||||
</header>
|
||||
)}
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 32 KiB After Width: | Height: | Size: 23 KiB |
|
@ -78,7 +78,7 @@ class WalletSend extends React.PureComponent<Props> {
|
|||
</fieldset-group>
|
||||
<div className="card__actions">
|
||||
<Button
|
||||
button="inverse"
|
||||
button="primary"
|
||||
type="submit"
|
||||
label={__('Send')}
|
||||
disabled={
|
||||
|
|
118
src/ui/index.jsx
118
src/ui/index.jsx
|
@ -8,7 +8,7 @@ import { ipcRenderer, remote, shell } from 'electron';
|
|||
import * as ACTIONS from 'constants/action_types';
|
||||
// @endif
|
||||
import * as MODALS from 'constants/modal_types';
|
||||
import React from 'react';
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import { Provider } from 'react-redux';
|
||||
import { doConditionalAuthNavigate, doDaemonReady, doAutoUpdate, doOpenModal, doHideModal } from 'redux/actions/app';
|
||||
|
@ -21,13 +21,14 @@ import {
|
|||
doBlackListedOutpointsSubscribe,
|
||||
doFilteredOutpointsSubscribe,
|
||||
} from 'lbryinc';
|
||||
import { store, history } from 'store';
|
||||
import { store, persistor, history } from 'store';
|
||||
import pjson from 'package.json';
|
||||
import app from './app';
|
||||
import doLogWarningConsoleMessage from './logWarningConsoleMessage';
|
||||
import { ConnectedRouter, push } from 'connected-react-router';
|
||||
import cookie from 'cookie';
|
||||
import { formatLbryUriForWeb } from 'util/uri';
|
||||
import { PersistGate } from 'redux-persist/integration/react';
|
||||
|
||||
// Import our app styles
|
||||
// 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 = () => {
|
||||
// @if TARGET='app'
|
||||
moment.locale(remote.app.getLocale());
|
||||
function AppWrapper() {
|
||||
const haveLaunched = window.sessionStorage.getItem('loaded') === 'y';
|
||||
const [readyToLaunch, setReadyToLaunch] = useState(haveLaunched || IS_WEB);
|
||||
|
||||
autoUpdater.on('error', error => {
|
||||
console.error(error.message);
|
||||
});
|
||||
useEffect(() => {
|
||||
moment.locale(remote.app.getLocale());
|
||||
|
||||
if (['win32', 'darwin'].includes(process.platform)) {
|
||||
autoUpdater.on('update-available', () => {
|
||||
console.log('Update available');
|
||||
autoUpdater.on('error', error => {
|
||||
console.error(error.message); // eslint-disable-line no-console
|
||||
});
|
||||
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());
|
||||
// @endif
|
||||
if (['win32', 'darwin'].includes(process.platform)) {
|
||||
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());
|
||||
app.store.dispatch(doBlackListedOutpointsSubscribe());
|
||||
app.store.dispatch(doFilteredOutpointsSubscribe());
|
||||
useEffect(() => {
|
||||
if (readyToLaunch) {
|
||||
app.store.dispatch(doUpdateIsNightAsync());
|
||||
app.store.dispatch(doDaemonReady());
|
||||
app.store.dispatch(doInitLanguage());
|
||||
app.store.dispatch(doBlackListedOutpointsSubscribe());
|
||||
app.store.dispatch(doFilteredOutpointsSubscribe());
|
||||
}
|
||||
|
||||
function onDaemonReady() {
|
||||
// @if TARGET='app'
|
||||
window.sessionStorage.setItem('loaded', 'y'); // once we've made it here once per session, we don't need to show splash again
|
||||
// @endif
|
||||
window.sessionStorage.setItem('loaded', 'y');
|
||||
}, [readyToLaunch, haveLaunched]);
|
||||
|
||||
app.store.dispatch(doDaemonReady());
|
||||
ReactDOM.render(
|
||||
<Provider store={store}>
|
||||
<ConnectedRouter history={history}>
|
||||
<ErrorBoundary>
|
||||
<App />
|
||||
<SnackBar />
|
||||
</ErrorBoundary>
|
||||
</ConnectedRouter>
|
||||
</Provider>,
|
||||
document.getElementById('app')
|
||||
);
|
||||
}
|
||||
return (
|
||||
<Provider store={store}>
|
||||
<PersistGate persistor={persistor} loading={<div className="main--launching" />}>
|
||||
<div>
|
||||
{readyToLaunch ? (
|
||||
<ConnectedRouter history={history}>
|
||||
<ErrorBoundary>
|
||||
<App />
|
||||
<SnackBar />
|
||||
</ErrorBoundary>
|
||||
</ConnectedRouter>
|
||||
) : (
|
||||
<SplashScreen
|
||||
authenticate={() => app.store.dispatch(doAuthenticate(pjson.version))}
|
||||
onReadyToLaunch={() => setReadyToLaunch(true)}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</PersistGate>
|
||||
</Provider>
|
||||
);
|
||||
}
|
||||
|
||||
// @if TARGET='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();
|
||||
ReactDOM.render(<AppWrapper />, document.getElementById('app'));
|
||||
|
|
|
@ -19,7 +19,9 @@ function DiscoverPage(props: Props) {
|
|||
personalView
|
||||
tags={followedTags.map(tag => tag.name)}
|
||||
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>
|
||||
);
|
||||
|
|
|
@ -30,8 +30,8 @@ type Props = {
|
|||
showNsfw: boolean,
|
||||
instantPurchaseEnabled: boolean,
|
||||
instantPurchaseMax: Price,
|
||||
currentLanguage: string,
|
||||
languages: {},
|
||||
// currentLanguage: string,
|
||||
// languages: {},
|
||||
currentTheme: string,
|
||||
themes: Array<string>,
|
||||
automaticDarkModeEnabled: boolean,
|
||||
|
@ -140,8 +140,8 @@ class SettingsPage extends React.PureComponent<Props, State> {
|
|||
instantPurchaseEnabled,
|
||||
instantPurchaseMax,
|
||||
currentTheme,
|
||||
currentLanguage,
|
||||
languages,
|
||||
// currentLanguage,
|
||||
// languages,
|
||||
themes,
|
||||
automaticDarkModeEnabled,
|
||||
autoplay,
|
||||
|
@ -409,7 +409,7 @@ class SettingsPage extends React.PureComponent<Props, State> {
|
|||
)}
|
||||
/>
|
||||
|
||||
<FormField
|
||||
{/* <FormField
|
||||
name="language_select"
|
||||
type="select"
|
||||
label={__('Language')}
|
||||
|
@ -424,7 +424,7 @@ class SettingsPage extends React.PureComponent<Props, State> {
|
|||
{languages[language]}
|
||||
</option>
|
||||
))}
|
||||
</FormField>
|
||||
</FormField> */}
|
||||
</Form>
|
||||
</section>
|
||||
|
||||
|
|
|
@ -24,7 +24,6 @@ import {
|
|||
import { doAuthenticate } from 'lbryinc';
|
||||
import { lbrySettings as config, version as appVersion } from 'package.json';
|
||||
import { push } from 'connected-react-router';
|
||||
import { whiteListedReducers } from 'store';
|
||||
|
||||
// @if TARGET='app'
|
||||
const { autoUpdater } = remote.require('electron-updater');
|
||||
|
@ -188,7 +187,7 @@ export function doCancelUpgrade() {
|
|||
try {
|
||||
upgradeDownloadItem.cancel();
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
console.error(err); // eslint-disable-line no-console
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -328,10 +327,11 @@ export function doDaemonReady() {
|
|||
|
||||
export function doClearCache() {
|
||||
return () => {
|
||||
const reducersToClear = whiteListedReducers.filter(reducerKey => reducerKey !== 'tags');
|
||||
window.cacheStore.purge(reducersToClear);
|
||||
|
||||
return Promise.resolve();
|
||||
// Need to update this to work with new version of redux-persist
|
||||
// Leaving for now
|
||||
// const reducersToClear = whiteListedReducers.filter(reducerKey => reducerKey !== 'tags');
|
||||
// window.cacheStore.purge(reducersToClear);
|
||||
return window.persistor.purge();
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -200,7 +200,7 @@ export const doPrepareEdit = (claim: StreamClaim, uri: string, fileInfo: FileLis
|
|||
fs.accessSync(fileInfo.download_path, fs.constants.R_OK);
|
||||
publishData.filePath = fileInfo.download_path;
|
||||
} 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;
|
||||
}
|
||||
|
||||
// Set release time to curret date. On edits, keep original release/transaction time as release_time
|
||||
if (myClaimForUri && 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) {
|
||||
|
|
|
@ -71,7 +71,7 @@ const defaultState: AppState = {
|
|||
// This action is dispatched any time a user navigates forward or back
|
||||
reducers['@@router/LOCATION_CHANGE'] = (state, action) => {
|
||||
const { currentScroll } = state;
|
||||
const scrollHistory = state.scrollHistory.slice();
|
||||
const scrollHistory = (state.scrollHistory && state.scrollHistory.slice()) || [];
|
||||
const { action: name } = action.payload;
|
||||
|
||||
let newCurrentScroll = currentScroll;
|
||||
|
|
|
@ -18,10 +18,6 @@
|
|||
&:hover {
|
||||
background-color: $lbry-teal-4;
|
||||
}
|
||||
|
||||
svg {
|
||||
stroke: $lbry-teal-4;
|
||||
}
|
||||
}
|
||||
|
||||
// Play/View button that is overlayed ontop of the video player
|
||||
|
@ -62,7 +58,7 @@
|
|||
|
||||
.button--link {
|
||||
[data-mode='dark'] & {
|
||||
color: $lbry-teal-5;
|
||||
color: $lbry-teal-3;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
$border-color: rgba($lbry-teal-5, 0.1);
|
||||
$border-color--dark: var(--dm-color-04);
|
||||
|
||||
.claim-list__header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
@ -13,7 +16,8 @@
|
|||
}
|
||||
|
||||
fieldset-section {
|
||||
margin: 0;
|
||||
margin-top: 0;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
// Normal link buttons are too dark on the black file list background
|
||||
|
@ -105,7 +109,7 @@
|
|||
|
||||
.claim-preview--injected,
|
||||
.claim-preview {
|
||||
border-bottom: 1px solid rgba($lbry-teal-5, 0.1);
|
||||
border-bottom: 1px solid $border-color;
|
||||
|
||||
&:only-of-type {
|
||||
border: none;
|
||||
|
@ -113,7 +117,15 @@
|
|||
|
||||
[data-mode='dark'] & {
|
||||
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 {
|
||||
font-weight: 600;
|
||||
margin-right: auto;
|
||||
|
|
|
@ -4,7 +4,11 @@
|
|||
}
|
||||
|
||||
.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) {
|
||||
border-bottom: 1px solid var(--lbry-gray-1);
|
||||
|
@ -13,58 +17,20 @@
|
|||
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 {
|
||||
time {
|
||||
opacity: 0.3;
|
||||
}
|
||||
text-overflow: ellipsis;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 1rem;
|
||||
|
||||
time {
|
||||
opacity: 0.3;
|
||||
}
|
||||
}
|
||||
|
||||
.comment__message {
|
||||
white-space: pre-line;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.comment__author {
|
||||
|
|
|
@ -83,6 +83,14 @@ radio-element {
|
|||
margin-bottom: 0;
|
||||
margin-left: var(--spacing-miniscule);
|
||||
font-size: var(--font-body);
|
||||
|
||||
[data-mode='dark'] & {
|
||||
color: $lbry-gray-1;
|
||||
|
||||
&:hover {
|
||||
color: $lbry-teal-4;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -229,11 +237,8 @@ fieldset-section {
|
|||
|
||||
.button,
|
||||
// specificity needed because of @lbry/component rules
|
||||
// @lbry/componentsfixme
|
||||
.button[type='submit']:not(:hover),
|
||||
.button[type='submit']:hover {
|
||||
border-color: $lbry-black;
|
||||
border-radius: var(--button-radius);
|
||||
// @lbry/componentfixme
|
||||
.button[type='submit']:not(:hover) {
|
||||
border-top-left-radius: 0;
|
||||
border-bottom-left-radius: 0;
|
||||
border-color: $lbry-black;
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
position: fixed;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
padding: 0 var(--spacing-large);
|
||||
background-color: $lbry-white;
|
||||
border-bottom: 1px solid $lbry-gray-1;
|
||||
box-shadow: var(--card-box-shadow) $lbry-gray-1;
|
||||
|
@ -27,6 +26,7 @@
|
|||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin: auto;
|
||||
padding: 0 var(--spacing-large);
|
||||
}
|
||||
|
||||
.header__navigation {
|
||||
|
@ -34,7 +34,8 @@
|
|||
justify-content: space-between;
|
||||
|
||||
&:last-of-type {
|
||||
width: calc(var(--side-nav-width) + var(--spacing-medium));
|
||||
width: var(--side-nav-width);
|
||||
|
||||
@media (max-width: 600px) {
|
||||
display: none;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
.main-wrapper {
|
||||
position: relative;
|
||||
|
||||
[data-mode='dark'] & {
|
||||
background-color: var(--dm-color-08);
|
||||
}
|
||||
|
@ -7,20 +9,16 @@
|
|||
.main-wrapper__inner {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
min-height: 100vh;
|
||||
justify-content: space-between;
|
||||
max-width: var(--page-max-width);
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
padding: 0 var(--spacing-large);
|
||||
padding-bottom: var(--spacing-main-padding);
|
||||
margin-top: var(--header-height);
|
||||
padding: var(--spacing-large);
|
||||
}
|
||||
|
||||
.main {
|
||||
min-width: 0;
|
||||
position: relative;
|
||||
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) {
|
||||
width: 100%;
|
||||
|
@ -51,8 +49,14 @@
|
|||
text-align: center;
|
||||
}
|
||||
|
||||
.main--launching {
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
background-color: var(--color-background);
|
||||
}
|
||||
|
||||
.main__status {
|
||||
@extend .help;
|
||||
@extend .card__subtitle;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
background-color: $lbry-teal-4;
|
||||
|
@ -64,5 +68,6 @@
|
|||
|
||||
[data-mode='dark'] & {
|
||||
background-color: $lbry-teal-5;
|
||||
color: $lbry-white;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
.navigation {
|
||||
width: var(--side-nav-width);
|
||||
font-size: var(--font-body);
|
||||
// padding-top: 100px;
|
||||
|
||||
@media (max-width: 600px) {
|
||||
display: none;
|
||||
|
@ -11,7 +12,6 @@
|
|||
@extend .ul--no-style;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
position: relative;
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
|
|
|
@ -28,8 +28,8 @@ td {
|
|||
}
|
||||
|
||||
.table__item--actionable {
|
||||
.button svg {
|
||||
top: 3px;
|
||||
span {
|
||||
vertical-align: top;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
flex: 1;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
margin-right: calc(var(--spacing-large));
|
||||
margin-right: var(--spacing-main-padding);
|
||||
font-size: var(--font-label);
|
||||
|
||||
@media (max-width: 600px) {
|
||||
|
|
|
@ -70,9 +70,11 @@
|
|||
}
|
||||
|
||||
.menu__title {
|
||||
padding: var(--spacing-large) 0;
|
||||
padding-left: var(--spacing-medium);
|
||||
padding-right: 0;
|
||||
// padding: var(--spacing-large) 0;
|
||||
&:not(:last-of-type) {
|
||||
margin-right: var(--spacing-medium);
|
||||
}
|
||||
// padding-right: 0;
|
||||
|
||||
span {
|
||||
margin-left: var(--spacing-small);
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
@extend .button--link;
|
||||
margin-right: var(--spacing-large);
|
||||
padding: 5px 0;
|
||||
font-size: var(--font-title);
|
||||
font-size: var(--font-multiplier-large);
|
||||
color: $lbry-white;
|
||||
position: relative;
|
||||
|
||||
|
|
|
@ -84,7 +84,7 @@ $large-breakpoint: 1921px;
|
|||
// Image
|
||||
--thumbnail-preview-height: 100px;
|
||||
--thumbnail-preview-width: 177px;
|
||||
--cover-photo-height: 160px;
|
||||
--cover-photo-height: 180px;
|
||||
--channel-thumbnail-width: 10rem;
|
||||
--channel-thumbnail-width--small: 4rem;
|
||||
--file-list-thumbnail-width: 10rem;
|
||||
|
|
|
@ -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 createFilter from 'redux-persist-transform-filter';
|
||||
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 fileInfoFilter = createFilter('fileInfo', [
|
||||
'fileListPublishedSort',
|
||||
|
@ -79,7 +52,7 @@ const whiteListedReducers = [
|
|||
// @if TARGET='app'
|
||||
'publish',
|
||||
'wallet',
|
||||
'fileInfo',
|
||||
// 'fileInfo',
|
||||
// @endif
|
||||
'content',
|
||||
'subscriptions',
|
||||
|
@ -88,29 +61,48 @@ const whiteListedReducers = [
|
|||
'tags',
|
||||
];
|
||||
|
||||
const transforms = [
|
||||
// @if TARGET='app'
|
||||
walletFilter,
|
||||
contentFilter,
|
||||
fileInfoFilter,
|
||||
// @endif
|
||||
appFilter,
|
||||
searchFilter,
|
||||
tagsFilter,
|
||||
createCompressor(),
|
||||
];
|
||||
|
||||
const persistOptions = {
|
||||
key: 'v0',
|
||||
storage: localForage,
|
||||
stateReconciler: autoMergeLevel2,
|
||||
whitelist: whiteListedReducers,
|
||||
// Order is important. Needs to be compressed last or other transforms can't
|
||||
// read the data
|
||||
transforms: [
|
||||
// @if TARGET='app'
|
||||
walletFilter,
|
||||
contentFilter,
|
||||
fileInfoFilter,
|
||||
// @endif
|
||||
appFilter,
|
||||
searchFilter,
|
||||
tagsFilter,
|
||||
compressor,
|
||||
],
|
||||
debounce: 5000,
|
||||
storage: localForage,
|
||||
transforms,
|
||||
};
|
||||
|
||||
window.cacheStore = persistStore(store, persistOptions, err => {
|
||||
if (err) {
|
||||
console.error('Unable to load saved settings');
|
||||
}
|
||||
});
|
||||
let history;
|
||||
// @if TARGET='app'
|
||||
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 };
|
||||
|
|
|
@ -291,5 +291,27 @@
|
|||
"Tags You Follow": "Tags You Follow",
|
||||
"Channels You Follow": "Channels You Follow",
|
||||
"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."
|
||||
}
|
|
@ -23,7 +23,7 @@ console.log(ifProduction('production', 'development'));
|
|||
|
||||
let baseConfig = {
|
||||
mode: ifProduction('production', 'development'),
|
||||
devtool: ifProduction(false, 'inline-cheap-source-map'),
|
||||
devtool: ifProduction(false, 'cheap-module-eval-source-map'),
|
||||
optimization: {
|
||||
minimizer: [
|
||||
new TerserPlugin({
|
||||
|
|
14
yarn.lock
14
yarn.lock
|
@ -6851,7 +6851,7 @@ locate-path@^3.0.0:
|
|||
p-locate "^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"
|
||||
resolved "https://registry.yarnpkg.com/lodash-es/-/lodash-es-4.17.14.tgz#12a95a963cc5955683cee3b74e85458954f37ecc"
|
||||
integrity sha512-7zchRrGa8UZXjD/4ivUWP1867jDkhzTG2c/uj739utSd7O/pFFdxspCemIFKEEjErbcqRzn8nKnGsi7mvTgRPA==
|
||||
|
@ -9745,14 +9745,10 @@ redux-persist-transform-filter@0.0.16:
|
|||
lodash.set "^4.3.2"
|
||||
lodash.unset "^4.5.2"
|
||||
|
||||
redux-persist@^4.8.0:
|
||||
version "4.10.2"
|
||||
resolved "https://registry.yarnpkg.com/redux-persist/-/redux-persist-4.10.2.tgz#8efdb16cfe882c521a78a6d0bfdfef2437f49f96"
|
||||
integrity sha512-U+e0ieMGC69Zr72929iJW40dEld7Mflh6mu0eJtVMLGfMq/aJqjxUM1hzyUWMR1VUyAEEdPHuQmeq5ti9krIgg==
|
||||
dependencies:
|
||||
json-stringify-safe "^5.0.1"
|
||||
lodash "^4.17.4"
|
||||
lodash-es "^4.17.4"
|
||||
redux-persist@^5.10.0:
|
||||
version "5.10.0"
|
||||
resolved "https://registry.yarnpkg.com/redux-persist/-/redux-persist-5.10.0.tgz#5d8d802c5571e55924efc1c3a9b23575283be62b"
|
||||
integrity sha512-sSJAzNq7zka3qVHKce1hbvqf0Vf5DuTVm7dr4GtsqQVOexnrvbV47RWFiPxQ8fscnyiuWyD2O92DOxPl0tGCRg==
|
||||
|
||||
redux-thunk@^2.2.0:
|
||||
version "2.3.0"
|
||||
|
|
Loading…
Reference in a new issue