add back reverted changes
This commit is contained in:
parent
58b92fe4aa
commit
b89c8a51c6
45 changed files with 326 additions and 300 deletions
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "lbry",
|
||||
"version": "0.36.0-rc.1",
|
||||
"version": "0.36.0-rc.5",
|
||||
"description": "A browser for the LBRY network, a digital marketplace controlled by its users.",
|
||||
"keywords": [
|
||||
"lbry"
|
||||
|
@ -128,8 +128,8 @@
|
|||
"husky": "^0.14.3",
|
||||
"json-loader": "^0.5.4",
|
||||
"lbry-format": "https://github.com/lbryio/lbry-format.git",
|
||||
"lbry-redux": "lbryio/lbry-redux#85fe532d69704a283fd2ec640ad6e3b8dacd6d0d",
|
||||
"lbryinc": "lbryio/lbryinc#a44576194e1f5f60e37d328ddfdca40bd6165c2d",
|
||||
"lbry-redux": "lbryio/lbry-redux#b6a7dd0d99f0f8cfc204d3734b6cfc6eb7f8303d",
|
||||
"lbryinc": "lbryio/lbryinc#f5bee9cd300c4bdc05228e31ea15cfc430975f67",
|
||||
"lint-staged": "^7.0.2",
|
||||
"localforage": "^1.7.1",
|
||||
"lodash-es": "^4.17.14",
|
||||
|
|
|
@ -187,6 +187,7 @@ function ChannelForm(props: Props) {
|
|||
suggestMature
|
||||
help={__('The better your tags are, the easier it will be for people to discover your channel.')}
|
||||
empty={__('No tags added')}
|
||||
placeholder={__('Add a tag')}
|
||||
onSelect={newTag => {
|
||||
if (!params.tags.map(savedTag => savedTag.name).includes(newTag.name)) {
|
||||
setParams({ ...params, tags: [...params.tags, newTag] });
|
||||
|
|
|
@ -78,7 +78,8 @@ const ClaimPreview = forwardRef<any, {}>((props: Props, ref: any) => {
|
|||
properties,
|
||||
onClick,
|
||||
} = props;
|
||||
const shouldFetch = claim === undefined || (claim !== null && claim.value_type === 'channel' && isEmpty(claim.meta));
|
||||
const shouldFetch =
|
||||
claim === undefined || (claim !== null && claim.value_type === 'channel' && isEmpty(claim.meta) && !pending);
|
||||
const abandoned = !isResolvingUri && !claim;
|
||||
const claimsInChannel = (claim && claim.meta.claims_in_channel) || 0;
|
||||
const showPublishLink = abandoned && placeholder === 'publish';
|
||||
|
@ -187,24 +188,27 @@ const ClaimPreview = forwardRef<any, {}>((props: Props, ref: any) => {
|
|||
<div className="claim-preview-title">
|
||||
{claim ? <TruncatedText text={title || claim.name} lines={1} /> : <span>{__('Nothing here')}</span>}
|
||||
</div>
|
||||
{!hideActions && actions !== undefined ? (
|
||||
actions
|
||||
) : (
|
||||
<div className="card__actions--inline">
|
||||
{isChannel && !channelIsBlocked && !claimIsMine && (
|
||||
<SubscribeButton uri={uri.startsWith('lbry://') ? uri : `lbry://${uri}`} />
|
||||
{!pending && (
|
||||
<React.Fragment>
|
||||
{!hideActions && actions !== undefined ? (
|
||||
actions
|
||||
) : (
|
||||
<div className="card__actions--inline">
|
||||
{isChannel && !channelIsBlocked && !claimIsMine && (
|
||||
<SubscribeButton uri={uri.startsWith('lbry://') ? uri : `lbry://${uri}`} />
|
||||
)}
|
||||
{isChannel && !isSubscribed && !claimIsMine && (
|
||||
<BlockButton uri={uri.startsWith('lbry://') ? uri : `lbry://${uri}`} />
|
||||
)}
|
||||
{!isChannel && claim && <FileProperties uri={uri} />}
|
||||
</div>
|
||||
)}
|
||||
{isChannel && !isSubscribed && !claimIsMine && (
|
||||
<BlockButton uri={uri.startsWith('lbry://') ? uri : `lbry://${uri}`} />
|
||||
)}
|
||||
{!isChannel && claim && <FileProperties uri={uri} />}
|
||||
</div>
|
||||
</React.Fragment>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className="claim-preview-properties">
|
||||
<div className="media__subtitle">
|
||||
{pending && <div>Pending...</div>}
|
||||
{!isResolvingUri && (
|
||||
<div>
|
||||
{claim ? (
|
||||
|
@ -222,12 +226,16 @@ const ClaimPreview = forwardRef<any, {}>((props: Props, ref: any) => {
|
|||
</Fragment>
|
||||
)}
|
||||
<div>
|
||||
{claim &&
|
||||
{pending ? (
|
||||
<div>Pending...</div>
|
||||
) : (
|
||||
claim &&
|
||||
(isChannel ? (
|
||||
type !== 'inline' && `${claimsInChannel} ${__('publishes')}`
|
||||
) : (
|
||||
<DateTime timeAgo uri={uri} />
|
||||
))}
|
||||
))
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
|
13
src/ui/component/common/help-link.jsx
Normal file
13
src/ui/component/common/help-link.jsx
Normal file
|
@ -0,0 +1,13 @@
|
|||
// @flow
|
||||
import * as ICONS from 'constants/icons';
|
||||
import React from 'react';
|
||||
import Button from 'component/button';
|
||||
|
||||
type Props = {
|
||||
href: string,
|
||||
};
|
||||
|
||||
export default function HelpLink(props: Props) {
|
||||
const { href } = props;
|
||||
return <Button className="icon--help" icon={ICONS.HELP} description={__('Help')} href={href} />;
|
||||
}
|
|
@ -37,7 +37,7 @@ class InviteList extends React.PureComponent<Props> {
|
|||
return (
|
||||
<section className="card">
|
||||
<div className="table__header">
|
||||
<h2 className="card__title">
|
||||
<h2 className="card__title--between">
|
||||
{__('Invite History')}
|
||||
{referralReward && showClaimable && (
|
||||
<RewardLink
|
||||
|
|
|
@ -34,7 +34,9 @@ function PublishFile(props: Props) {
|
|||
icon={ICONS.PUBLISH}
|
||||
disabled={disabled || balance === 0}
|
||||
title={isStillEditing ? __('Edit') : __('Publish')}
|
||||
subtitle={__('You are currently editing a claim.')}
|
||||
subtitle={
|
||||
isStillEditing ? __('You are currently editing a claim.') : __('Publish something totally wacky and wild.')
|
||||
}
|
||||
actions={
|
||||
<React.Fragment>
|
||||
<FileSelector currentPath={filePath} onFileChosen={handleFileChange} />
|
||||
|
|
|
@ -135,6 +135,7 @@ function PublishForm(props: Props) {
|
|||
suggestMature
|
||||
help={__('The better your tags are, the easier it will be for people to discover your content.')}
|
||||
empty={__('No tags added')}
|
||||
placeholder={__('Add a tag')}
|
||||
onSelect={newTag => {
|
||||
if (!tags.map(savedTag => savedTag.name).includes(newTag.name)) {
|
||||
updatePublishForm({ tags: [...tags, newTag] });
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
// @flow
|
||||
import React from 'react';
|
||||
import { THUMBNAIL_STATUSES, isNameValid } from 'lbry-redux';
|
||||
import { INVALID_NAME_ERROR } from 'constants/claim';
|
||||
|
||||
type Props = {
|
||||
title: ?string,
|
||||
|
@ -21,7 +22,7 @@ function PublishFormErrors(props: Props) {
|
|||
<div className="error-text">
|
||||
{!title && <div>{__('A title is required')}</div>}
|
||||
{!name && <div>{__('A URL is required')}</div>}
|
||||
{!isNameValid(name, false) && __('LBRY names cannot contain spaces or reserved symbols ($#@;/"<>%{}|^~[]`)')}
|
||||
{!isNameValid(name, false) && INVALID_NAME_ERROR}
|
||||
{!bid && <div>{__('A deposit amount is required')}</div>}
|
||||
{uploadThumbnailStatus === THUMBNAIL_STATUSES.IN_PROGRESS && (
|
||||
<div>{__('Please wait for thumbnail to finish uploading')}</div>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// @flow
|
||||
import { CHANNEL_NEW, CHANNEL_ANONYMOUS, MINIMUM_PUBLISH_BID } from 'constants/claim';
|
||||
import { CHANNEL_NEW, CHANNEL_ANONYMOUS, MINIMUM_PUBLISH_BID, INVALID_NAME_ERROR } from 'constants/claim';
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { isNameValid } from 'lbry-redux';
|
||||
import { FormField } from 'component/common/form';
|
||||
|
@ -50,7 +50,7 @@ function PublishName(props: Props) {
|
|||
if (!name) {
|
||||
nameError = __('A name is required');
|
||||
} else if (!isNameValid(name, false)) {
|
||||
nameError = __('LBRY names cannot contain spaces or reserved symbols ($#@;/"<>%{}|^~[]`)');
|
||||
nameError = INVALID_NAME_ERROR;
|
||||
}
|
||||
|
||||
setNameError(nameError);
|
||||
|
|
|
@ -4,7 +4,7 @@ import { isNameValid } from 'lbry-redux';
|
|||
import { FormField } from 'component/common/form';
|
||||
import BusyIndicator from 'component/common/busy-indicator';
|
||||
import Button from 'component/button';
|
||||
import { CHANNEL_NEW, CHANNEL_ANONYMOUS } from 'constants/claim';
|
||||
import { CHANNEL_NEW, CHANNEL_ANONYMOUS, INVALID_NAME_ERROR } from 'constants/claim';
|
||||
|
||||
type Props = {
|
||||
channel: string, // currently selected channel
|
||||
|
@ -77,7 +77,7 @@ class ChannelSection extends React.PureComponent<Props, State> {
|
|||
|
||||
let newChannelNameError;
|
||||
if (newChannelName.length > 0 && !isNameValid(newChannelName, false)) {
|
||||
newChannelNameError = __('LBRY names cannot contain spaces or reserved symbols ($#@;/"<>%{}|^~[]`)');
|
||||
newChannelNameError = INVALID_NAME_ERROR;
|
||||
}
|
||||
|
||||
this.setState({
|
||||
|
|
|
@ -3,7 +3,7 @@ import React from 'react';
|
|||
import { Form, FormField } from 'component/common/form';
|
||||
import Button from 'component/button';
|
||||
import Card from 'component/common/card';
|
||||
import { setSavedPassword } from 'util/saved-passwords';
|
||||
import { setSavedPassword, deleteSavedPassword } from 'util/saved-passwords';
|
||||
|
||||
type Props = {
|
||||
getSync: (?string) => void,
|
||||
|
@ -18,6 +18,8 @@ function SyncPassword(props: Props) {
|
|||
function handleSubmit() {
|
||||
if (rememberPassword) {
|
||||
setSavedPassword(password);
|
||||
} else {
|
||||
deleteSavedPassword();
|
||||
}
|
||||
|
||||
getSync(password);
|
||||
|
|
|
@ -12,9 +12,10 @@ type Props = {
|
|||
onSelect?: Tag => void,
|
||||
suggestMature?: boolean,
|
||||
onRemove: Tag => void,
|
||||
placeholder?: string,
|
||||
};
|
||||
|
||||
export default function TagSelect(props: Props) {
|
||||
export default function TagsSearch(props: Props) {
|
||||
const {
|
||||
tagsPasssedIn,
|
||||
unfollowedTags = [],
|
||||
|
@ -24,6 +25,7 @@ export default function TagSelect(props: Props) {
|
|||
onSelect,
|
||||
onRemove,
|
||||
suggestMature,
|
||||
placeholder,
|
||||
} = props;
|
||||
const [newTag, setNewTag] = useState('');
|
||||
|
||||
|
@ -96,7 +98,7 @@ export default function TagSelect(props: Props) {
|
|||
autoFocus
|
||||
className="tag__input"
|
||||
onChange={onChange}
|
||||
placeholder={__('Follow more tags')}
|
||||
placeholder={placeholder || __('Follow more tags')}
|
||||
type="text"
|
||||
value={newTag}
|
||||
/>
|
||||
|
|
|
@ -20,6 +20,7 @@ type Props = {
|
|||
tagsChosen?: Array<Tag>,
|
||||
onSelect?: Tag => void,
|
||||
onRemove?: Tag => void,
|
||||
placeholder?: string,
|
||||
};
|
||||
|
||||
export default function TagSelect(props: Props) {
|
||||
|
@ -33,6 +34,7 @@ export default function TagSelect(props: Props) {
|
|||
onSelect,
|
||||
onRemove,
|
||||
suggestMature,
|
||||
placeholder,
|
||||
} = props;
|
||||
const [hasClosed, setHasClosed] = usePersistedState('tag-select:has-closed', false);
|
||||
const tagsToDisplay = tagsChosen || followedTags;
|
||||
|
@ -88,6 +90,7 @@ export default function TagSelect(props: Props) {
|
|||
onSelect={onSelect}
|
||||
suggestMature={suggestMature && !hasMatureTag}
|
||||
tagsPasssedIn={tagsToDisplay}
|
||||
placeholder={placeholder}
|
||||
/>
|
||||
</React.Fragment>
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ import Button from 'component/button';
|
|||
import { Lbryio } from 'lbryinc';
|
||||
import analytics from 'analytics';
|
||||
import { EMAIL_REGEX } from 'constants/email';
|
||||
import I18nMessage from 'component/i18nMessage';
|
||||
|
||||
type Props = {
|
||||
errorMessage: ?string,
|
||||
|
@ -18,6 +19,7 @@ type Props = {
|
|||
function UserEmailNew(props: Props) {
|
||||
const { errorMessage, isPending, addUserEmail, syncEnabled, setSync, balance } = props;
|
||||
const [newEmail, setEmail] = useState('');
|
||||
const [ageConfirmation, setAgeConfirmation] = useState(true);
|
||||
const valid = newEmail.match(EMAIL_REGEX);
|
||||
|
||||
function handleSubmit() {
|
||||
|
@ -52,28 +54,57 @@ function UserEmailNew(props: Props) {
|
|||
error={errorMessage}
|
||||
onChange={e => setEmail(e.target.value)}
|
||||
/>
|
||||
{!IS_WEB && (
|
||||
<div className="section">
|
||||
<FormField
|
||||
type="checkbox"
|
||||
name="sync_checkbox"
|
||||
label={__('Sync balance and preferences across devices')}
|
||||
helper={
|
||||
balance > 0 ? (
|
||||
__('This feature is not yet available for wallets with balances, but the gerbils are working on it.')
|
||||
) : (
|
||||
<React.Fragment>
|
||||
{__('Blockchain expert?')}{' '}
|
||||
<Button button="link" href="https://lbry.com/faq/account-sync" label={__('Learn More')} />
|
||||
</React.Fragment>
|
||||
)
|
||||
name="age_checkbox"
|
||||
label={
|
||||
<I18nMessage
|
||||
tokens={{
|
||||
terms: (
|
||||
<Button button="link" href="https://www.lbry.com/termsofservice" label={__('Terms of Service')} />
|
||||
),
|
||||
}}
|
||||
>
|
||||
I am over the age of 13 and agree to the %terms%.
|
||||
</I18nMessage>
|
||||
}
|
||||
checked={syncEnabled}
|
||||
onChange={() => setSync(!syncEnabled)}
|
||||
disabled={balance > 0}
|
||||
checked={ageConfirmation}
|
||||
onChange={() => setAgeConfirmation(!ageConfirmation)}
|
||||
/>
|
||||
)}
|
||||
<div className="card__actions">
|
||||
<Button button="primary" type="submit" label={__('Continue')} disabled={!newEmail || !valid || isPending} />
|
||||
{!IS_WEB && (
|
||||
<FormField
|
||||
type="checkbox"
|
||||
name="sync_checkbox"
|
||||
label={__('Sync balance and preferences across devices')}
|
||||
helper={
|
||||
balance > 0 ? (
|
||||
__('This feature is not yet available for wallets with balances, but the gerbils are working on it.')
|
||||
) : (
|
||||
<I18nMessage
|
||||
tokens={{
|
||||
learn_more: (
|
||||
<Button button="link" href="https://lbry.com/faq/account-sync" label={__('Learn More')} />
|
||||
),
|
||||
}}
|
||||
>
|
||||
Blockchain expert? %learn_more%
|
||||
</I18nMessage>
|
||||
)
|
||||
}
|
||||
checked={syncEnabled}
|
||||
onChange={() => setSync(!syncEnabled)}
|
||||
disabled={balance > 0}
|
||||
/>
|
||||
)}
|
||||
<div className="card__actions">
|
||||
<Button
|
||||
button="primary"
|
||||
type="submit"
|
||||
label={__('Continue')}
|
||||
disabled={!newEmail || !valid || !ageConfirmation || isPending}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</Form>
|
||||
</div>
|
||||
|
|
|
@ -3,7 +3,7 @@ import React, { useState } from 'react';
|
|||
import { isNameValid } from 'lbry-redux';
|
||||
import Button from 'component/button';
|
||||
import { Form, FormField } from 'component/common/form';
|
||||
|
||||
import { INVALID_NAME_ERROR } from 'constants/claim';
|
||||
export const DEFAULT_BID_FOR_FIRST_CHANNEL = 0.9;
|
||||
|
||||
type Props = {
|
||||
|
@ -29,7 +29,7 @@ function UserFirstChannel(props: Props) {
|
|||
const { value } = e.target;
|
||||
setChannel(value);
|
||||
if (!isNameValid(value, false)) {
|
||||
setNameError(__('LBRY names cannot contain spaces or reserved symbols ($#@;/"<>%{}|^~[]`)'));
|
||||
setNameError(INVALID_NAME_ERROR);
|
||||
} else {
|
||||
setNameError();
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@ import {
|
|||
selectGetSyncErrorMessage,
|
||||
selectSyncHash,
|
||||
} from 'lbryinc';
|
||||
import { selectMyChannelClaims, selectBalance, selectFetchingMyChannels } from 'lbry-redux';
|
||||
import { selectMyChannelClaims, selectBalance, selectFetchingMyChannels, selectCreatingChannel } from 'lbry-redux';
|
||||
import { makeSelectClientSetting } from 'redux/selectors/settings';
|
||||
import UserSignIn from './view';
|
||||
|
||||
|
@ -36,6 +36,7 @@ const select = state => ({
|
|||
syncingWallet: selectGetSyncIsPending(state),
|
||||
getSyncError: selectGetSyncErrorMessage(state),
|
||||
hasSynced: Boolean(selectSyncHash(state)),
|
||||
creatingChannel: selectCreatingChannel(state),
|
||||
});
|
||||
|
||||
const perform = dispatch => ({
|
||||
|
|
|
@ -8,9 +8,10 @@ import { DEFAULT_BID_FOR_FIRST_CHANNEL } from 'component/userFirstChannel/view';
|
|||
import { rewards as REWARDS, YOUTUBE_STATUSES } from 'lbryinc';
|
||||
import UserVerify from 'component/userVerify';
|
||||
import Spinner from 'component/spinner';
|
||||
import YoutubeTransferWelcome from 'component/youtubeTransferWelcome';
|
||||
import YoutubeTransferStatus from 'component/youtubeTransferStatus';
|
||||
import SyncPassword from 'component/syncPassword';
|
||||
import useFetched from 'effects/use-fetched';
|
||||
import Confetti from 'react-confetti';
|
||||
|
||||
type Props = {
|
||||
user: ?User,
|
||||
|
@ -29,6 +30,7 @@ type Props = {
|
|||
hasSynced: boolean,
|
||||
syncingWallet: boolean,
|
||||
getSyncError: ?string,
|
||||
creatingChannel: boolean,
|
||||
};
|
||||
|
||||
function UserSignIn(props: Props) {
|
||||
|
@ -49,6 +51,7 @@ function UserSignIn(props: Props) {
|
|||
getSyncError,
|
||||
hasSynced,
|
||||
fetchingChannels,
|
||||
creatingChannel,
|
||||
} = props;
|
||||
const { search } = location;
|
||||
const urlParams = new URLSearchParams(search);
|
||||
|
@ -59,30 +62,33 @@ function UserSignIn(props: Props) {
|
|||
const channelCount = channels ? channels.length : 0;
|
||||
const hasClaimedEmailAward = claimedRewards.some(reward => reward.reward_type === REWARDS.TYPE_CONFIRM_EMAIL);
|
||||
const hasYoutubeChannels = youtubeChannels && Boolean(youtubeChannels.length);
|
||||
const hasTransferrableYoutubeChannels = hasYoutubeChannels && youtubeChannels.some(channel => channel.transferable);
|
||||
const hasPendingYoutubeTransfer =
|
||||
hasYoutubeChannels && youtubeChannels.some(channel => channel.transfer_state === YOUTUBE_STATUSES.PENDING_TRANSFER);
|
||||
const isYoutubeTransferComplete =
|
||||
hasYoutubeChannels &&
|
||||
youtubeChannels.every(channel => channel.transfer_state === YOUTUBE_STATUSES.COMPLETED_TRANSFER);
|
||||
|
||||
// Complexity warning
|
||||
// We can't just check if we are currently fetching something
|
||||
// We may want to keep a component rendered while something is being fetched, instead of replacing it with the large spinner
|
||||
// The verbose variable names are an attempt to alleviate _some_ of the confusion from handling all edge cases that come from
|
||||
// reward claiming (plus the balance updating after), channel creation, account syncing, and youtube transfer
|
||||
const canHijackSignInFlowWithSpinner = hasVerifiedEmail && !getSyncError && balance === 0;
|
||||
const isCurrentlyFetchingSomething = fetchingChannels || claimingReward || syncingWallet;
|
||||
// reward claiming, channel creation, account syncing, and youtube transfer
|
||||
const canHijackSignInFlowWithSpinner = hasVerifiedEmail && !getSyncError;
|
||||
const isCurrentlyFetchingSomething = fetchingChannels || claimingReward || syncingWallet || creatingChannel;
|
||||
const isWaitingForSomethingToFinish =
|
||||
// If the user has claimed the email award, we need to wait until the balance updates sometime in the future
|
||||
!hasFetchedReward || (hasFetchedReward && balance === 0) || (syncEnabled && !hasSynced);
|
||||
|
||||
(!hasFetchedReward && !hasClaimedEmailAward) || (syncEnabled && !hasSynced);
|
||||
// The possible screens for the sign in flow
|
||||
const showEmail = !emailToVerify && !hasVerifiedEmail;
|
||||
const showEmailVerification = emailToVerify && !hasVerifiedEmail;
|
||||
const showUserVerification = hasVerifiedEmail && !rewardsApproved;
|
||||
const showSyncPassword = syncEnabled && getSyncError && !hasSynced;
|
||||
const showChannelCreation =
|
||||
hasVerifiedEmail && balance && balance > DEFAULT_BID_FOR_FIRST_CHANNEL && channelCount === 0 && !hasYoutubeChannels;
|
||||
const showYoutubeTransfer =
|
||||
hasVerifiedEmail && hasYoutubeChannels && (hasTransferrableYoutubeChannels || hasPendingYoutubeTransfer);
|
||||
hasVerifiedEmail &&
|
||||
balance !== undefined &&
|
||||
balance !== null &&
|
||||
balance > DEFAULT_BID_FOR_FIRST_CHANNEL &&
|
||||
channelCount === 0 &&
|
||||
!hasYoutubeChannels;
|
||||
const showYoutubeTransfer = hasVerifiedEmail && hasYoutubeChannels && !isYoutubeTransferComplete;
|
||||
const showLoadingSpinner =
|
||||
canHijackSignInFlowWithSpinner && (isCurrentlyFetchingSomething || isWaitingForSomethingToFinish);
|
||||
|
||||
|
@ -109,7 +115,11 @@ function UserSignIn(props: Props) {
|
|||
showSyncPassword && <SyncPassword />,
|
||||
showChannelCreation && <UserFirstChannel />,
|
||||
// @if TARGET='app'
|
||||
showYoutubeTransfer && <YoutubeTransferWelcome />,
|
||||
showYoutubeTransfer && (
|
||||
<div>
|
||||
<YoutubeTransferStatus /> <Confetti recycle={false} style={{ position: 'fixed' }} />
|
||||
</div>
|
||||
),
|
||||
// @endif
|
||||
showLoadingSpinner && (
|
||||
<div className="main--empty">
|
||||
|
|
|
@ -12,12 +12,10 @@ type Props = {
|
|||
claimsBalance: number,
|
||||
supportsBalance: number,
|
||||
tipsBalance: number,
|
||||
rewards: Array<Reward>,
|
||||
};
|
||||
|
||||
const WalletBalance = (props: Props) => {
|
||||
const { balance, claimsBalance, supportsBalance, tipsBalance, rewards } = props;
|
||||
const rewardTotal = rewards.reduce((acc, val) => acc + val.reward_amount, 0);
|
||||
const { balance, claimsBalance, supportsBalance, tipsBalance } = props;
|
||||
|
||||
return (
|
||||
<React.Fragment>
|
||||
|
@ -29,24 +27,12 @@ const WalletBalance = (props: Props) => {
|
|||
</span>
|
||||
|
||||
<div className="section__actions">
|
||||
<Button button="inverse" label={__('Send Credits')} navigate={`$/${PAGES.WALLET_SEND}`} />
|
||||
<Button button="inverse" icon={ICONS.SEND} label={__('Send Credits')} navigate={`$/${PAGES.WALLET_SEND}`} />
|
||||
<Button button="inverse" label={__('Your Address')} navigate={`$/${PAGES.WALLET_RECEIVE}`} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div className="section">
|
||||
<div className="section__flex">
|
||||
<Icon sectionIcon icon={ICONS.FEATURED} />
|
||||
<h2 className="section__title--small">
|
||||
<strong>
|
||||
<CreditAmount badge={false} amount={rewardTotal} precision={8} />
|
||||
</strong>{' '}
|
||||
{__('Earned From Rewards')}
|
||||
</h2>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="section">
|
||||
<div className="section__flex">
|
||||
<Icon sectionIcon icon={ICONS.TIP} />
|
||||
|
@ -54,7 +40,7 @@ const WalletBalance = (props: Props) => {
|
|||
<strong>
|
||||
<CreditAmount badge={false} amount={tipsBalance} precision={8} />
|
||||
</strong>{' '}
|
||||
{__('Earned From Tips')}
|
||||
{__('Earned and bound in tips')}
|
||||
</h2>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -68,12 +54,12 @@ const WalletBalance = (props: Props) => {
|
|||
</h2>
|
||||
<div className="section__subtitle">
|
||||
<dl>
|
||||
<dt>{__('Your Publishes')}</dt>
|
||||
<dt>{__('... in your publishes')}</dt>
|
||||
<dd>
|
||||
<CreditAmount badge={false} amount={claimsBalance} precision={8} />
|
||||
</dd>
|
||||
|
||||
<dt>{__('Your Supports')}</dt>
|
||||
<dt>{__('... in your supports')}</dt>
|
||||
<dd>
|
||||
<CreditAmount badge={false} amount={supportsBalance} precision={8} />
|
||||
</dd>
|
||||
|
|
|
@ -1,10 +1,14 @@
|
|||
// @flow
|
||||
import * as PAGES from 'constants/pages';
|
||||
import * as React from 'react';
|
||||
import Button from 'component/button';
|
||||
import ClaimPreview from 'component/claimPreview';
|
||||
import Card from 'component/common/card';
|
||||
import { YOUTUBE_STATUSES } from 'lbryinc';
|
||||
import { buildURI } from 'lbry-redux';
|
||||
import I18nMessage from 'component/i18nMessage';
|
||||
|
||||
const STATUS_URL = 'https://lbry.com/youtube/status/';
|
||||
|
||||
type Props = {
|
||||
youtubeChannels: Array<any>,
|
||||
|
@ -13,6 +17,7 @@ type Props = {
|
|||
updateUser: () => void,
|
||||
checkYoutubeTransfer: () => void,
|
||||
videosImported: ?Array<number>, // [currentAmountImported, totalAmountToImport]
|
||||
hideChannelLink: boolean,
|
||||
};
|
||||
|
||||
export default function YoutubeTransferStatus(props: Props) {
|
||||
|
@ -23,13 +28,15 @@ export default function YoutubeTransferStatus(props: Props) {
|
|||
videosImported,
|
||||
checkYoutubeTransfer,
|
||||
updateUser,
|
||||
hideChannelLink = false,
|
||||
} = props;
|
||||
const hasChannels = youtubeChannels && youtubeChannels.length;
|
||||
|
||||
const transferEnabled = youtubeChannels.some(status => status.transferable);
|
||||
const hasPendingTransfers = youtubeChannels.some(
|
||||
status => status.transfer_state === YOUTUBE_STATUSES.PENDING_TRANSFER
|
||||
);
|
||||
const isYoutubeTransferComplete =
|
||||
hasChannels && youtubeChannels.every(channel => channel.transfer_state === YOUTUBE_STATUSES.COMPLETED_TRANSFER);
|
||||
|
||||
let total;
|
||||
let complete;
|
||||
|
@ -72,26 +79,49 @@ export default function YoutubeTransferStatus(props: Props) {
|
|||
|
||||
return (
|
||||
hasChannels &&
|
||||
(hasPendingTransfers || transferEnabled) && (
|
||||
!isYoutubeTransferComplete && (
|
||||
<div>
|
||||
<Card
|
||||
title={youtubeChannels.length > 1 ? __('Your YouTube Channels') : __('Your YouTube Channel')}
|
||||
subtitle={
|
||||
<span>
|
||||
{hasPendingTransfers
|
||||
? __('Your videos are currently being transferred. There is nothing else for you to do.')
|
||||
: __('Your videos are ready to be transferred.')}
|
||||
{hasPendingTransfers &&
|
||||
__('Your videos are currently being transferred. There is nothing else for you to do.')}
|
||||
{transferEnabled && !hasPendingTransfers && __('Your videos are ready to be transferred.')}
|
||||
{!transferEnabled && !hasPendingTransfers && __('Please check back later.')}
|
||||
</span>
|
||||
}
|
||||
body={
|
||||
<section>
|
||||
{youtubeChannels.map((channel, index) => {
|
||||
const { lbry_channel_name: channelName, channel_claim_id: claimId } = channel;
|
||||
const {
|
||||
lbry_channel_name: channelName,
|
||||
channel_claim_id: claimId,
|
||||
status_token: statusToken,
|
||||
} = channel;
|
||||
const url = buildURI({ channelName, channelClaimId: claimId });
|
||||
const transferState = getMessage(channel);
|
||||
return (
|
||||
<div key={url} className="card--inline">
|
||||
<ClaimPreview uri={url} actions={<span className="help">{transferState}</span>} properties={''} />
|
||||
{claimId ? (
|
||||
<ClaimPreview
|
||||
uri={url}
|
||||
actions={<span className="help">{transferState}</span>}
|
||||
properties={false}
|
||||
/>
|
||||
) : (
|
||||
<p className="section--padded">
|
||||
<I18nMessage
|
||||
tokens={{
|
||||
statusLink: <Button button="link" href={STATUS_URL + statusToken} label={__('here')} />,
|
||||
channelName,
|
||||
}}
|
||||
>
|
||||
%channelName% is not ready to be transferred. You can check the status %statusLink% or check
|
||||
back later.
|
||||
</I18nMessage>
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
|
@ -101,7 +131,7 @@ export default function YoutubeTransferStatus(props: Props) {
|
|||
</section>
|
||||
}
|
||||
actions={
|
||||
transferEnabled && (
|
||||
transferEnabled ? (
|
||||
<div className="card__actions">
|
||||
<Button
|
||||
button="primary"
|
||||
|
@ -111,6 +141,12 @@ export default function YoutubeTransferStatus(props: Props) {
|
|||
/>
|
||||
<Button button="link" label={__('Learn more')} href="https://lbry.com/faq/youtube#transfer" />
|
||||
</div>
|
||||
) : !hideChannelLink ? (
|
||||
<div className="card__actions">
|
||||
<Button button="primary" navigate={`/$/${PAGES.CHANNELS}`} label={__('View Your Channels')} />
|
||||
</div>
|
||||
) : (
|
||||
false
|
||||
)
|
||||
}
|
||||
/>
|
||||
|
|
|
@ -1,25 +0,0 @@
|
|||
import { connect } from 'react-redux';
|
||||
import {
|
||||
selectYoutubeChannels,
|
||||
selectYouTubeImportPending,
|
||||
selectUserIsPending,
|
||||
doClaimYoutubeChannels,
|
||||
doUserFetch,
|
||||
} from 'lbryinc';
|
||||
import YoutubeChannelList from './view';
|
||||
|
||||
const select = state => ({
|
||||
youtubeChannels: selectYoutubeChannels(state),
|
||||
youtubeImportPending: selectYouTubeImportPending(state),
|
||||
userFetchPending: selectUserIsPending(state),
|
||||
});
|
||||
|
||||
const perform = dispatch => ({
|
||||
claimChannels: () => dispatch(doClaimYoutubeChannels()),
|
||||
updateUser: () => dispatch(doUserFetch()),
|
||||
});
|
||||
|
||||
export default connect(
|
||||
select,
|
||||
perform
|
||||
)(YoutubeChannelList);
|
|
@ -1,72 +0,0 @@
|
|||
// @flow
|
||||
import * as PAGES from 'constants/pages';
|
||||
import React from 'react';
|
||||
import classnames from 'classnames';
|
||||
import ClaimPreview from 'component/claimPreview';
|
||||
import Button from 'component/button';
|
||||
import Confetti from 'react-confetti';
|
||||
import { YOUTUBE_STATUSES } from 'lbryinc';
|
||||
|
||||
type Props = {
|
||||
youtubeChannels: Array<{ lbry_channel_name: string, channel_claim_id: string, transfer_state: string }>,
|
||||
claimChannels: () => void,
|
||||
};
|
||||
|
||||
export default function UserYoutubeTransfer(props: Props) {
|
||||
const { youtubeChannels, claimChannels } = props;
|
||||
const hasYoutubeChannels = youtubeChannels && youtubeChannels.length;
|
||||
const hasPendingYoutubeTransfer =
|
||||
hasYoutubeChannels && youtubeChannels.some(channel => channel.transfer_state === YOUTUBE_STATUSES.PENDING_TRANSFER);
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div className="section__header">
|
||||
{!hasPendingYoutubeTransfer ? (
|
||||
<React.Fragment>
|
||||
<h1 className="section__title--large">{__('Welcome back!')}</h1>
|
||||
<p className="section__subtitle">{__('Your channel is ready to be sent over.')}</p>
|
||||
</React.Fragment>
|
||||
) : (
|
||||
<React.Fragment>
|
||||
<h1 className="section__title--large">{__('Good To Go!')}</h1>
|
||||
<p className="section__subtitle">
|
||||
{__('You now control your channel and your videos are being transferred to your account.')}
|
||||
</p>
|
||||
</React.Fragment>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<section className="section">
|
||||
{youtubeChannels.map(({ lbry_channel_name: channelName, channel_claim_id: claimId }) => (
|
||||
<div key={channelName} className={classnames('card--inline')}>
|
||||
<ClaimPreview disabled onClick={() => {}} actions={false} uri={`lbry://${channelName}#${claimId}`} />
|
||||
</div>
|
||||
))}
|
||||
</section>
|
||||
|
||||
{hasPendingYoutubeTransfer ? (
|
||||
<section className="section">
|
||||
<h1 className="section__title">{__('Transfer In Progress...')}</h1>
|
||||
<p className="section__subtitle">{__('You can now publish and comment using your official channel.')}</p>
|
||||
|
||||
<div className="card__actions">
|
||||
<Button
|
||||
button="primary"
|
||||
label={youtubeChannels.length > 1 ? __('View Your Channels') : __('View Your Channel')}
|
||||
navigate={`/$/${PAGES.CHANNELS}`}
|
||||
/>
|
||||
</div>
|
||||
</section>
|
||||
) : (
|
||||
<section className="section">
|
||||
<h1 className="section__title">{__('Begin Transfer')}</h1>
|
||||
<div className="section__actions">
|
||||
<Button button="primary" label={__('Transfer')} onClick={claimChannels} />
|
||||
</div>
|
||||
</section>
|
||||
)}
|
||||
|
||||
{hasPendingYoutubeTransfer && <Confetti recycle={false} style={{ position: 'fixed' }} />}
|
||||
</div>
|
||||
);
|
||||
}
|
|
@ -3,3 +3,6 @@ export const MINIMUM_PUBLISH_BID = 0.00000001;
|
|||
export const CHANNEL_ANONYMOUS = 'anonymous';
|
||||
export const CHANNEL_NEW = 'new';
|
||||
export const PAGE_SIZE = 20;
|
||||
|
||||
export const INVALID_NAME_ERROR =
|
||||
__('LBRY names cannot contain spaces or reserved symbols') + ' ' + '($#@;/"<>%{}|^~[]`)';
|
||||
|
|
|
@ -20,6 +20,7 @@ import * as MODALS from 'constants/modal_types';
|
|||
import { Form, FormField } from 'component/common/form';
|
||||
import ClaimPreview from 'component/claimPreview';
|
||||
import Icon from 'component/common/icon';
|
||||
import HelpLink from 'component/common/help-link';
|
||||
|
||||
const PAGE_VIEW_QUERY = `view`;
|
||||
const ABOUT_PAGE = `about`;
|
||||
|
@ -190,6 +191,7 @@ function ChannelPage(props: Props) {
|
|||
<ClaimUri uri={uri} />
|
||||
<span>
|
||||
{subCount} {subCount !== 1 ? __('Subscribers') : __('Subscriber')}
|
||||
<HelpLink href="https://lbry.com/faq/views" />
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -15,15 +15,27 @@ type Props = {
|
|||
export default function ChannelsPage(props: Props) {
|
||||
const { channels, fetchChannelListMine, fetchingChannels, youtubeChannels } = props;
|
||||
const hasYoutubeChannels = youtubeChannels && Boolean(youtubeChannels.length);
|
||||
const hasPendingChannels = channels && channels.some(channel => channel.confirmations === -1);
|
||||
|
||||
useEffect(() => {
|
||||
fetchChannelListMine();
|
||||
}, [fetchChannelListMine]);
|
||||
|
||||
let interval;
|
||||
if (hasPendingChannels) {
|
||||
interval = setInterval(() => {
|
||||
fetchChannelListMine();
|
||||
}, 5000);
|
||||
}
|
||||
|
||||
return () => {
|
||||
clearInterval(interval);
|
||||
};
|
||||
}, [fetchChannelListMine, hasPendingChannels]);
|
||||
|
||||
return (
|
||||
<Page>
|
||||
{/* @if TARGET='app' */}
|
||||
{hasYoutubeChannels && <YoutubeTransferStatus />}
|
||||
{hasYoutubeChannels && <YoutubeTransferStatus hideChannelLink />}
|
||||
{/* @endif */}
|
||||
|
||||
{channels && channels.length ? (
|
||||
|
|
|
@ -18,6 +18,7 @@ import CommentsList from 'component/commentsList';
|
|||
import CommentCreate from 'component/commentCreate';
|
||||
import ClaimUri from 'component/claimUri';
|
||||
import ClaimPreview from 'component/claimPreview';
|
||||
import HelpLink from 'component/common/help-link';
|
||||
|
||||
export const FILE_WRAPPER_CLASS = 'grid-area--content';
|
||||
|
||||
|
@ -161,6 +162,7 @@ class FilePage extends React.Component<Props> {
|
|||
<DateTime uri={uri} show={DateTime.SHOW_DATE} />
|
||||
<span>
|
||||
{viewCount} {viewCount !== 1 ? __('Views') : __('View')}
|
||||
<HelpLink href="https://lbry.com/faq/views" />
|
||||
</span>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -1,13 +1,7 @@
|
|||
import { connect } from 'react-redux';
|
||||
import * as SETTINGS from 'constants/settings';
|
||||
import { doClearCache, doNotifyEncryptWallet, doNotifyDecryptWallet, doNotifyForgetPassword } from 'redux/actions/app';
|
||||
import {
|
||||
doSetDaemonSetting,
|
||||
doSetClientSetting,
|
||||
doGetThemes,
|
||||
doChangeLanguage,
|
||||
doSetDarkTime,
|
||||
} from 'redux/actions/settings';
|
||||
import { doSetDaemonSetting, doSetClientSetting, doSetDarkTime } from 'redux/actions/settings';
|
||||
import { doSetPlayingUri } from 'redux/actions/content';
|
||||
import { makeSelectClientSetting, selectDaemonSettings, selectosNotificationsEnabled } from 'redux/selectors/settings';
|
||||
import { doWalletStatus, selectWalletIsEncrypted, selectBlockedChannelsCount } from 'lbry-redux';
|
||||
|
@ -36,7 +30,6 @@ const perform = dispatch => ({
|
|||
setDaemonSetting: (key, value) => dispatch(doSetDaemonSetting(key, value)),
|
||||
clearCache: () => dispatch(doClearCache()),
|
||||
setClientSetting: (key, value) => dispatch(doSetClientSetting(key, value)),
|
||||
getThemes: () => dispatch(doGetThemes()),
|
||||
encryptWallet: () => dispatch(doNotifyEncryptWallet()),
|
||||
decryptWallet: () => dispatch(doNotifyDecryptWallet()),
|
||||
updateWalletStatus: () => dispatch(doWalletStatus()),
|
||||
|
|
|
@ -44,7 +44,6 @@ type Props = {
|
|||
setDaemonSetting: (string, ?SetDaemonSettingArg) => void,
|
||||
setClientSetting: (string, SetDaemonSettingArg) => void,
|
||||
clearCache: () => Promise<any>,
|
||||
getThemes: () => void,
|
||||
daemonSettings: DaemonSettings,
|
||||
showNsfw: boolean,
|
||||
instantPurchaseEnabled: boolean,
|
||||
|
@ -95,7 +94,6 @@ class SettingsPage extends React.PureComponent<Props, State> {
|
|||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.props.getThemes();
|
||||
this.props.updateWalletStatus();
|
||||
getSavedPassword().then(p => {
|
||||
if (p) {
|
||||
|
@ -513,6 +511,7 @@ class SettingsPage extends React.PureComponent<Props, State> {
|
|||
<React.Fragment>
|
||||
{/* @if TARGET='app' */}
|
||||
<FormField
|
||||
disabled
|
||||
type="checkbox"
|
||||
name="encrypt_wallet"
|
||||
onChange={() => this.onChangeEncryptWallet()}
|
||||
|
@ -520,9 +519,19 @@ class SettingsPage extends React.PureComponent<Props, State> {
|
|||
label={__('Encrypt my wallet with a custom password')}
|
||||
helper={
|
||||
<React.Fragment>
|
||||
{__('Secure your local wallet data with a custom password.')}{' '}
|
||||
<I18nMessage
|
||||
tokens={{
|
||||
learn_more: (
|
||||
<Button button="link" label={__('Learn more')} href="https://lbry.com/faq/account-sync" />
|
||||
),
|
||||
}}
|
||||
>
|
||||
Wallet encryption is currently unavailable until it's supported for synced accounts. It will
|
||||
be added back soon. %learn_more%
|
||||
</I18nMessage>
|
||||
{/* {__('Secure your local wallet data with a custom password.')}{' '}
|
||||
<strong>{__('Lost passwords cannot be recovered.')} </strong>
|
||||
<Button button="link" label={__('Learn more')} href="https://lbry.com/faq/wallet-encryption" />.
|
||||
<Button button="link" label={__('Learn more')} href="https://lbry.com/faq/wallet-encryption" />. */}
|
||||
</React.Fragment>
|
||||
}
|
||||
/>
|
||||
|
|
|
@ -7,6 +7,7 @@ import path from 'path';
|
|||
import * as ACTIONS from 'constants/action_types';
|
||||
import * as MODALS from 'constants/modal_types';
|
||||
import * as PAGES from 'constants/pages';
|
||||
import * as SETTINGS from 'constants/settings';
|
||||
import {
|
||||
Lbry,
|
||||
doBalanceSubscribe,
|
||||
|
@ -16,6 +17,7 @@ import {
|
|||
makeSelectClaimIsMine,
|
||||
doPopulateSharedUserState,
|
||||
doFetchChannelListMine,
|
||||
selectBalance,
|
||||
} from 'lbry-redux';
|
||||
import Native from 'native';
|
||||
import { doFetchDaemonSettings } from 'redux/actions/settings';
|
||||
|
@ -31,12 +33,13 @@ import {
|
|||
selectUpgradeTimer,
|
||||
selectModal,
|
||||
} from 'redux/selectors/app';
|
||||
import { Lbryio, doAuthenticate, doGetSync } from 'lbryinc';
|
||||
import { Lbryio, doAuthenticate, doGetSync, selectSyncHash, doResetSync } from 'lbryinc';
|
||||
import { lbrySettings as config, version as appVersion } from 'package.json';
|
||||
import { push } from 'connected-react-router';
|
||||
import analytics from 'analytics';
|
||||
import { deleteAuthToken } from 'util/saved-passwords';
|
||||
import cookie from 'cookie';
|
||||
import { makeSelectClientSetting } from 'redux/selectors/settings';
|
||||
|
||||
// @if TARGET='app'
|
||||
const { autoUpdater } = remote.require('electron-updater');
|
||||
|
@ -456,7 +459,19 @@ export function doSignIn() {
|
|||
// @endif
|
||||
|
||||
// @if TARGET='app'
|
||||
dispatch(doGetSync());
|
||||
const state = getState();
|
||||
const syncEnabled = makeSelectClientSetting(SETTINGS.ENABLE_SYNC)(state);
|
||||
const syncHash = selectSyncHash(state);
|
||||
const balance = selectBalance(state);
|
||||
|
||||
// For existing users, check if they've synced before, or have 0 balance
|
||||
if (syncEnabled && (syncHash || balance === 0)) {
|
||||
dispatch(doGetSync());
|
||||
|
||||
setInterval(() => {
|
||||
dispatch(doGetSync());
|
||||
}, 1000 * 60 * 5);
|
||||
}
|
||||
// @endif
|
||||
|
||||
Lbryio.call('user_settings', 'get').then(settings => {
|
||||
|
@ -468,9 +483,18 @@ export function doSignIn() {
|
|||
export function doSignOut() {
|
||||
return dispatch => {
|
||||
deleteAuthToken()
|
||||
.then(window.persistor.purge)
|
||||
.then(() => {
|
||||
location.reload();
|
||||
// @if TARGET='web'
|
||||
window.persistor.purge();
|
||||
// @endif
|
||||
// @if TARGET='app'
|
||||
return dispatch(doResetSync());
|
||||
// @endif
|
||||
})
|
||||
.then(() => {
|
||||
setTimeout(() => {
|
||||
location.reload();
|
||||
});
|
||||
})
|
||||
.catch(() => location.reload());
|
||||
};
|
||||
|
|
|
@ -54,7 +54,10 @@ export const doCheckPendingPublishesApp = () => (dispatch: Dispatch, getState: G
|
|||
const onConfirmed = claim => {
|
||||
if (selectosNotificationsEnabled(getState())) {
|
||||
const notif = new window.Notification('LBRY Publish Complete', {
|
||||
body: `${claim.value.title} has been published to lbry://${claim.name}. Click here to view it`,
|
||||
body: __('%nameOrTitle% has been published to lbry://%name%. Click here to view it.', {
|
||||
nameOrTitle: claim.value_type === 'channel' ? `@${claim.name}` : claim.value.title,
|
||||
name: claim.name,
|
||||
}),
|
||||
silent: false,
|
||||
});
|
||||
notif.onclick = () => {
|
||||
|
|
|
@ -46,13 +46,6 @@ export function doSetClientSetting(key, value) {
|
|||
};
|
||||
}
|
||||
|
||||
export function doGetThemes() {
|
||||
return dispatch => {
|
||||
const themes = [__('light'), __('dark')];
|
||||
dispatch(doSetClientSetting(SETTINGS.THEMES, themes));
|
||||
};
|
||||
}
|
||||
|
||||
export function doUpdateIsNight() {
|
||||
return {
|
||||
type: ACTIONS.UPDATE_IS_NIGHT,
|
||||
|
|
|
@ -15,8 +15,8 @@ const defaultState = {
|
|||
|
||||
// UI
|
||||
[SETTINGS.LANGUAGE]: window.localStorage.getItem(SETTINGS.LANGUAGE) || 'en',
|
||||
[SETTINGS.THEME]: 'light',
|
||||
[SETTINGS.THEMES]: [],
|
||||
[SETTINGS.THEME]: __('light'),
|
||||
[SETTINGS.THEMES]: [__('light'), __('dark')],
|
||||
[SETTINGS.SUPPORT_OPTION]: false,
|
||||
[SETTINGS.HIDE_SPLASH_ANIMATION]: false,
|
||||
[SETTINGS.HIDE_BALANCE]: false,
|
||||
|
|
|
@ -40,6 +40,7 @@
|
|||
.button--inverse {
|
||||
height: var(--button-height);
|
||||
border-radius: var(--button-radius);
|
||||
font-size: var(--font-body);
|
||||
padding-top: 0;
|
||||
padding-bottom: 0;
|
||||
box-sizing: border-box;
|
||||
|
@ -69,7 +70,11 @@
|
|||
|
||||
.button--link {
|
||||
[data-mode='dark'] & {
|
||||
color: $lbry-teal-3;
|
||||
color: $lbry-teal-4;
|
||||
|
||||
&:hover {
|
||||
color: $lbry-teal-3;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -40,6 +40,11 @@
|
|||
.card--inline {
|
||||
border: 1px solid $lbry-gray-1;
|
||||
border-radius: var(--card-radius);
|
||||
margin-bottom: var(--spacing-medium);
|
||||
|
||||
&:last-of-type {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
[data-mode='dark'] & {
|
||||
border-color: var(--dm-color-03);
|
||||
|
@ -198,7 +203,7 @@
|
|||
font-size: var(--font-body);
|
||||
|
||||
[data-mode='dark'] & {
|
||||
background-color: var(--dm-color-04);
|
||||
background-color: var(--color-card-actions--dark);
|
||||
color: inherit;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@ $border-color--dark: var(--dm-color-04);
|
|||
font-size: var(--font-body);
|
||||
border-top-left-radius: var(--card-radius);
|
||||
border-top-right-radius: var(--card-radius);
|
||||
color: $lbry-white;
|
||||
background-color: var(--color-card-actions);
|
||||
|
||||
& > *:not(:last-child) {
|
||||
margin-right: 0.5rem;
|
||||
|
@ -26,22 +26,6 @@ $border-color--dark: var(--dm-color-04);
|
|||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
// Normal link buttons are too dark on the black file list background
|
||||
.button--link {
|
||||
color: $lbry-teal-3;
|
||||
|
||||
&:hover {
|
||||
color: $lbry-teal-1;
|
||||
}
|
||||
|
||||
[data-mode='dark'] & {
|
||||
color: $lbry-teal-4;
|
||||
&:hover {
|
||||
color: $lbry-teal-1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Fix this in @lbry/components, we shouldn't need to be this specific
|
||||
checkbox-element input[type='checkbox']:checked + label {
|
||||
color: $lbry-white;
|
||||
|
@ -49,6 +33,7 @@ $border-color--dark: var(--dm-color-04);
|
|||
|
||||
[data-mode='dark'] & {
|
||||
color: var(--dm-color-01);
|
||||
background-color: var(--color-card-actions--dark);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -61,25 +46,12 @@ $border-color--dark: var(--dm-color-04);
|
|||
margin-bottom: 0;
|
||||
padding: 0 var(--spacing-medium);
|
||||
padding-right: var(--spacing-large);
|
||||
background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 96 96' xmlns='http://www.w3.org/2000/svg' fill='%23ffffff'%3E%3Cpath d='M17.172, 31.172c1.562, -1.562 4.095, -1.562 5.656, 0l25.172, 25.171l25.172, -25.171c1.562, -1.562 4.095, -1.562 5.656, 0c1.562, 1.562 1.562, 4.095 0, 5.656l-28, 28c-1.562, 1.562 -4.095, 1.562 -5.656, 0l-28, -28c-0.781, -0.781 -1.172, -1.805 -1.172, -2.828c0, -1.023 0.391, -2.047 1.172, -2.828Z'/%3E%3C/svg%3E%0A");
|
||||
border: 1px solid $lbry-white;
|
||||
color: $lbry-white;
|
||||
background-color: lighten($lbry-black, 10%);
|
||||
|
||||
[data-mode='dark'] & {
|
||||
color: var(--dm-color-01);
|
||||
}
|
||||
}
|
||||
|
||||
.claim-list__header,
|
||||
.claim-list__dropdown {
|
||||
background-color: lighten($lbry-black, 10%);
|
||||
|
||||
[data-mode='dark'] & {
|
||||
background-color: var(--dm-color-07);
|
||||
}
|
||||
}
|
||||
|
||||
.claim-list__alt-controls {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
|
|
@ -18,12 +18,6 @@ form {
|
|||
}
|
||||
}
|
||||
|
||||
textarea {
|
||||
&::placeholder {
|
||||
opacity: 0.4;
|
||||
}
|
||||
}
|
||||
|
||||
// lbry/components overrides and minor styles
|
||||
// Some items have very specific styling
|
||||
// This is because many styles inside `lbry/components/sass/form/` are very specific
|
||||
|
@ -46,29 +40,35 @@ textarea {
|
|||
height: var(--input-height);
|
||||
padding-bottom: 0.1em;
|
||||
|
||||
&::placeholder {
|
||||
color: $lbry-gray-5;
|
||||
opacity: 0.4;
|
||||
}
|
||||
|
||||
[data-mode='dark'] & {
|
||||
&::placeholder {
|
||||
opacity: 0.4;
|
||||
color: $lbry-white;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
input,
|
||||
select,
|
||||
textarea {
|
||||
border-color: lighten($lbry-black, 20%);
|
||||
border-radius: var(--input-border-radius);
|
||||
background-color: $lbry-white;
|
||||
border-width: 1px;
|
||||
|
||||
[data-mode='dark'] & {
|
||||
background-color: var(--dm-color-02);
|
||||
}
|
||||
}
|
||||
|
||||
fieldset-section {
|
||||
margin-bottom: var(--spacing-small);
|
||||
|
||||
input,
|
||||
select,
|
||||
textarea {
|
||||
border-color: lighten($lbry-black, 20%);
|
||||
border-radius: var(--input-border-radius);
|
||||
background-color: $lbry-white;
|
||||
border-width: 1px;
|
||||
|
||||
[data-mode='dark'] & {
|
||||
background-color: var(--dm-color-03);
|
||||
border-color: $lbry-black;
|
||||
}
|
||||
}
|
||||
|
||||
label {
|
||||
width: auto;
|
||||
text-transform: none;
|
||||
|
@ -177,15 +177,6 @@ fieldset-group {
|
|||
width: 0;
|
||||
}
|
||||
|
||||
fieldset-section:first-child .form-field__prefix,
|
||||
fieldset-section:last-child input {
|
||||
border-color: $lbry-black;
|
||||
|
||||
[data-mode='dark'] {
|
||||
border-color: $lbry-gray-4;
|
||||
}
|
||||
}
|
||||
|
||||
fieldset-section:first-child {
|
||||
.form-field__prefix {
|
||||
white-space: nowrap;
|
||||
|
@ -201,7 +192,8 @@ fieldset-group {
|
|||
background-color: $lbry-white;
|
||||
|
||||
[data-mode='dark'] & {
|
||||
border-color: $lbry-gray-4;
|
||||
background-color: var(--dm-color-03);
|
||||
border-color: var(--dm-color-02);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -222,7 +214,7 @@ fieldset-group {
|
|||
|
||||
[data-mode='dark'] & {
|
||||
&:focus {
|
||||
border-image-source: linear-gradient(to right, $lbry-gray-4, $lbry-teal-5 5%);
|
||||
border-image-source: linear-gradient(to right, var(--dm-color-02), $lbry-teal-5 5%);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -289,8 +281,6 @@ fieldset-section {
|
|||
background-size: 1.2rem;
|
||||
|
||||
[data-mode='dark'] & {
|
||||
background-color: transparent;
|
||||
|
||||
option {
|
||||
background-color: $lbry-gray-5;
|
||||
}
|
||||
|
@ -304,10 +294,10 @@ fieldset-section {
|
|||
color: $lbry-white;
|
||||
}
|
||||
|
||||
input:not(:focus):not(.form-field--copyable),
|
||||
textarea:not(:focus),
|
||||
select:not(:focus) {
|
||||
border-color: var(--dm-color-04);
|
||||
input:not(.form-field--copyable),
|
||||
textarea,
|
||||
select {
|
||||
border-color: $lbry-gray-5;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,4 +15,16 @@
|
|||
position: absolute;
|
||||
stroke: $lbry-gray-5;
|
||||
}
|
||||
|
||||
[data-mode='dark'] & {
|
||||
background-color: var(--color-card-actions--dark);
|
||||
}
|
||||
}
|
||||
|
||||
.icon--help {
|
||||
margin-left: var(--spacing-small);
|
||||
bottom: -0.3rem;
|
||||
opacity: 0.7;
|
||||
height: 1rem;
|
||||
width: 1rem;
|
||||
}
|
||||
|
|
|
@ -74,6 +74,10 @@
|
|||
align-items: flex-start;
|
||||
max-width: 40rem;
|
||||
text-align: left;
|
||||
|
||||
& > * {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.main--full-width {
|
||||
|
|
|
@ -77,10 +77,10 @@
|
|||
}
|
||||
|
||||
[data-mode='dark'] & {
|
||||
color: var(--dm-color-01);
|
||||
color: darken($lbry-white, 30%);
|
||||
|
||||
svg {
|
||||
stroke: var(--dm-color-01);
|
||||
stroke: darken($lbry-white, 30%);
|
||||
}
|
||||
|
||||
&:hover,
|
||||
|
|
|
@ -48,8 +48,8 @@ $main: $lbry-teal-5;
|
|||
margin-top: -2px; // To handle the border height
|
||||
|
||||
[data-mode='dark'] & {
|
||||
background-color: var(--dm-color-02);
|
||||
border-color: $lbry-white;
|
||||
background-color: var(--dm-color-03);
|
||||
border-color: $lbry-gray-4;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,6 +20,10 @@
|
|||
position: absolute;
|
||||
z-index: 1;
|
||||
stroke: $lbry-gray-5;
|
||||
|
||||
[data-mode='dark'] & {
|
||||
stroke: $lbry-gray-3;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
}
|
||||
|
||||
.section--padded {
|
||||
padding: var(--spacing-large);
|
||||
padding: var(--spacing-medium);
|
||||
}
|
||||
|
||||
.section--small {
|
||||
|
@ -31,7 +31,6 @@
|
|||
@extend .section__flex;
|
||||
flex-wrap: wrap;
|
||||
margin-bottom: var(--spacing-large);
|
||||
|
||||
& > * {
|
||||
margin-bottom: var(--spacing-large);
|
||||
}
|
||||
|
|
|
@ -70,6 +70,7 @@ dl {
|
|||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
overflow-x: visible;
|
||||
margin-top: var(--spacing-medium);
|
||||
}
|
||||
|
||||
|
@ -284,12 +285,3 @@ legend {
|
|||
border-color: transparent;
|
||||
}
|
||||
}
|
||||
|
||||
checkbox-toggle,
|
||||
.checkbox-toggle,
|
||||
radio-toggle,
|
||||
.radio-toggle {
|
||||
[data-mode='dark'] & {
|
||||
border-color: var(--dm-color-04);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -41,6 +41,7 @@ $large-breakpoint: 1921px;
|
|||
--color-background: #f7f7f7;
|
||||
--color-background--splash: #270f34;
|
||||
--color-card-actions: #f7fbfe;
|
||||
--color-card-actions--dark: #545454;
|
||||
|
||||
// Dark Mode
|
||||
--dm-color-01: #ddd;
|
||||
|
|
|
@ -63,6 +63,7 @@ const whiteListedReducers = [
|
|||
'search',
|
||||
'blocked',
|
||||
'settings',
|
||||
'sync',
|
||||
];
|
||||
|
||||
const transforms = [
|
||||
|
|
|
@ -6858,9 +6858,9 @@ lbry-redux@lbryio/lbry-redux#85fe532d69704a283fd2ec640ad6e3b8dacd6d0d:
|
|||
reselect "^3.0.0"
|
||||
uuid "^3.3.2"
|
||||
|
||||
lbryinc@lbryio/lbryinc#a44576194e1f5f60e37d328ddfdca40bd6165c2d:
|
||||
lbryinc@lbryio/lbryinc#f5bee9cd300c4bdc05228e31ea15cfc430975f67:
|
||||
version "0.0.1"
|
||||
resolved "https://codeload.github.com/lbryio/lbryinc/tar.gz/a44576194e1f5f60e37d328ddfdca40bd6165c2d"
|
||||
resolved "https://codeload.github.com/lbryio/lbryinc/tar.gz/f5bee9cd300c4bdc05228e31ea15cfc430975f67"
|
||||
dependencies:
|
||||
reselect "^3.0.0"
|
||||
|
||||
|
|
Loading…
Reference in a new issue