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-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",

View file

@ -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)} />}

View file

@ -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>

View file

@ -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>

View file

@ -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}

View file

@ -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>

View file

@ -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>
);
}

View file

@ -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(

View file

@ -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>

View file

@ -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">
{[

View file

@ -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}

View file

@ -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>

View file

@ -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

View file

@ -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={

View file

@ -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'));

View file

@ -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>
);

View file

@ -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>

View file

@ -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();
};
}

View file

@ -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) {

View file

@ -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;

View file

@ -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;
}
}

View file

@ -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;

View file

@ -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 {

View file

@ -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;

View file

@ -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;
}

View file

@ -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;
}
}

View file

@ -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;
}

View file

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

View file

@ -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) {

View file

@ -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);

View file

@ -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;

View file

@ -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;

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 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 };

View file

@ -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."
}

View file

@ -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({

View file

@ -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"