From b9bd164b10e71867228d3e0a4ac5134ab54b4cb5 Mon Sep 17 00:00:00 2001 From: Thomas Zarebczan Date: Thu, 19 Aug 2021 16:09:31 -0400 Subject: [PATCH 01/58] format follower count --- ui/component/claimPreview/view.jsx | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/ui/component/claimPreview/view.jsx b/ui/component/claimPreview/view.jsx index 650839952..375ceb8b1 100644 --- a/ui/component/claimPreview/view.jsx +++ b/ui/component/claimPreview/view.jsx @@ -168,15 +168,17 @@ const ClaimPreview = forwardRef((props: Props, ref: any) => { const shouldHideActions = hideActions || isMyCollection || type === 'small' || type === 'tooltip'; const canonicalUrl = claim && claim.canonical_url; const lastCollectionIndex = collectionUris ? collectionUris.length - 1 : 0; + const channelSubscribers = React.useMemo(() => { if (channelSubCount === undefined) { return ; } + const formattedSubCount = Number(channelSubCount).toLocaleString(); return ( {channelSubCount === 1 - ? __('%channelSubCount% Follower', { channelSubCount }) - : __('%channelSubCount% Followers', { channelSubCount })} + ? __('%channelSubCount% Follower', { formattedSubCount }) + : __('%channelSubCount% Followers', { formattedSubCount })} ); }, [channelSubCount]); -- 2.45.3 From 6fe1923ef53436a00a48f1ec3d3ec9efc66c457f Mon Sep 17 00:00:00 2001 From: Thomas Zarebczan Date: Thu, 19 Aug 2021 16:17:15 -0400 Subject: [PATCH 02/58] fix lint --- ui/component/claimPreview/view.jsx | 1 - 1 file changed, 1 deletion(-) diff --git a/ui/component/claimPreview/view.jsx b/ui/component/claimPreview/view.jsx index 375ceb8b1..9b454fd90 100644 --- a/ui/component/claimPreview/view.jsx +++ b/ui/component/claimPreview/view.jsx @@ -168,7 +168,6 @@ const ClaimPreview = forwardRef((props: Props, ref: any) => { const shouldHideActions = hideActions || isMyCollection || type === 'small' || type === 'tooltip'; const canonicalUrl = claim && claim.canonical_url; const lastCollectionIndex = collectionUris ? collectionUris.length - 1 : 0; - const channelSubscribers = React.useMemo(() => { if (channelSubCount === undefined) { return ; -- 2.45.3 From 15b076fd2024cbae40f121382db5e9bbcf7c5e49 Mon Sep 17 00:00:00 2001 From: Anthony Date: Wed, 18 Aug 2021 20:06:12 +0200 Subject: [PATCH 03/58] fix merge conflicts --- ui/component/common/credit-amount.jsx | 5 + ui/component/txoList/view.jsx | 233 ++++++++++++++++-- ui/component/walletBalance/view.jsx | 7 + .../walletFiatAccountHistory/view.jsx | 111 ++++----- ui/component/walletFiatBalance/view.jsx | 104 ++++---- .../walletFiatPaymentHistory/view.jsx | 133 +++++----- ui/page/wallet/view.jsx | 215 +++++----------- 7 files changed, 441 insertions(+), 367 deletions(-) diff --git a/ui/component/common/credit-amount.jsx b/ui/component/common/credit-amount.jsx index b22e63cab..92adbba4c 100644 --- a/ui/component/common/credit-amount.jsx +++ b/ui/component/common/credit-amount.jsx @@ -49,6 +49,11 @@ class CreditAmount extends React.PureComponent { isFiat, } = this.props; const minimumRenderableAmount = 10 ** (-1 * precision); + + // return null, otherwise it will try and convert undefined to a string + if (amount === undefined) { + return null; + } const fullPrice = formatFullPrice(amount, 2); const isFree = parseFloat(amount) === 0; diff --git a/ui/component/txoList/view.jsx b/ui/component/txoList/view.jsx index e07b3e6b1..9153842b5 100644 --- a/ui/component/txoList/view.jsx +++ b/ui/component/txoList/view.jsx @@ -12,6 +12,17 @@ import { toCapitalCase } from 'util/string'; import classnames from 'classnames'; import HelpLink from 'component/common/help-link'; import FileExporter from 'component/common/file-exporter'; +import WalletFiatPaymentHistory from 'component/walletFiatPaymentHistory'; +import WalletFiatAccountHistory from 'component/walletFiatAccountHistory'; +import { STRIPE_PUBLIC_KEY } from '../../../config'; +import { Lbryio } from 'lbryinc'; + +let stripeEnvironment = 'test'; +// if the key contains pk_live it's a live key +// update the environment for the calls to the backend to indicate which environment to hit +if (STRIPE_PUBLIC_KEY.indexOf('pk_live') > -1) { + stripeEnvironment = 'live'; +} type Props = { search: string, @@ -30,6 +41,7 @@ type Props = { type Delta = { dkey: string, value: string, + tab: string }; function TxoList(props: Props) { @@ -45,12 +57,72 @@ function TxoList(props: Props) { transactionsFile, } = props; + const [accountTransactionResponse, setAccountTransactionResponse] = React.useState([]); + const [customerTransactions, setCustomerTransactions] = React.useState([]); + + function getPaymentHistory() { + return Lbryio.call( + 'customer', + 'list', + { + environment: stripeEnvironment, + }, + 'post' + ); + } + + function getAccountTransactionsa() { + return Lbryio.call( + 'account', + 'list', + { + environment: stripeEnvironment, + }, + 'post' + ); + } + + // calculate account transactions section + React.useEffect(() => { + (async function() { + try { + const getAccountTransactions = await getAccountTransactionsa(); + + setAccountTransactionResponse(getAccountTransactions); + } catch (err) { + console.log(err); + } + })(); + }, []); + + // populate customer payment data + React.useEffect(() => { + (async function() { + try { + // get card payments customer has made + let customerTransactionResponse = await getPaymentHistory(); + // console.log('amount of transactions'); + // console.log(customerTransactionResponse.length); + + if (customerTransactionResponse && customerTransactionResponse.length) { + customerTransactionResponse.reverse(); + } + + setCustomerTransactions(customerTransactionResponse); + } catch (err) { + console.log(err); + } + })(); + }, []); + const urlParams = new URLSearchParams(search); const page = urlParams.get(TXO.PAGE) || String(1); const pageSize = urlParams.get(TXO.PAGE_SIZE) || String(TXO.PAGE_SIZE_DEFAULT); const type = urlParams.get(TXO.TYPE) || TXO.ALL; const subtype = urlParams.get(TXO.SUB_TYPE); const active = urlParams.get(TXO.ACTIVE) || TXO.ALL; + const currency = urlParams.get('currency') || 'credits'; + const fiatType = urlParams.get('fiatType') || 'incoming'; const currentUrlParams = { page, @@ -58,6 +130,8 @@ function TxoList(props: Props) { active, type, subtype, + currency, + fiatType, }; const hideStatus = @@ -119,8 +193,32 @@ function TxoList(props: Props) { history.push(url); } + // let currency = 'credits'; function updateUrl(delta: Delta) { const newUrlParams = new URLSearchParams(); + + const existingCurrency = newUrlParams.get('currency') || 'credits'; + + const existingFiatType = newUrlParams.get('fiatType') || 'incoming'; + + console.log(existingFiatType); + + console.log(newUrlParams); + + // set tab name to account for wallet page tab + newUrlParams.set('tab', delta.tab); + + // only update currency if it's being changed + if (delta.currency) { + newUrlParams.set('currency', delta.currency); + } + + if (delta.fiatType) { + newUrlParams.set('fiatType', delta.fiatType); + } else { + newUrlParams.set('fiatType', existingFiatType); + } + switch (delta.dkey) { case TXO.PAGE: if (currentUrlParams.type) { @@ -179,6 +277,10 @@ function TxoList(props: Props) { const paramsString = JSON.stringify(params); + // tab used in the wallet section + // TODO: change the name of this eventually + const tab = 'fiat-payment-history'; + useEffect(() => { if (paramsString && updateTxoPageParams) { const params = JSON.parse(paramsString); @@ -188,28 +290,54 @@ function TxoList(props: Props) { return ( {__(`Transactions`)}} - titleActions={ -
- {!isFetchingTransactions && transactionsFile === null && ( - - )} -
- fetchTransactions()} - progressMsg={isFetchingTransactions ? __('Fetching data') : ''} - /> + title={ + <>
{__(`Transactions`)}
+
+ +
+
+
-
+ + + } + titleActions={<> + //
+ // {!isFetchingTransactions && transactionsFile === null && ( + // + // )} + //
+ // fetchTransactions()} + // progressMsg={isFetchingTransactions ? __('Fetching data') : ''} + // /> + //
+ //
} isBodyList - body={ -
+ body={currency === 'credits' + ?
@@ -223,7 +351,7 @@ function TxoList(props: Props) { } value={type || 'all'} - onChange={(e) => handleChange({ dkey: TXO.TYPE, value: e.target.value })} + onChange={(e) => handleChange({ dkey: TXO.TYPE, value: e.target.value, tab })} > {Object.values(TXO.DROPDOWN_TYPES).map((v) => { const stringV = String(v); @@ -242,7 +370,7 @@ function TxoList(props: Props) { name="subtype" label={__('Payment Type')} value={subtype || 'all'} - onChange={(e) => handleChange({ dkey: TXO.SUB_TYPE, value: e.target.value })} + onChange={(e) => handleChange({ dkey: TXO.SUB_TYPE, value: e.target.value, tab })} > {Object.values(TXO.DROPDOWN_SUBTYPES).map((v) => { const stringV = String(v); @@ -262,7 +390,7 @@ function TxoList(props: Props) {
)} +
+ {!isFetchingTransactions && transactionsFile === null && ( + + )} +
+ fetchTransactions()} + progressMsg={isFetchingTransactions ? __('Fetching data') : ''} + /> +
+
+ {/* listing of the transactions */}
+ :
+ {/* fiat section (buttons and transactions) */} +
+
+
+ {!hideStatus && ( +
+ + +
+
+
+
+ )} +
+
+ {/* listing of the transactions */} + { fiatType === 'incoming' && } + { fiatType === 'outgoing' && } + {/* TODO: have to finish pagination */} + {/* */} +
+
} + /> ); } diff --git a/ui/component/walletBalance/view.jsx b/ui/component/walletBalance/view.jsx index 6746d5c36..4b6c06ca5 100644 --- a/ui/component/walletBalance/view.jsx +++ b/ui/component/walletBalance/view.jsx @@ -10,6 +10,8 @@ import Card from 'component/common/card'; import LbcSymbol from 'component/common/lbc-symbol'; import I18nMessage from 'component/i18nMessage'; import { formatNumberWithCommas } from 'util/number'; +import Icon from 'component/common/icon'; +import WalletFiatBalance from 'component/walletFiatBalance'; type Props = { balance: number, @@ -63,6 +65,7 @@ const WalletBalance = (props: Props) => { }, [doFetchUtxoCounts, balance, detailsExpanded]); return ( +
} subtitle={ @@ -181,6 +184,10 @@ const WalletBalance = (props: Props) => { } /> + + {/* fiat balance card */} + +
); }; diff --git a/ui/component/walletFiatAccountHistory/view.jsx b/ui/component/walletFiatAccountHistory/view.jsx index 49b1ff299..07616c2f7 100644 --- a/ui/component/walletFiatAccountHistory/view.jsx +++ b/ui/component/walletFiatAccountHistory/view.jsx @@ -21,67 +21,60 @@ const WalletBalance = (props: Props) => { } // if there are more than 10 transactions, limit it to 10 for the frontend - if (accountTransactions && accountTransactions.length > 10) { - accountTransactions.length = 10; - } + // if (accountTransactions && accountTransactions.length > 10) { + // accountTransactions.length = 10; + // } return ( - <> -
- - - - - - - - - - - - - - {accountTransactions && - accountTransactions.map((transaction) => ( - - - - - - - - - - ))} - -
{__('Date')}{<>{__('Receiving Channel Name')}}{__('Tip Location')}{__('Amount (USD)')} {__('Processing Fee')}{__('Odysee Fee')}{__('Received Amount')}
{moment(transaction.created_at).format('LLL')} - - ${transaction.tipped_amount / 100}${transaction.transaction_fee / 100}${transaction.application_fee / 100}${transaction.received_amount / 100}
- {!accountTransactions &&

No Transactions

} -
- - )} - /> - +
+ + + + + + + + + + + + + + {accountTransactions && + accountTransactions.map((transaction) => ( + + + + + + + + + + ))} + +
{__('Date')}{<>{__('Receiving Channel Name')}}{__('Tip Location')}{__('Amount (USD)')} {__('Processing Fee')}{__('Odysee Fee')}{__('Received Amount')}
{moment(transaction.created_at).format('LLL')} + + ${transaction.tipped_amount / 100}${transaction.transaction_fee / 100}${transaction.application_fee / 100}${transaction.received_amount / 100}
+ {!accountTransactions &&

No Transactions

} +
+ ); }; diff --git a/ui/component/walletFiatBalance/view.jsx b/ui/component/walletFiatBalance/view.jsx index 9c71623ba..a58373e7f 100644 --- a/ui/component/walletFiatBalance/view.jsx +++ b/ui/component/walletFiatBalance/view.jsx @@ -6,83 +6,69 @@ import Button from 'component/button'; import Card from 'component/common/card'; import Icon from 'component/common/icon'; import I18nMessage from 'component/i18nMessage'; +import { Lbryio } from 'lbryinc'; +import { STRIPE_PUBLIC_KEY } from 'config'; -type Props = { - accountDetails: any, -}; +let stripeEnvironment = 'test'; +// if the key contains pk_live it's a live key +// update the environment for the calls to the backend to indicate which environment to hit +if (STRIPE_PUBLIC_KEY.indexOf('pk_live') > -1) { + stripeEnvironment = 'live'; +} const WalletBalance = (props: Props) => { - const { - accountDetails, - } = props; + const [accountStatusResponse, setAccountStatusResponse] = React.useState(); + + function getAccountStatus() { + return Lbryio.call( + 'account', + 'status', + { + environment: stripeEnvironment, + }, + 'post' + ); + } + + // calculate account transactions section + React.useEffect(() => { + (async function () { + try { + if (!stripeEnvironment) { + return; + } + const response = await getAccountStatus(); + + setAccountStatusResponse(response); + + } catch (err) { + console.log(err); + } + })(); + }, [stripeEnvironment]); return ( <>{{(accountDetails && ((accountDetails.total_received_unpaid - accountDetails.total_paid_out) / 100)) || 0} USD} - subtitle={accountDetails && accountDetails.total_received_unpaid > 0 && + title={<>{(accountStatusResponse && ((accountStatusResponse.total_received_unpaid - accountStatusResponse.total_paid_out) / 100)) || 0} USD} + subtitle={accountStatusResponse && accountStatusResponse.total_received_unpaid > 0 ? ( This is your pending balance that will be automatically sent to your bank account - + ) : ( + + When you begin to receive tips your balance will be updated here + ) } actions={ <>

- ${(accountDetails && (accountDetails.total_received_unpaid / 100)) || 0} Total Received Tips + ${(accountStatusResponse && (accountStatusResponse.total_received_unpaid / 100)) || 0} Total Received Tips

- ${(accountDetails && (accountDetails.total_paid_out / 100)) || 0} Withdrawn - {/*

- {/* view more section */} - {/* commenting out because not implemented, but could be used in the future */} - {/* {detailsExpanded && ( */} - {/*
*/} - {/*
*/} - {/*
*/} - {/* {__('Earned from uploads')} */} - {/* /!* ({__('Earned from channel page')}) *!/ */} - {/*
*/} - {/*
*/} - {/* */} - {/* {Boolean(1) && ( */} - {/*
*/} - - {/*
*/} - {/* {__('Earned from channel page')} */} - {/* /!* ({__('Delete or edit past content to spend')}) *!/ */} - {/*
*/} - {/*
*/} - {/* */} - {/*
*/} - - {/* /!*
*!/ */} - {/* /!* {__('...supporting content')} *!/ */} - {/* /!* ({__('Delete supports to spend')}) *!/ */} - {/* /!*
*!/ */} - {/* /!*
*!/ */} - {/* /!* *!/ */} - {/* /!*
*!/ */} - {/*
*/} - {/*
*/} - {/* )} */} -
- {/*
diff --git a/ui/component/walletFiatPaymentHistory/view.jsx b/ui/component/walletFiatPaymentHistory/view.jsx index 45d55bde7..1e0ea0383 100644 --- a/ui/component/walletFiatPaymentHistory/view.jsx +++ b/ui/component/walletFiatPaymentHistory/view.jsx @@ -1,7 +1,6 @@ // @flow import React from 'react'; import Button from 'component/button'; -import Card from 'component/common/card'; import { Lbryio } from 'lbryinc'; import moment from 'moment'; import { getStripeEnvironment } from 'util/stripe'; @@ -16,10 +15,6 @@ const WalletBalance = (props: Props) => { // receive transactions from parent component const { transactions: accountTransactions } = props; - // const [accountStatusResponse, setAccountStatusResponse] = React.useState(); - - // const [subscriptions, setSubscriptions] = React.useState(); - const [lastFour, setLastFour] = React.useState(); function getCustomerStatus() { @@ -35,78 +30,76 @@ const WalletBalance = (props: Props) => { // TODO: this is actually incorrect, last4 should be populated based on the transaction not the current customer details React.useEffect(() => { - (async function () { - const customerStatusResponse = await getCustomerStatus(); + (async function() { + const customerStatusResponse = await getCustomerStatus(); - const lastFour = - customerStatusResponse.PaymentMethods && - customerStatusResponse.PaymentMethods.length && - customerStatusResponse.PaymentMethods[0].card.last4; + const lastFour = customerStatusResponse.PaymentMethods && customerStatusResponse.PaymentMethods.length && customerStatusResponse.PaymentMethods[0].card.last4; - setLastFour(lastFour); + setLastFour(lastFour); })(); }, []); return ( <> - -
- - - - - - - - - - - - - {accountTransactions && - accountTransactions.map((transaction) => ( - - - - - - - - - ))} - -
{__('Date')}{<>{__('Receiving Channel Name')}}{__('Tip Location')}{__('Amount (USD)')} {__('Card Last 4')}{__('Anonymous')}
{moment(transaction.created_at).format('LLL')} - - ${transaction.tipped_amount / 100}{lastFour}{transaction.private_tip ? 'Yes' : 'No'}
- {(!accountTransactions || accountTransactions.length === 0) && ( -

- No Transactions -

- )} -
- - } - /> - +
+
+ + {/* table header */} + + + + + + + + + + + {/* list data for transactions */} + + {accountTransactions && + accountTransactions.map((transaction) => ( + + {/* date */} + + {/* receiving channel name */} + + {/* link to content or channel */} + + {/* how much tipped */} + + {/* TODO: this is incorrect need it per transactions not per user */} + {/* last four of credit card */} + + {/* whether tip is anonymous or not */} + + + ))} + +
{__('Date')}{<>{__('Receiving Channel Name')}}{__('Tip Location')}{__('Amount (USD)')} {__('Card Last 4')}{__('Anonymous')}
{moment(transaction.created_at).format('LLL')} + + ${transaction.tipped_amount / 100}{lastFour}{transaction.private_tip ? 'Yes' : 'No'}
+ {/* show some markup if there's no transactions */} + {(!accountTransactions || accountTransactions.length === 0) &&

No Transactions

} +
+
+ ); }; diff --git a/ui/page/wallet/view.jsx b/ui/page/wallet/view.jsx index d056e74d9..a2c071327 100644 --- a/ui/page/wallet/view.jsx +++ b/ui/page/wallet/view.jsx @@ -2,10 +2,6 @@ import React from 'react'; import { useHistory } from 'react-router'; import WalletBalance from 'component/walletBalance'; -import WalletFiatBalance from 'component/walletFiatBalance'; -import WalletFiatPaymentBalance from 'component/walletFiatPaymentBalance'; -import WalletFiatAccountHistory from 'component/walletFiatAccountHistory'; -import WalletFiatPaymentHistory from 'component/walletFiatPaymentHistory'; import TxoList from 'component/txoList'; import Page from 'component/page'; import * as PAGES from 'constants/pages'; @@ -73,84 +69,6 @@ const WalletPage = (props: Props) => { push(url); } - const [accountStatusResponse, setAccountStatusResponse] = React.useState(); - const [accountTransactionResponse, setAccountTransactionResponse] = React.useState([]); - const [customerTransactions, setCustomerTransactions] = React.useState([]); - - function getPaymentHistory() { - return Lbryio.call( - 'customer', - 'list', - { - environment: stripeEnvironment, - }, - 'post' - ); - } - - function getAccountStatus() { - return Lbryio.call( - 'account', - 'status', - { - environment: stripeEnvironment, - }, - 'post' - ); - } - - function getAccountTransactionsa() { - return Lbryio.call( - 'account', - 'list', - { - environment: stripeEnvironment, - }, - 'post' - ); - } - - // calculate account transactions section - React.useEffect(() => { - (async function () { - try { - if (!stripeEnvironment) { - return; - } - const response = await getAccountStatus(); - - setAccountStatusResponse(response); - - // TODO: some weird naming clash hence getAccountTransactionsa - const getAccountTransactions = await getAccountTransactionsa(); - - setAccountTransactionResponse(getAccountTransactions); - } catch (err) { - console.log(err); - } - })(); - }, [stripeEnvironment]); - - // populate customer payment data - React.useEffect(() => { - (async function () { - try { - // get card payments customer has made - if (!stripeEnvironment) { - return; - } - let customerTransactionResponse = await getPaymentHistory(); - if (customerTransactionResponse && customerTransactionResponse.length) { - customerTransactionResponse.reverse(); - } - - setCustomerTransactions(customerTransactionResponse); - } catch (err) { - console.log(err); - } - })(); - }, [stripeEnvironment]); - // @endif const { totalBalance } = props; @@ -159,80 +77,67 @@ const WalletPage = (props: Props) => { return ( <> - {stripeEnvironment && ( - - - - {__('LBRY Credits')} - {__('Account History')} - {__('Payment History')} - - - -
-
- {/* if the transactions are loading */} - {loading && ( -
- -
- )} - {/* when the transactions are finished loading */} - {!loading && ( - <> - {showIntro ? ( - - ) : ( -
- - -
- )} - - )} -
+ {/* @if TARGET='web' */} + + + + {__('Balance')} + {__('Transactions')} + + + {/* balances for lbc and fiat */} + + + + {/* transactions panel */} + +
+
+ {/* if the transactions are loading */} + {loading && ( +
+ +
+ )} + {/* when the transactions are finished loading */} + {!loading && ( + <> + {showIntro ? ( + + ) : ( +
+ +
+ )} + + )}
- - -
- - -
-
- -
- - -
-
- - - - )} - {!stripeEnvironment && ( - - {loading && ( -
- -
- )} - {!loading && ( - <> - {showIntro ? ( - - ) : ( -
- - -
- )} - - )} -
- )} +
+
+
+
+
+ {/* @endif */} + {/* @if TARGET='app' */} + + {loading && ( +
+ +
+ )} + {!loading && ( + <> + {showIntro ? ( + + ) : ( +
+ +
+ )} + + )} +
+ {/* @endif */} ); }; -- 2.45.3 From 6ae732b77bedb28eee961f17742871ca96c47df8 Mon Sep 17 00:00:00 2001 From: Anthony Date: Thu, 19 Aug 2021 22:23:20 +0200 Subject: [PATCH 04/58] pr fixes --- ui/component/txoList/view.jsx | 32 ++++---------------------------- ui/scss/component/_txo-list.scss | 5 +++++ 2 files changed, 9 insertions(+), 28 deletions(-) diff --git a/ui/component/txoList/view.jsx b/ui/component/txoList/view.jsx index 9153842b5..436a11974 100644 --- a/ui/component/txoList/view.jsx +++ b/ui/component/txoList/view.jsx @@ -71,7 +71,7 @@ function TxoList(props: Props) { ); } - function getAccountTransactionsa() { + function getAccountTransactions() { return Lbryio.call( 'account', 'list', @@ -86,9 +86,9 @@ function TxoList(props: Props) { React.useEffect(() => { (async function() { try { - const getAccountTransactions = await getAccountTransactionsa(); + const accountTransactionResponse = await getAccountTransactions(); - setAccountTransactionResponse(getAccountTransactions); + setAccountTransactionResponse(accountTransactionResponse); } catch (err) { console.log(err); } @@ -197,14 +197,8 @@ function TxoList(props: Props) { function updateUrl(delta: Delta) { const newUrlParams = new URLSearchParams(); - const existingCurrency = newUrlParams.get('currency') || 'credits'; - const existingFiatType = newUrlParams.get('fiatType') || 'incoming'; - console.log(existingFiatType); - - console.log(newUrlParams); - // set tab name to account for wallet page tab newUrlParams.set('tab', delta.tab); @@ -291,7 +285,7 @@ function TxoList(props: Props) { return (
{__(`Transactions`)}
+ <>
{__(`Transactions`)}
@@ -317,24 +311,6 @@ function TxoList(props: Props) { } - titleActions={<> - //
- // {!isFetchingTransactions && transactionsFile === null && ( - // - // )} - //
- // fetchTransactions()} - // progressMsg={isFetchingTransactions ? __('Fetching data') : ''} - // /> - //
- //
- } isBodyList body={currency === 'credits' ?
diff --git a/ui/scss/component/_txo-list.scss b/ui/scss/component/_txo-list.scss index 58d38adf5..a9088378b 100644 --- a/ui/scss/component/_txo-list.scss +++ b/ui/scss/component/_txo-list.scss @@ -10,3 +10,8 @@ display: block; } } + +.table__header-text { + width: 124px; + display: inline-block; +} -- 2.45.3 From 51576a827d1fbe1cd2f79ff3352589d91345d4c4 Mon Sep 17 00:00:00 2001 From: Thomas Zarebczan Date: Thu, 19 Aug 2021 16:32:03 -0400 Subject: [PATCH 05/58] Update view.jsx --- ui/component/claimPreview/view.jsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ui/component/claimPreview/view.jsx b/ui/component/claimPreview/view.jsx index 9b454fd90..5370d14f4 100644 --- a/ui/component/claimPreview/view.jsx +++ b/ui/component/claimPreview/view.jsx @@ -176,8 +176,8 @@ const ClaimPreview = forwardRef((props: Props, ref: any) => { return ( {channelSubCount === 1 - ? __('%channelSubCount% Follower', { formattedSubCount }) - : __('%channelSubCount% Followers', { formattedSubCount })} + ? __('%formattedSubCount% Follower', { formattedSubCount }) + : __('%formattedSubCount% Followers', { formattedSubCount })} ); }, [channelSubCount]); -- 2.45.3 From f8c568e301559685499b5f620a5ec85c1f3c1f94 Mon Sep 17 00:00:00 2001 From: Thomas Zarebczan Date: Thu, 19 Aug 2021 16:46:34 -0400 Subject: [PATCH 06/58] Fix random crash Fixes https://github.com/lbryio/lbry-desktop/issues/6918 --- ui/component/previewOverlayProperties/view.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/component/previewOverlayProperties/view.jsx b/ui/component/previewOverlayProperties/view.jsx index b428a1c3f..53c9a2182 100644 --- a/ui/component/previewOverlayProperties/view.jsx +++ b/ui/component/previewOverlayProperties/view.jsx @@ -36,7 +36,7 @@ export default function PreviewOverlayProperties(props: Props) { } = props; const isCollection = claim && claim.value_type === 'collection'; // $FlowFixMe - const claimLength = claim && claim.value.claims && claim.value.claims.length; + const claimLength = claim && claim.value && claim.value.claims && claim.value.claims.length; const claimCount = editedCollection ? editedCollection.items.length : claimLength; const isStream = claim && claim.value_type === 'stream'; -- 2.45.3 From bcb1197dfb536f783c711fdc20226759abc55d4c Mon Sep 17 00:00:00 2001 From: Anthony Date: Thu, 19 Aug 2021 23:20:01 +0200 Subject: [PATCH 07/58] fixes for flow and linter --- ui/component/txoList/view.jsx | 19 ++++++++++++++----- ui/component/walletBalance/view.jsx | 1 - .../walletFiatAccountHistory/view.jsx | 1 - ui/component/walletFiatBalance/view.jsx | 13 +++---------- ui/page/wallet/view.jsx | 4 ---- 5 files changed, 17 insertions(+), 21 deletions(-) diff --git a/ui/component/txoList/view.jsx b/ui/component/txoList/view.jsx index 436a11974..897da504e 100644 --- a/ui/component/txoList/view.jsx +++ b/ui/component/txoList/view.jsx @@ -39,9 +39,11 @@ type Props = { }; type Delta = { - dkey: string, - value: string, - tab: string + dkey?: string, + value?: string, + tab?: string, + currency?: string, + fiatType?: string }; function TxoList(props: Props) { @@ -197,10 +199,17 @@ function TxoList(props: Props) { function updateUrl(delta: Delta) { const newUrlParams = new URLSearchParams(); + // fix for flow, maybe there is a better way? + if (!delta.value) { + delta.value = ''; + } + const existingFiatType = newUrlParams.get('fiatType') || 'incoming'; - // set tab name to account for wallet page tab - newUrlParams.set('tab', delta.tab); + if (delta.tab) { + // set tab name to account for wallet page tab + newUrlParams.set('tab', delta.tab); + } // only update currency if it's being changed if (delta.currency) { diff --git a/ui/component/walletBalance/view.jsx b/ui/component/walletBalance/view.jsx index 4b6c06ca5..71d4dba67 100644 --- a/ui/component/walletBalance/view.jsx +++ b/ui/component/walletBalance/view.jsx @@ -10,7 +10,6 @@ import Card from 'component/common/card'; import LbcSymbol from 'component/common/lbc-symbol'; import I18nMessage from 'component/i18nMessage'; import { formatNumberWithCommas } from 'util/number'; -import Icon from 'component/common/icon'; import WalletFiatBalance from 'component/walletFiatBalance'; type Props = { diff --git a/ui/component/walletFiatAccountHistory/view.jsx b/ui/component/walletFiatAccountHistory/view.jsx index 07616c2f7..b9b7dbd19 100644 --- a/ui/component/walletFiatAccountHistory/view.jsx +++ b/ui/component/walletFiatAccountHistory/view.jsx @@ -1,7 +1,6 @@ // @flow import React from 'react'; import Button from 'component/button'; -import Card from 'component/common/card'; import moment from 'moment'; type Props = { diff --git a/ui/component/walletFiatBalance/view.jsx b/ui/component/walletFiatBalance/view.jsx index a58373e7f..f8bfc874f 100644 --- a/ui/component/walletFiatBalance/view.jsx +++ b/ui/component/walletFiatBalance/view.jsx @@ -7,16 +7,10 @@ import Card from 'component/common/card'; import Icon from 'component/common/icon'; import I18nMessage from 'component/i18nMessage'; import { Lbryio } from 'lbryinc'; -import { STRIPE_PUBLIC_KEY } from 'config'; +import { getStripeEnvironment } from 'util/stripe'; +let stripeEnvironment = getStripeEnvironment(); -let stripeEnvironment = 'test'; -// if the key contains pk_live it's a live key -// update the environment for the calls to the backend to indicate which environment to hit -if (STRIPE_PUBLIC_KEY.indexOf('pk_live') > -1) { - stripeEnvironment = 'live'; -} - -const WalletBalance = (props: Props) => { +const WalletBalance = () => { const [accountStatusResponse, setAccountStatusResponse] = React.useState(); function getAccountStatus() { @@ -40,7 +34,6 @@ const WalletBalance = (props: Props) => { const response = await getAccountStatus(); setAccountStatusResponse(response); - } catch (err) { console.log(err); } diff --git a/ui/page/wallet/view.jsx b/ui/page/wallet/view.jsx index a2c071327..cd667949a 100644 --- a/ui/page/wallet/view.jsx +++ b/ui/page/wallet/view.jsx @@ -7,9 +7,7 @@ import Page from 'component/page'; import * as PAGES from 'constants/pages'; import Spinner from 'component/spinner'; import YrblWalletEmpty from 'component/yrblWalletEmpty'; -import { Lbryio } from 'lbryinc'; import { Tabs, TabList, Tab, TabPanels, TabPanel } from 'component/common/tabs'; -import { getStripeEnvironment } from 'util/stripe'; const TAB_QUERY = 'tab'; @@ -19,8 +17,6 @@ const TABS = { PAYMENT_HISTORY: 'fiat-payment-history', }; -let stripeEnvironment = getStripeEnvironment(); - type Props = { history: { action: string, push: (string) => void, replace: (string) => void }, location: { search: string, pathname: string }, -- 2.45.3 From ffe22e1c5035e64021e92bf272a824b128223ff5 Mon Sep 17 00:00:00 2001 From: infinite-persistence Date: Fri, 20 Aug 2021 09:21:26 +0800 Subject: [PATCH 08/58] i18n --- static/app-strings.json | 13 +++++++++---- ui/component/claimPreview/view.jsx | 4 +--- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/static/app-strings.json b/static/app-strings.json index 896dd1b96..7b2e6774a 100644 --- a/static/app-strings.json +++ b/static/app-strings.json @@ -1450,7 +1450,6 @@ "Controversial": "Controversial", "Show Replies": "Show Replies", "Hide replies": "Hide replies", - "Unable to create comment, please try again later.": "Unable to create comment, please try again later.", "Unable to comment. This channel has blocked you.": "Unable to comment. This channel has blocked you.", "Unable to comment. Your channel has been blocked by an admin.": "Unable to comment. Your channel has been blocked by an admin.", "Unable to comment. The content owner has disabled comments.": "Unable to comment. The content owner has disabled comments.", @@ -1621,7 +1620,7 @@ "No Reposts Found": "No Reposts Found", "Publish Something": "Publish Something", "Repost Something": "Repost Something", - "Watch on lbry.tv": "Watch on lbry.tv", + "Watch on %SITE_NAME%": "Watch on %SITE_NAME%", "Paid content cannot be embedded.": "Paid content cannot be embedded.", "Please wait a bit, we are still getting your account ready.": "Please wait a bit, we are still getting your account ready.", "this channel is connected to a different account. Contact hello@lbry.com for help.": "this channel is connected to a different account. Contact hello@lbry.com for help.", @@ -1944,6 +1943,7 @@ "Enabling a minimum amount to comment will force all comments, including livestreams, to have tips associated with them. This can help prevent spam.": "Enabling a minimum amount to comment will force all comments, including livestreams, to have tips associated with them. This can help prevent spam.", "Minimum %lbc% tip amount for hyperchats": "Minimum %lbc% tip amount for hyperchats", "Enabling a minimum amount to hyperchat will force all TIPPED comments to have this value in order to be shown. This still allows regular comments to be posted.": "Enabling a minimum amount to hyperchat will force all TIPPED comments to have this value in order to be shown. This still allows regular comments to be posted.", + "This settings is not applicable if all comments require a tip.": "This settings is not applicable if all comments require a tip.", "Settings unavailable for this channel": "Settings unavailable for this channel", "This channel isn't staking enough LBRY Credits to enable Creator Settings.": "This channel isn't staking enough LBRY Credits to enable Creator Settings.", "Not a channel (prefix with \"@\", or enter the channel URL)": "Not a channel (prefix with \"@\", or enter the channel URL)", @@ -2090,10 +2090,15 @@ "Expand Comments": "Expand Comments", "Expand": "Expand", "Load More": "Load More", - "%channelSubCount% Followers": "%channelSubCount% Followers", - "%channelSubCount% Follower": "%channelSubCount% Follower", + "%formattedSubCount% Followers": "%formattedSubCount% Followers", + "1 Follower": "1 Follower", "Collection": "Collection", "%channelName% isn't live right now, but the chat is! Check back later to watch the stream.": "%channelName% isn't live right now, but the chat is! Check back later to watch the stream.", "Review": "Review", + "Account History": "Account History", + "Payment History": "Payment History", + "There was an error from the server, please try again later": "There was an error from the server, please try again later", + "There was an error getting your card setup, please try again later": "There was an error getting your card setup, please try again later", + "View Transactions": "View Transactions", "--end--": "--end--" } diff --git a/ui/component/claimPreview/view.jsx b/ui/component/claimPreview/view.jsx index 5370d14f4..2e1844ac9 100644 --- a/ui/component/claimPreview/view.jsx +++ b/ui/component/claimPreview/view.jsx @@ -175,9 +175,7 @@ const ClaimPreview = forwardRef((props: Props, ref: any) => { const formattedSubCount = Number(channelSubCount).toLocaleString(); return ( - {channelSubCount === 1 - ? __('%formattedSubCount% Follower', { formattedSubCount }) - : __('%formattedSubCount% Followers', { formattedSubCount })} + {channelSubCount === 1 ? __('1 Follower') : __('%formattedSubCount% Followers', { formattedSubCount })} ); }, [channelSubCount]); -- 2.45.3 From 6e018c74623c9ec712c79e924e087b92f77f1d84 Mon Sep 17 00:00:00 2001 From: zeppi Date: Fri, 20 Aug 2021 10:11:23 -0400 Subject: [PATCH 09/58] v0.51.2 --- CHANGELOG.md | 3 ++- package.json | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a6118a90e..0f9356a7d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,13 +3,14 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). -## [Unreleased for Desktop] +## [0.51.1] - [2021-08-20] ### Added - Show currently active playing item on playlist _community pr!_ ([#6453](https://github.com/lbryio/lbry-desktop/pull/6453)) - Add watch later to hover action for last used playlist on popup _community pr!_ ([#6274](https://github.com/lbryio/lbry-desktop/pull/6274)) - Add confirmation on comment removal _community pr!_ ([#6563](https://github.com/lbryio/lbry-desktop/pull/6563)) - Show on content page if a file is part of a playlist already _community pr!_([#6393](https://github.com/lbryio/lbry-desktop/pull/6393)) +- Add filtering to playlists ([#6905](https://github.com/lbryio/lbry-desktop/pull/6905)) ### Changed - Use Canonical Url for copy link ([#6500](https://github.com/lbryio/lbry-desktop/pull/6500)) diff --git a/package.json b/package.json index 301ccd167..5e5db1f0a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "lbry", - "version": "0.51.2-rc.4", + "version": "0.51.2", "description": "A browser for the LBRY network, a digital marketplace controlled by its users.", "keywords": [ "lbry" -- 2.45.3 From 82a39e6562416f10d3197ca3f41765635510687d Mon Sep 17 00:00:00 2001 From: Anthony Date: Fri, 20 Aug 2021 17:06:04 +0200 Subject: [PATCH 10/58] cleanups for PR --- ui/component/txoList/view.jsx | 89 +++++++++++++++++------------------ 1 file changed, 44 insertions(+), 45 deletions(-) diff --git a/ui/component/txoList/view.jsx b/ui/component/txoList/view.jsx index 897da504e..9f617731c 100644 --- a/ui/component/txoList/view.jsx +++ b/ui/component/txoList/view.jsx @@ -14,15 +14,14 @@ import HelpLink from 'component/common/help-link'; import FileExporter from 'component/common/file-exporter'; import WalletFiatPaymentHistory from 'component/walletFiatPaymentHistory'; import WalletFiatAccountHistory from 'component/walletFiatAccountHistory'; -import { STRIPE_PUBLIC_KEY } from '../../../config'; import { Lbryio } from 'lbryinc'; +import { getStripeEnvironment } from 'util/stripe'; +let stripeEnvironment = getStripeEnvironment(); -let stripeEnvironment = 'test'; -// if the key contains pk_live it's a live key -// update the environment for the calls to the backend to indicate which environment to hit -if (STRIPE_PUBLIC_KEY.indexOf('pk_live') > -1) { - stripeEnvironment = 'live'; -} +// constants to be used in query params +const Q_CURRENCY = 'currency'; +const Q_TAB = 'tab'; +const Q_FIAT_TYPE = 'fiatType'; type Props = { search: string, @@ -123,8 +122,12 @@ function TxoList(props: Props) { const type = urlParams.get(TXO.TYPE) || TXO.ALL; const subtype = urlParams.get(TXO.SUB_TYPE); const active = urlParams.get(TXO.ACTIVE) || TXO.ALL; - const currency = urlParams.get('currency') || 'credits'; - const fiatType = urlParams.get('fiatType') || 'incoming'; + const currency = urlParams.get(Q_CURRENCY) || 'credits'; + const fiatType = urlParams.get(Q_FIAT_TYPE) || 'incoming'; + + // tab used in the wallet section + // TODO: need to change this eventually + const tab = urlParams.get(Q_TAB) || 'fiat-payment-history'; const currentUrlParams = { page, @@ -134,6 +137,7 @@ function TxoList(props: Props) { subtype, currency, fiatType, + tab }; const hideStatus = @@ -204,22 +208,22 @@ function TxoList(props: Props) { delta.value = ''; } - const existingFiatType = newUrlParams.get('fiatType') || 'incoming'; + const existingFiatType = newUrlParams.get(Q_FIAT_TYPE) || 'incoming'; if (delta.tab) { // set tab name to account for wallet page tab - newUrlParams.set('tab', delta.tab); + newUrlParams.set(Q_TAB, delta.tab); } // only update currency if it's being changed if (delta.currency) { - newUrlParams.set('currency', delta.currency); + newUrlParams.set(Q_CURRENCY, delta.currency); } if (delta.fiatType) { - newUrlParams.set('fiatType', delta.fiatType); + newUrlParams.set(Q_FIAT_TYPE, delta.fiatType); } else { - newUrlParams.set('fiatType', existingFiatType); + newUrlParams.set(Q_FIAT_TYPE, existingFiatType); } switch (delta.dkey) { @@ -280,10 +284,6 @@ function TxoList(props: Props) { const paramsString = JSON.stringify(params); - // tab used in the wallet section - // TODO: change the name of this eventually - const tab = 'fiat-payment-history'; - useEffect(() => { if (paramsString && updateTxoPageParams) { const params = JSON.parse(paramsString); @@ -323,6 +323,7 @@ function TxoList(props: Props) { isBodyList body={currency === 'credits' ?
+ {/* LBC transactions section */}
@@ -419,40 +420,38 @@ function TxoList(props: Props) {
- {/* listing of the transactions */} + {/* listing of the lbc transactions */}
:
- {/* fiat section (buttons and transactions) */} + {/* FIAT SECTION ( toggle buttons and transactions) */}
- {!hideStatus && ( -
- - -
-
-
-
- )} +
+ + +
+
+
+
{/* listing of the transactions */} -- 2.45.3 From 97222704035681892257502fc3ab56c3c3c861c5 Mon Sep 17 00:00:00 2001 From: Anthony Date: Fri, 20 Aug 2021 17:39:33 +0200 Subject: [PATCH 11/58] preparing for refactor --- ui/component/txoList/view.jsx | 35 +++++++++++-------- .../walletFiatAccountHistory/view.jsx | 2 +- .../walletFiatPaymentHistory/view.jsx | 2 +- ui/scss/component/_txo-list.scss | 9 +++++ 4 files changed, 31 insertions(+), 17 deletions(-) diff --git a/ui/component/txoList/view.jsx b/ui/component/txoList/view.jsx index 9f617731c..70bb5ee3b 100644 --- a/ui/component/txoList/view.jsx +++ b/ui/component/txoList/view.jsx @@ -19,9 +19,13 @@ import { getStripeEnvironment } from 'util/stripe'; let stripeEnvironment = getStripeEnvironment(); // constants to be used in query params -const Q_CURRENCY = 'currency'; -const Q_TAB = 'tab'; -const Q_FIAT_TYPE = 'fiatType'; +const QUERY_NAME_CURRENCY = 'currency'; +const QUERY_NAME_TAB = 'tab'; +const QUERY_NAME_FIAT_TYPE = 'fiatType'; +// TODO: this tab will be renamed +const DEFAULT_CURRENCY_PARAM = 'credits'; +const DEFAULT_TAB_PARAM = 'fiat-payment-history'; +const DEFAULT_FIAT_TYPE_PARAM = 'incoming'; type Props = { search: string, @@ -122,12 +126,11 @@ function TxoList(props: Props) { const type = urlParams.get(TXO.TYPE) || TXO.ALL; const subtype = urlParams.get(TXO.SUB_TYPE); const active = urlParams.get(TXO.ACTIVE) || TXO.ALL; - const currency = urlParams.get(Q_CURRENCY) || 'credits'; - const fiatType = urlParams.get(Q_FIAT_TYPE) || 'incoming'; - + const currency = urlParams.get(QUERY_NAME_CURRENCY) || DEFAULT_CURRENCY_PARAM; + const fiatType = urlParams.get(QUERY_NAME_FIAT_TYPE) || DEFAULT_FIAT_TYPE_PARAM; // tab used in the wallet section // TODO: need to change this eventually - const tab = urlParams.get(Q_TAB) || 'fiat-payment-history'; + const tab = urlParams.get(QUERY_NAME_TAB) || DEFAULT_TAB_PARAM; const currentUrlParams = { page, @@ -137,7 +140,7 @@ function TxoList(props: Props) { subtype, currency, fiatType, - tab + tab, }; const hideStatus = @@ -199,7 +202,7 @@ function TxoList(props: Props) { history.push(url); } - // let currency = 'credits'; + function updateUrl(delta: Delta) { const newUrlParams = new URLSearchParams(); @@ -208,22 +211,22 @@ function TxoList(props: Props) { delta.value = ''; } - const existingFiatType = newUrlParams.get(Q_FIAT_TYPE) || 'incoming'; + const existingFiatType = newUrlParams.get(QUERY_NAME_FIAT_TYPE) || DEFAULT_FIAT_TYPE_PARAM; if (delta.tab) { // set tab name to account for wallet page tab - newUrlParams.set(Q_TAB, delta.tab); + newUrlParams.set(QUERY_NAME_TAB, delta.tab); } // only update currency if it's being changed if (delta.currency) { - newUrlParams.set(Q_CURRENCY, delta.currency); + newUrlParams.set(QUERY_NAME_CURRENCY, delta.currency); } if (delta.fiatType) { - newUrlParams.set(Q_FIAT_TYPE, delta.fiatType); + newUrlParams.set(QUERY_NAME_FIAT_TYPE, delta.fiatType); } else { - newUrlParams.set(Q_FIAT_TYPE, existingFiatType); + newUrlParams.set(QUERY_NAME_FIAT_TYPE, existingFiatType); } switch (delta.dkey) { @@ -425,7 +428,7 @@ function TxoList(props: Props) {
:
- {/* FIAT SECTION ( toggle buttons and transactions) */} + {/* FIAT SECTION ( toggle buttons and transactions) */}
@@ -433,6 +436,7 @@ function TxoList(props: Props) {
+ {/* incoming transactions button */}
); diff --git a/ui/component/walletFiatPaymentHistory/view.jsx b/ui/component/walletFiatPaymentHistory/view.jsx index 1e0ea0383..2113947c0 100644 --- a/ui/component/walletFiatPaymentHistory/view.jsx +++ b/ui/component/walletFiatPaymentHistory/view.jsx @@ -96,7 +96,7 @@ const WalletBalance = (props: Props) => { {/* show some markup if there's no transactions */} - {(!accountTransactions || accountTransactions.length === 0) &&

No Transactions

} + {(!accountTransactions || accountTransactions.length === 0) &&

No Transactions

}
diff --git a/ui/scss/component/_txo-list.scss b/ui/scss/component/_txo-list.scss index a9088378b..402068c6d 100644 --- a/ui/scss/component/_txo-list.scss +++ b/ui/scss/component/_txo-list.scss @@ -15,3 +15,12 @@ width: 124px; display: inline-block; } + +// displaying fiat transactions (incoming/outgoing) in wallet +.wallet__fiat-transactions { + text-align: center; + margin-top: 13px; + margin-bottom: 9px; + font-size: 13px; + color: rgb(171, 171, 171); +} -- 2.45.3 From 68697baaf49e4108aff6ab302765fdedc851ab5c Mon Sep 17 00:00:00 2001 From: Anthony Date: Fri, 20 Aug 2021 19:31:38 +0200 Subject: [PATCH 12/58] refactor to only change based on the delta --- ui/component/txoList/view.jsx | 73 ++++++++++++++++------------------- 1 file changed, 34 insertions(+), 39 deletions(-) diff --git a/ui/component/txoList/view.jsx b/ui/component/txoList/view.jsx index 70bb5ee3b..409d48196 100644 --- a/ui/component/txoList/view.jsx +++ b/ui/component/txoList/view.jsx @@ -42,11 +42,8 @@ type Props = { }; type Delta = { - dkey?: string, - value?: string, - tab?: string, - currency?: string, - fiatType?: string + changedParameterKey: string, + value: string, }; function TxoList(props: Props) { @@ -146,6 +143,7 @@ function TxoList(props: Props) { const hideStatus = type === TXO.SENT || (currentUrlParams.type === TXO.RECEIVED && currentUrlParams.subtype !== TXO.TIP); + // this is for sdk params const params = {}; if (currentUrlParams.type) { if (currentUrlParams.type === TXO.ALL) { @@ -202,34 +200,10 @@ function TxoList(props: Props) { history.push(url); } - function updateUrl(delta: Delta) { const newUrlParams = new URLSearchParams(); - // fix for flow, maybe there is a better way? - if (!delta.value) { - delta.value = ''; - } - - const existingFiatType = newUrlParams.get(QUERY_NAME_FIAT_TYPE) || DEFAULT_FIAT_TYPE_PARAM; - - if (delta.tab) { - // set tab name to account for wallet page tab - newUrlParams.set(QUERY_NAME_TAB, delta.tab); - } - - // only update currency if it's being changed - if (delta.currency) { - newUrlParams.set(QUERY_NAME_CURRENCY, delta.currency); - } - - if (delta.fiatType) { - newUrlParams.set(QUERY_NAME_FIAT_TYPE, delta.fiatType); - } else { - newUrlParams.set(QUERY_NAME_FIAT_TYPE, existingFiatType); - } - - switch (delta.dkey) { + switch (delta.changedParameterKey) { case TXO.PAGE: if (currentUrlParams.type) { newUrlParams.set(TXO.TYPE, currentUrlParams.type); @@ -241,6 +215,8 @@ function TxoList(props: Props) { newUrlParams.set(TXO.ACTIVE, currentUrlParams.active); } newUrlParams.set(TXO.PAGE, delta.value); + newUrlParams.set(QUERY_NAME_TAB, currentUrlParams.tab); + newUrlParams.set(QUERY_NAME_CURRENCY, currentUrlParams.currency); break; case TXO.TYPE: newUrlParams.set(TXO.TYPE, delta.value); @@ -259,6 +235,8 @@ function TxoList(props: Props) { } newUrlParams.set(TXO.PAGE, String(1)); newUrlParams.set(TXO.PAGE_SIZE, currentUrlParams.pageSize); + newUrlParams.set(QUERY_NAME_TAB, currentUrlParams.tab); + newUrlParams.set(QUERY_NAME_CURRENCY, currentUrlParams.currency); break; case TXO.SUB_TYPE: if (currentUrlParams.type) { @@ -268,6 +246,8 @@ function TxoList(props: Props) { newUrlParams.set(TXO.SUB_TYPE, delta.value); newUrlParams.set(TXO.PAGE, String(1)); newUrlParams.set(TXO.PAGE_SIZE, currentUrlParams.pageSize); + newUrlParams.set(QUERY_NAME_TAB, currentUrlParams.tab); + newUrlParams.set(QUERY_NAME_CURRENCY, currentUrlParams.currency); break; case TXO.ACTIVE: if (currentUrlParams.type) { @@ -279,6 +259,20 @@ function TxoList(props: Props) { newUrlParams.set(TXO.ACTIVE, delta.value); newUrlParams.set(TXO.PAGE, String(1)); newUrlParams.set(TXO.PAGE_SIZE, currentUrlParams.pageSize); + newUrlParams.set(QUERY_NAME_TAB, currentUrlParams.tab); + newUrlParams.set(QUERY_NAME_CURRENCY, currentUrlParams.currency); + break; + // toggling the currency type (lbc/fiat) + case QUERY_NAME_CURRENCY: + newUrlParams.set(QUERY_NAME_CURRENCY, delta.value); + newUrlParams.set(QUERY_NAME_FIAT_TYPE, currentUrlParams.fiatType); + newUrlParams.set(QUERY_NAME_TAB, currentUrlParams.tab); + break; + // toggling the fiat type (incoming/outgoing) + case QUERY_NAME_FIAT_TYPE: + newUrlParams.set(QUERY_NAME_FIAT_TYPE, delta.value); + newUrlParams.set(QUERY_NAME_TAB, currentUrlParams.tab); + newUrlParams.set(QUERY_NAME_CURRENCY, currentUrlParams.currency); break; } @@ -303,7 +297,7 @@ function TxoList(props: Props) {
)} + {/* TODO: use card-between to display this properly */}
{!isFetchingTransactions && transactionsFile === null && ( @@ -439,7 +434,7 @@ function TxoList(props: Props) { {/* incoming transactions button */}
); } diff --git a/ui/component/walletBalance/view.jsx b/ui/component/walletBalance/view.jsx index 71d4dba67..5288b63d5 100644 --- a/ui/component/walletBalance/view.jsx +++ b/ui/component/walletBalance/view.jsx @@ -65,127 +65,137 @@ const WalletBalance = (props: Props) => { return (
- } - subtitle={ - totalLocked > 0 ? ( - }}> - Your total balance. All of this is yours, but some %lbc% is in use on channels and content right now. - - ) : ( - {__('Your total balance.')} - ) - } - actions={ - <> -

- }}> - %lbc_amount% immediately spendable - -

- -

- , - }} - > - %lbc_amount% boosting content - -

- {detailsExpanded && ( -
-
-
- {__('...earned from others')} - ({__('Unlock to spend')}) -
-
- - {Boolean(tipsBalance) && ( -
- -
- {__('...on initial publishes')} - ({__('Delete or edit past content to spend')}) -
-
- -
- -
- {__('...supporting content')} - ({__('Delete supports to spend')}) -
-
- -
-
-
- )} - - {/* @if TARGET='app' */} - {hasSynced ? ( -

- {__('A backup of your wallet is synced with lbry.tv.')} - -

- ) : ( -

- {__('Your wallet is not currently synced with lbry.tv. You are in control of backing up your wallet.')} - -

- )} - {/* @endif */} -
-
- {(otherCount > WALLET_CONSOLIDATE_UTXOS || consolidateIsPending || consolidatingUtxos) && ( -

- doUtxoConsolidate()} - disabled={operationPending} - label={ - consolidateIsPending || consolidatingUtxos ? __('Consolidating...') : __('Consolidate Now') - } - /> - ), - help: , - }} - > - Your wallet has a lot of change lying around. Consolidating will speed up your transactions. This could - take some time. %now%%help% +

+ } + subtitle={ + totalLocked > 0 ? ( + }}> + Your total balance. All of this is yours, but some %lbc% is in use on channels and content right now. -

- )} - - } - /> + ) : ( + {__('Your total balance.')} + ) + } + actions={ + <> +

+ }}> + %lbc_amount% immediately spendable + +

- {/* fiat balance card */} - +

+ , + }} + > + %lbc_amount% boosting content + +

+ {detailsExpanded && ( +
+
+
+ {__('...earned from others')} + ({__('Unlock to spend')}) +
+
+ + {Boolean(tipsBalance) && ( +
+ +
+ {__('...on initial publishes')} + ({__('Delete or edit past content to spend')}) +
+
+ +
+ +
+ {__('...supporting content')} + ({__('Delete supports to spend')}) +
+
+ +
+
+
+ )} + + {/* @if TARGET='app' */} + {hasSynced ? ( +

+ {__('A backup of your wallet is synced with lbry.tv.')} + +

+ ) : ( +

+ {__( + 'Your wallet is not currently synced with lbry.tv. You are in control of backing up your wallet.' + )} + +

+ )} + {/* @endif */} +
+
+ {(otherCount > WALLET_CONSOLIDATE_UTXOS || consolidateIsPending || consolidatingUtxos) && ( +

+ doUtxoConsolidate()} + disabled={operationPending} + label={ + consolidateIsPending || consolidatingUtxos ? __('Consolidating...') : __('Consolidate Now') + } + /> + ), + help: , + }} + > + Your wallet has a lot of change lying around. Consolidating will speed up your transactions. This + could take some time. %now%%help% + +

+ )} + + } + /> +
+
+ {/* fiat balance card */} + +
); }; -- 2.45.3 From d17a333fc6489126886039774c9b60ff8435a1b2 Mon Sep 17 00:00:00 2001 From: Anthony Date: Fri, 20 Aug 2021 20:48:28 +0200 Subject: [PATCH 14/58] pull export and refresh buttons to the right --- ui/component/txoList/view.jsx | 148 ++++++++++++++++++---------------- 1 file changed, 79 insertions(+), 69 deletions(-) diff --git a/ui/component/txoList/view.jsx b/ui/component/txoList/view.jsx index 409d48196..5c126f057 100644 --- a/ui/component/txoList/view.jsx +++ b/ui/component/txoList/view.jsx @@ -291,10 +291,12 @@ function TxoList(props: Props) { return (
{__(`Transactions`)}
-
- -
+ <>
{__(`Transactions`)}
+
+ + {/* toggle between LBC and fiat buttons */} +
+ {/* toggle to LBC */}
-
-
- )} + {(type === TXO.SENT || type === TXO.RECEIVED) && ( +
+ handleChange({ changedParameterKey: TXO.SUB_TYPE, value: e.target.value, tab })} + > + {Object.values(TXO.DROPDOWN_SUBTYPES).map((v) => { + const stringV = String(v); + return ( + + ); + })} + +
+ )} + {!hideStatus && ( +
+ + +
+ {/* active transactions button */} +
+
+
+ )} +
{/* TODO: use card-between to display this properly */} -
+ {/* export and refresh buttons */} +
{!isFetchingTransactions && transactionsFile === null && ( )} -- 2.45.3 From 9fed5643ff617251807e2e0cf105a83430dba8c8 Mon Sep 17 00:00:00 2001 From: Baltazar Gomez Date: Fri, 20 Aug 2021 23:03:45 -0500 Subject: [PATCH 15/58] fix typo on changelog version --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0f9356a7d..7d1aa2d53 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,7 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). -## [0.51.1] - [2021-08-20] +## [0.51.2] - [2021-08-20] ### Added - Show currently active playing item on playlist _community pr!_ ([#6453](https://github.com/lbryio/lbry-desktop/pull/6453)) -- 2.45.3 From 8010b2680a1041dedd1e4503f4c70f8166702a9f Mon Sep 17 00:00:00 2001 From: zeppi Date: Sun, 22 Aug 2021 16:25:12 -0400 Subject: [PATCH 16/58] default support to boost --- ui/component/walletSendTip/view.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/component/walletSendTip/view.jsx b/ui/component/walletSendTip/view.jsx index 2167f2e62..87b6b25e3 100644 --- a/ui/component/walletSendTip/view.jsx +++ b/ui/component/walletSendTip/view.jsx @@ -150,7 +150,7 @@ function WalletSendTip(props: Props) { const noBalance = balance === 0; const tipAmount = useCustomTip ? customTipAmount : presetTipAmount; - const [activeTab, setActiveTab] = React.useState(claimIsMine ? TAB_BOOST : TAB_LBC); + const [activeTab, setActiveTab] = React.useState(TAB_BOOST); function getClaimTypeText() { if (claim.value_type === 'stream') { -- 2.45.3 From 7da1d8cdf79c62bc3ddda1ed5208fcc05f56b5b0 Mon Sep 17 00:00:00 2001 From: infinite-persistence Date: Mon, 23 Aug 2021 15:19:23 +0800 Subject: [PATCH 17/58] Add icon to "Show/Hide Reply" --- ui/component/comment/view.jsx | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/ui/component/comment/view.jsx b/ui/component/comment/view.jsx index 6e3d03e9b..6d3c6dc62 100644 --- a/ui/component/comment/view.jsx +++ b/ui/component/comment/view.jsx @@ -373,13 +373,19 @@ function Comment(props: Props) { setPage(1); } }} + icon={ICONS.DOWN} />
)} {numDirectReplies > 0 && showReplies && (
-
)} -- 2.45.3 From 3b080012acf44eca23043009f50c8f00fc6d551a Mon Sep 17 00:00:00 2001 From: infinite-persistence Date: Thu, 5 Aug 2021 16:42:37 +0800 Subject: [PATCH 18/58] Styles for new Settings Page --- ui/component/settingsRow/index.js | 2 + ui/component/settingsRow/view.jsx | 36 +++++++++++++ ui/scss/component/section.scss | 90 ++++++++++++++++++++++++++++++- 3 files changed, 127 insertions(+), 1 deletion(-) create mode 100644 ui/component/settingsRow/index.js create mode 100644 ui/component/settingsRow/view.jsx diff --git a/ui/component/settingsRow/index.js b/ui/component/settingsRow/index.js new file mode 100644 index 000000000..a8d6ab489 --- /dev/null +++ b/ui/component/settingsRow/index.js @@ -0,0 +1,2 @@ +import SettingsRow from './view'; +export default SettingsRow; diff --git a/ui/component/settingsRow/view.jsx b/ui/component/settingsRow/view.jsx new file mode 100644 index 000000000..a59b7e52b --- /dev/null +++ b/ui/component/settingsRow/view.jsx @@ -0,0 +1,36 @@ +// @flow +import React from 'react'; +import classnames from 'classnames'; + +type Props = { + title: string, + subtitle?: string, + multirow?: boolean, // Displays the Value widget(s) below the Label instead of on the right. + useVerticalSeparator?: boolean, // Show a separator line between Label and Value. Useful when there are multiple Values. + children?: React$Node, +}; + +export default function SettingsRow(props: Props) { + const { title, subtitle, multirow, useVerticalSeparator, children } = props; + + return ( +
+
+

{title}

+ {subtitle &&

{subtitle}

} +
+
+ {children && children} +
+
+ ); +} diff --git a/ui/scss/component/section.scss b/ui/scss/component/section.scss index 2c6fd46f8..a45b88a7e 100644 --- a/ui/scss/component/section.scss +++ b/ui/scss/component/section.scss @@ -140,7 +140,7 @@ margin-right: var(--spacing-s); } - @media (max-width: $breakpoint-small) { + @media (max-width: $breakpoint-medium) { flex-wrap: wrap; > * { @@ -203,3 +203,91 @@ margin-right: 10px; } } + +.settings__row { + &:first-child, + &:only-child { + border-top: none; + } +} + +.settings__row--title { + min-width: 100%; + align-self: flex-start; + + @media (min-width: $breakpoint-small) { + min-width: 60%; + max-width: 60%; + } +} + +.settings__row--subtitle { + @extend .section__subtitle; + font-size: var(--font-small); + margin-top: calc(var(--spacing-xxs) / 2); +} + +.settings__row--value { + width: 100%; + + fieldset-section:not(:only-child) { + margin-top: var(--spacing-s); + } + + fieldset-section.radio { + margin-top: var(--spacing-s); + } + + fieldset-group { + margin-top: var(--spacing-m); + } + + .tags--remove { + margin-bottom: 0; + } + + .tags__input-wrapper { + .tag__input { + height: unset; + max-width: unset; + } + } + + .form-field--price-amount { + max-width: unset; + } + + @media (min-width: $breakpoint-medium) { + width: 40%; + margin-left: var(--spacing-m); + padding-left: var(--spacing-m); + + .button, + .checkbox { + &:only-child { + float: right; + } + } + + input { + align-self: flex-end; + } + } +} + +.settings__row--value--multirow { + @media (min-width: $breakpoint-medium) { + width: 80%; + margin-top: var(--spacing-l); + + input { + align-self: flex-start; + } + } +} + +.settings__row--value--vertical-separator { + @media (min-width: $breakpoint-medium) { + border-left: 1px solid var(--color-border); + } +} -- 2.45.3 From 04b510d88b9ba923b34d864da8412404e70a8a80 Mon Sep 17 00:00:00 2001 From: infinite-persistence Date: Thu, 5 Aug 2021 15:00:21 +0800 Subject: [PATCH 19/58] [Account] grab SyncToggle and AccountPassword Also made visual changes for the new Settings Page. ## SyncToggle: It will no longer be under a dedicated Card, so the "Sync" title is not there to give context for the case of "no verified email". Changed it such that the checkbox is always visible (it's label is self-explanatory) but disable when email is not set. The "Add Email" button will then appear below, so everything now makes sense in context. --- ui/component/settingAccount/index.js | 15 ++++ ui/component/settingAccount/view.jsx | 55 ++++++++++++ ui/component/settingAccountPassword/view.jsx | 95 ++++++++++---------- ui/component/syncToggle/view.jsx | 30 ++++--- ui/page/settings/index.js | 7 +- ui/page/settings/view.jsx | 50 ++--------- 6 files changed, 144 insertions(+), 108 deletions(-) create mode 100644 ui/component/settingAccount/index.js create mode 100644 ui/component/settingAccount/view.jsx diff --git a/ui/component/settingAccount/index.js b/ui/component/settingAccount/index.js new file mode 100644 index 000000000..9abbe808b --- /dev/null +++ b/ui/component/settingAccount/index.js @@ -0,0 +1,15 @@ +import { connect } from 'react-redux'; +import { doWalletStatus, selectWalletIsEncrypted } from 'lbry-redux'; +import { selectUserVerifiedEmail } from 'redux/selectors/user'; +import SettingAccount from './view'; + +const select = (state) => ({ + isAuthenticated: selectUserVerifiedEmail(state), + walletEncrypted: selectWalletIsEncrypted(state), +}); + +const perform = (dispatch) => ({ + doWalletStatus: () => dispatch(doWalletStatus()), +}); + +export default connect(select, perform)(SettingAccount); diff --git a/ui/component/settingAccount/view.jsx b/ui/component/settingAccount/view.jsx new file mode 100644 index 000000000..4097b532d --- /dev/null +++ b/ui/component/settingAccount/view.jsx @@ -0,0 +1,55 @@ +// @flow +import React from 'react'; +import Card from 'component/common/card'; +import SettingAccountPassword from 'component/settingAccountPassword'; +import SyncToggle from 'component/syncToggle'; +import { getPasswordFromCookie } from 'util/saved-passwords'; + +type Props = { + // --- select --- + isAuthenticated: boolean, + walletEncrypted: boolean, + // --- perform --- + doWalletStatus: () => void, +}; + +export default function SettingAccount(props: Props) { + const { isAuthenticated, walletEncrypted, doWalletStatus } = props; + const [storedPassword, setStoredPassword] = React.useState(false); + + // Determine if password is stored. + React.useEffect(() => { + if (isAuthenticated || !IS_WEB) { + doWalletStatus(); + getPasswordFromCookie().then((p) => { + if (typeof p === 'string') { + setStoredPassword(true); + } + }); + } + // enterSettings(); @KP need to do this at each component, or just at Settings Page? + }, []); // eslint-disable-line react-hooks/exhaustive-deps + + return ( + + {isAuthenticated && ( +
+ +
+ )} + + {/* @if TARGET='app' */} +
+ +
+ {/* @endif */} + + } + /> + ); +} diff --git a/ui/component/settingAccountPassword/view.jsx b/ui/component/settingAccountPassword/view.jsx index a63dff59a..494d078e6 100644 --- a/ui/component/settingAccountPassword/view.jsx +++ b/ui/component/settingAccountPassword/view.jsx @@ -3,7 +3,6 @@ import React, { useState } from 'react'; import { FormField, Form } from 'component/common/form'; import Button from 'component/button'; import ErrorText from 'component/common/error-text'; -import Card from 'component/common/card'; import * as PAGES from 'constants/pages'; type Props = { @@ -38,54 +37,52 @@ export default function SettingAccountPassword(props: Props) { } }, [passwordSetSuccess, setOldPassword, setNewPassword, doClearPasswordEntry, doToast]); - return ( - -
- {hasPassword && ( - setOldPassword(e.target.value)} - /> - )} - setNewPassword(e.target.value)} - /> - -
-
- - {passwordSetError && ( -
- {passwordSetError} -
- )} -
- ) : ( -
+ + {passwordSetError && ( +
+ {passwordSetError} +
+ )} +
+ ) : ( +
+
+

{__('Password')}

+ {!hasPassword &&

{__('You do not currently have a password set.')}

} +
+
); } diff --git a/ui/component/syncToggle/view.jsx b/ui/component/syncToggle/view.jsx index 2a885ecf3..e6a702947 100644 --- a/ui/component/syncToggle/view.jsx +++ b/ui/component/syncToggle/view.jsx @@ -6,10 +6,10 @@ import { withRouter } from 'react-router'; import { FormField } from 'component/common/form'; type Props = { - setSyncEnabled: boolean => void, + setSyncEnabled: (boolean) => void, syncEnabled: boolean, verifiedEmail: ?string, - history: { push: string => void }, + history: { push: (string) => void }, location: UrlLocation, getSyncError: ?string, disabled: boolean, @@ -21,20 +21,24 @@ function SyncToggle(props: Props) { return (
- {!verifiedEmail ? ( + openModal(MODALS.SYNC_ENABLE, { mode: syncEnabled ? 'disable' : 'enable' })} + disabled={disabled || !verifiedEmail} + helper={ + disabled + ? __("To enable Sync, close LBRY completely and check 'Remember Password' during wallet unlock.") + : null + } + /> + {!verifiedEmail && (
-
- ) : ( - openModal(MODALS.SYNC_ENABLE, { mode: syncEnabled ? 'disable' : 'enable' })} - disabled={disabled} - /> )}
); diff --git a/ui/page/settings/index.js b/ui/page/settings/index.js index c9292b3cf..6db459061 100644 --- a/ui/page/settings/index.js +++ b/ui/page/settings/index.js @@ -1,5 +1,5 @@ import { connect } from 'react-redux'; -import { doClearCache, doNotifyForgetPassword, doToggle3PAnalytics, doOpenModal } from 'redux/actions/app'; +import { doClearCache, doToggle3PAnalytics, doOpenModal } from 'redux/actions/app'; import { selectAllowAnalytics } from 'redux/selectors/app'; import { doSetDaemonSetting, @@ -16,7 +16,7 @@ import { selectLanguage, selectShowMatureContent, } from 'redux/selectors/settings'; -import { doWalletStatus, selectMyChannelUrls, selectWalletIsEncrypted, SETTINGS } from 'lbry-redux'; +import { selectMyChannelUrls, SETTINGS } from 'lbry-redux'; import SettingsPage from './view'; import { selectUserVerifiedEmail, selectUser } from 'redux/selectors/user'; @@ -30,7 +30,6 @@ const select = (state) => ({ automaticDarkModeEnabled: makeSelectClientSetting(SETTINGS.AUTOMATIC_DARK_MODE_ENABLED)(state), clock24h: makeSelectClientSetting(SETTINGS.CLOCK_24H)(state), autoplay: makeSelectClientSetting(SETTINGS.AUTOPLAY)(state), - walletEncrypted: selectWalletIsEncrypted(state), autoDownload: makeSelectClientSetting(SETTINGS.AUTO_DOWNLOAD)(state), hideBalance: makeSelectClientSetting(SETTINGS.HIDE_BALANCE)(state), floatingPlayer: makeSelectClientSetting(SETTINGS.FLOATING_PLAYER)(state), @@ -47,8 +46,6 @@ const perform = (dispatch) => ({ toggle3PAnalytics: (allow) => dispatch(doToggle3PAnalytics(allow)), clearCache: () => dispatch(doClearCache()), setClientSetting: (key, value) => dispatch(doSetClientSetting(key, value)), - updateWalletStatus: () => dispatch(doWalletStatus()), - confirmForgetPassword: (modalProps) => dispatch(doNotifyForgetPassword(modalProps)), clearPlayingUri: () => dispatch(doSetPlayingUri({ uri: null })), setDarkTime: (time, options) => dispatch(doSetDarkTime(time, options)), openModal: (id, params) => dispatch(doOpenModal(id, params)), diff --git a/ui/page/settings/view.jsx b/ui/page/settings/view.jsx index 60d29d385..79f9a0f40 100644 --- a/ui/page/settings/view.jsx +++ b/ui/page/settings/view.jsx @@ -7,14 +7,12 @@ import { SETTINGS } from 'lbry-redux'; import { FormField } from 'component/common/form'; import Button from 'component/button'; import Page from 'component/page'; +import SettingAccount from 'component/settingAccount'; import SettingLanguage from 'component/settingLanguage'; import FileSelector from 'component/common/file-selector'; -import SyncToggle from 'component/syncToggle'; import HomepageSelector from 'component/homepageSelector'; import Card from 'component/common/card'; -import SettingAccountPassword from 'component/settingAccountPassword'; import classnames from 'classnames'; -import { getPasswordFromCookie } from 'util/saved-passwords'; import { SIMPLE_SITE } from 'config'; // $FlowFixMe import homepages from 'homepages'; @@ -61,9 +59,6 @@ type Props = { automaticDarkModeEnabled: boolean, clock24h: boolean, autoplay: boolean, - updateWalletStatus: () => void, - walletEncrypted: boolean, - confirmForgetPassword: ({}) => void, floatingPlayer: boolean, hideReposts: ?boolean, clearPlayingUri: () => void, @@ -79,7 +74,6 @@ type Props = { type State = { clearingCache: boolean, - storedPassword: boolean, }; class SettingsPage extends React.PureComponent { @@ -88,26 +82,15 @@ class SettingsPage extends React.PureComponent { this.state = { clearingCache: false, - storedPassword: false, }; (this: any).onThemeChange = this.onThemeChange.bind(this); (this: any).onAutomaticDarkModeChange = this.onAutomaticDarkModeChange.bind(this); (this: any).onChangeTime = this.onChangeTime.bind(this); - (this: any).onConfirmForgetPassword = this.onConfirmForgetPassword.bind(this); } componentDidMount() { - const { isAuthenticated, enterSettings } = this.props; - - if (isAuthenticated || !IS_WEB) { - this.props.updateWalletStatus(); - getPasswordFromCookie().then((p) => { - if (typeof p === 'string') { - this.setState({ storedPassword: true }); - } - }); - } + const { enterSettings } = this.props; enterSettings(); } @@ -134,15 +117,6 @@ class SettingsPage extends React.PureComponent { this.props.setClientSetting(SETTINGS.CLOCK_24H, value); } - onConfirmForgetPassword() { - const { confirmForgetPassword } = this.props; - confirmForgetPassword({ - callback: () => { - this.setState({ storedPassword: false }); - }, - }); - } - onChangeTime(event: SyntheticInputEvent<*>, options: OptionTimes) { const { value } = event.target; @@ -180,7 +154,6 @@ class SettingsPage extends React.PureComponent { automaticDarkModeEnabled, clock24h, autoplay, - walletEncrypted, // autoDownload, setDaemonSetting, setClientSetting, @@ -194,12 +167,17 @@ class SettingsPage extends React.PureComponent { myChannelUrls, user, } = this.props; - const { storedPassword } = this.state; const noDaemonSettings = !daemonSettings || Object.keys(daemonSettings).length === 0; const startHours = ['18', '19', '20', '21']; const endHours = ['5', '6', '7', '8']; - return ( + const newStyle = true; + + return newStyle ? ( + + + + ) : ( { ) : (
- {isAuthenticated && } {/* @if TARGET='app' */} { } /> - } - /> {/* @endif */} Date: Thu, 5 Aug 2021 16:41:45 +0800 Subject: [PATCH 20/58] [System] grab Clear Cache, Startup and Closing Behavior --- static/app-strings.json | 5 +- ui/component/settingAutoLaunch/view.jsx | 17 +++--- ui/component/settingClosingBehavior/view.jsx | 9 +-- ui/component/settingSystem/index.js | 11 ++++ ui/component/settingSystem/view.jsx | 64 ++++++++++++++++++++ ui/page/settings/index.js | 3 +- ui/page/settings/view.jsx | 34 +---------- ui/page/settingsAdvanced/view.jsx | 12 ---- 8 files changed, 97 insertions(+), 58 deletions(-) create mode 100644 ui/component/settingSystem/index.js create mode 100644 ui/component/settingSystem/view.jsx diff --git a/static/app-strings.json b/static/app-strings.json index 7b2e6774a..0558bba20 100644 --- a/static/app-strings.json +++ b/static/app-strings.json @@ -156,8 +156,9 @@ "Experimental settings": "Experimental settings", "Autoplay media files": "Autoplay media files", "Autoplay video and audio files when navigating to a file, as well as the next related item when a file finishes playing.": "Autoplay video and audio files when navigating to a file, as well as the next related item when a file finishes playing.", - "Application cache": "Application cache", + "Clear application cache": "Clear application cache", "Clear Cache": "Clear Cache", + "This might fix issues that you are having. Your wallet will not be affected.": "This might fix issues that you are having. Your wallet will not be affected.", "Currency": "Currency", "US Dollars": "US Dollars", "There's nothing available at this location.": "There's nothing available at this location.", @@ -656,7 +657,6 @@ "Invalid claim ID %claimId%.": "Invalid claim ID %claimId%.", "Suggested": "Suggested", "Startup preferences": "Startup preferences", - "This will clear the application cache, and might fix issues you are having. Your wallet will not be affected. ": "This will clear the application cache, and might fix issues you are having. Your wallet will not be affected. ", "Start minimized": "Start minimized", "Improve view speed and help the LBRY network by allowing the app to cuddle up in your system tray.": "Improve view speed and help the LBRY network by allowing the app to cuddle up in your system tray.", "Content Type": "Content Type", @@ -2047,6 +2047,7 @@ "Commenting server is not set.": "Commenting server is not set.", "Comments are not currently enabled.": "Comments are not currently enabled.", "See All": "See All", + "System": "System", "Supporting content requires %lbc%": "Supporting content requires %lbc%", "With %lbc%, you can send tips to your favorite creators, or help boost their content for more people to see.": "With %lbc%, you can send tips to your favorite creators, or help boost their content for more people to see.", "Show this channel your appreciation by sending a donation in USD.": "Show this channel your appreciation by sending a donation in USD.", diff --git a/ui/component/settingAutoLaunch/view.jsx b/ui/component/settingAutoLaunch/view.jsx index 4effdabf7..f5c9cc169 100644 --- a/ui/component/settingAutoLaunch/view.jsx +++ b/ui/component/settingAutoLaunch/view.jsx @@ -6,25 +6,28 @@ import { FormField } from 'component/common/form'; type Props = { autoLaunch: string, showToast: ({}) => void, - setAutoLaunch: boolean => void, + setAutoLaunch: (boolean) => void, + noLabels?: boolean, }; function SettingAutoLaunch(props: Props) { - const { autoLaunch, setAutoLaunch } = props; + const { autoLaunch, setAutoLaunch, noLabels } = props; return ( { + onChange={(e) => { setAutoLaunch(e.target.checked); }} checked={autoLaunch} - label={__('Start minimized')} - helper={__( - 'Improve view speed and help the LBRY network by allowing the app to cuddle up in your system tray.' - )} + label={noLabels ? '' : __('Start minimized')} + helper={ + noLabels + ? '' + : __('Improve view speed and help the LBRY network by allowing the app to cuddle up in your system tray.') + } /> ); diff --git a/ui/component/settingClosingBehavior/view.jsx b/ui/component/settingClosingBehavior/view.jsx index a8560aa57..4ad423248 100644 --- a/ui/component/settingClosingBehavior/view.jsx +++ b/ui/component/settingClosingBehavior/view.jsx @@ -5,22 +5,23 @@ import { FormField } from 'component/common/form'; type Props = { toTrayWhenClosed: boolean, - setToTrayWhenClosed: boolean => void, + setToTrayWhenClosed: (boolean) => void, + noLabels?: boolean, }; function SettingClosingBehavior(props: Props) { - const { toTrayWhenClosed, setToTrayWhenClosed } = props; + const { toTrayWhenClosed, setToTrayWhenClosed, noLabels } = props; return ( { + onChange={(e) => { setToTrayWhenClosed(e.target.checked); }} checked={toTrayWhenClosed} - label={__('Leave app running in notification area when the window is closed')} + label={noLabels ? '' : __('Leave app running in notification area when the window is closed')} /> ); diff --git a/ui/component/settingSystem/index.js b/ui/component/settingSystem/index.js new file mode 100644 index 000000000..ccd1fbaab --- /dev/null +++ b/ui/component/settingSystem/index.js @@ -0,0 +1,11 @@ +import { connect } from 'react-redux'; +import { doClearCache } from 'redux/actions/app'; +import SettingSystem from './view'; + +const select = (state) => ({}); + +const perform = (dispatch) => ({ + clearCache: () => dispatch(doClearCache()), +}); + +export default connect(select, perform)(SettingSystem); diff --git a/ui/component/settingSystem/view.jsx b/ui/component/settingSystem/view.jsx new file mode 100644 index 000000000..a91803aec --- /dev/null +++ b/ui/component/settingSystem/view.jsx @@ -0,0 +1,64 @@ +// @flow +import { ALERT } from 'constants/icons'; +import React from 'react'; +import Button from 'component/button'; +import Card from 'component/common/card'; +import SettingAutoLaunch from 'component/settingAutoLaunch'; +import SettingClosingBehavior from 'component/settingClosingBehavior'; +import SettingsRow from 'component/settingsRow'; + +// @if TARGET='app' +const IS_MAC = process.platform === 'darwin'; +// @endif + +type Props = { + clearCache: () => Promise, +}; + +export default function SettingSystem(props: Props) { + const { clearCache } = props; + const [clearingCache, setClearingCache] = React.useState(false); + + return ( + + {/* @if TARGET='app' */} + {/* Auto launch in a hidden state doesn't work on mac https://github.com/Teamwork/node-auto-launch/issues/81 */} + {!IS_MAC && ( + + + + )} + {/* @endif */} + + {/* @if TARGET='app' */} + + + + {/* @endif */} + + +
)}
diff --git a/ui/page/settingsAdvanced/view.jsx b/ui/page/settingsAdvanced/view.jsx index 4807eaa9e..c4a380751 100644 --- a/ui/page/settingsAdvanced/view.jsx +++ b/ui/page/settingsAdvanced/view.jsx @@ -7,8 +7,6 @@ import I18nMessage from 'component/i18nMessage'; import Page from 'component/page'; import SettingCommentsServer from 'component/settingCommentsServer'; import SettingWalletServer from 'component/settingWalletServer'; -import SettingAutoLaunch from 'component/settingAutoLaunch'; -import SettingClosingBehavior from 'component/settingClosingBehavior'; import FileSelector from 'component/common/file-selector'; import { SETTINGS } from 'lbry-redux'; import Card from 'component/common/card'; @@ -16,10 +14,6 @@ import { getPasswordFromCookie } from 'util/saved-passwords'; import Spinner from 'component/spinner'; import PublishSettings from 'component/publishSettings'; -// @if TARGET='app' -const IS_MAC = process.platform === 'darwin'; -// @endif - type Price = { currency: string, amount: number, @@ -513,12 +507,6 @@ class SettingsAdvancedPage extends React.PureComponent { {/* @endif */} } /> - - {/* @if TARGET='app' */} - {/* Auto launch in a hidden state doesn't work on mac https://github.com/Teamwork/node-auto-launch/issues/81 */} - {!IS_MAC && } />} - } /> - {/* @endif */}
)} -- 2.45.3 From 17871e78c88a9a962ce1444bc93daf7a3eb00435 Mon Sep 17 00:00:00 2001 From: infinite-persistence Date: Thu, 5 Aug 2021 17:18:16 +0800 Subject: [PATCH 21/58] [Appearance] grab language and homepage Also applied new Settings Page styling. --- ui/component/homepageSelector/view.jsx | 15 ++++++----- ui/component/settingAppearance/index.js | 8 ++++++ ui/component/settingAppearance/view.jsx | 34 +++++++++++++++++++++++++ ui/page/settings/index.js | 8 +----- ui/page/settings/view.jsx | 12 ++------- 5 files changed, 54 insertions(+), 23 deletions(-) create mode 100644 ui/component/settingAppearance/index.js create mode 100644 ui/component/settingAppearance/view.jsx diff --git a/ui/component/homepageSelector/view.jsx b/ui/component/homepageSelector/view.jsx index 514cb2f94..ce7e15e48 100644 --- a/ui/component/homepageSelector/view.jsx +++ b/ui/component/homepageSelector/view.jsx @@ -8,7 +8,7 @@ import { getDefaultHomepageKey } from 'util/default-languages'; type Props = { homepage: string, - setHomepage: string => void, + setHomepage: (string) => void, }; function SelectHomepage(props: Props) { @@ -22,22 +22,25 @@ function SelectHomepage(props: Props) { return null; } return ( - +
+
+

{__('Homepage')}

+

{__('Tailor your experience.')}

+
+ - {Object.keys(homepages).map(hp => ( + {Object.keys(homepages).map((hp) => ( ))} - +
); } diff --git a/ui/component/settingAppearance/index.js b/ui/component/settingAppearance/index.js new file mode 100644 index 000000000..30230b578 --- /dev/null +++ b/ui/component/settingAppearance/index.js @@ -0,0 +1,8 @@ +import { connect } from 'react-redux'; +import SettingAppearance from './view'; + +const select = (state) => ({}); + +const perform = (dispatch) => ({}); + +export default connect(select, perform)(SettingAppearance); diff --git a/ui/component/settingAppearance/view.jsx b/ui/component/settingAppearance/view.jsx new file mode 100644 index 000000000..1daab7f0e --- /dev/null +++ b/ui/component/settingAppearance/view.jsx @@ -0,0 +1,34 @@ +// @flow +import React from 'react'; +import Card from 'component/common/card'; +import HomepageSelector from 'component/homepageSelector'; +import SettingLanguage from 'component/settingLanguage'; +// $FlowFixMe +import homepages from 'homepages'; + +type Props = {}; + +export default function SettingAppearance(props: Props) { + return ( + + {/* --- Language --- */} +
+ +
+ + {/* --- Homepage --- */} + {homepages && Object.keys(homepages).length > 1 && ( +
+ +
+ )} + + } + /> + ); +} diff --git a/ui/page/settings/index.js b/ui/page/settings/index.js index e69225a82..5e0e13d0b 100644 --- a/ui/page/settings/index.js +++ b/ui/page/settings/index.js @@ -10,12 +10,7 @@ import { doExitSettingsPage, } from 'redux/actions/settings'; import { doSetPlayingUri } from 'redux/actions/content'; -import { - makeSelectClientSetting, - selectDaemonSettings, - selectLanguage, - selectShowMatureContent, -} from 'redux/selectors/settings'; +import { makeSelectClientSetting, selectDaemonSettings, selectShowMatureContent } from 'redux/selectors/settings'; import { selectMyChannelUrls, SETTINGS } from 'lbry-redux'; import SettingsPage from './view'; import { selectUserVerifiedEmail, selectUser } from 'redux/selectors/user'; @@ -35,7 +30,6 @@ const select = (state) => ({ floatingPlayer: makeSelectClientSetting(SETTINGS.FLOATING_PLAYER)(state), hideReposts: makeSelectClientSetting(SETTINGS.HIDE_REPOSTS)(state), darkModeTimes: makeSelectClientSetting(SETTINGS.DARK_MODE_TIMES)(state), - language: selectLanguage(state), myChannelUrls: selectMyChannelUrls(state), user: selectUser(state), }); diff --git a/ui/page/settings/view.jsx b/ui/page/settings/view.jsx index 01cf0e876..dfd6aad60 100644 --- a/ui/page/settings/view.jsx +++ b/ui/page/settings/view.jsx @@ -8,15 +8,12 @@ import { FormField } from 'component/common/form'; import Button from 'component/button'; import Page from 'component/page'; import SettingAccount from 'component/settingAccount'; -import SettingLanguage from 'component/settingLanguage'; +import SettingAppearance from 'component/settingAppearance'; import SettingSystem from 'component/settingSystem'; import FileSelector from 'component/common/file-selector'; -import HomepageSelector from 'component/homepageSelector'; import Card from 'component/common/card'; import classnames from 'classnames'; import { SIMPLE_SITE } from 'config'; -// $FlowFixMe -import homepages from 'homepages'; import { Lbryio } from 'lbryinc'; import Yrbl from 'component/yrbl'; import { getStripeEnvironment } from 'util/stripe'; @@ -65,7 +62,6 @@ type Props = { darkModeTimes: DarkModeTimes, setDarkTime: (string, {}) => void, openModal: (string) => void, - language?: string, enterSettings: () => void, exitSettings: () => void, myChannelUrls: ?Array, @@ -166,6 +162,7 @@ class SettingsPage extends React.PureComponent { return newStyle ? ( + @@ -179,11 +176,6 @@ class SettingsPage extends React.PureComponent { }} className="card-stack" > - } /> - {homepages && Object.keys(homepages).length > 1 && ( - } /> - )} - {!isAuthenticated && IS_WEB && (
Date: Sun, 22 Aug 2021 11:18:21 +0800 Subject: [PATCH 22/58] [Appearance] Move homepages to top + i18n per feedback --- ui/component/settingAppearance/view.jsx | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/ui/component/settingAppearance/view.jsx b/ui/component/settingAppearance/view.jsx index 1daab7f0e..109c103a0 100644 --- a/ui/component/settingAppearance/view.jsx +++ b/ui/component/settingAppearance/view.jsx @@ -16,17 +16,17 @@ export default function SettingAppearance(props: Props) { isBodyList body={ <> - {/* --- Language --- */} -
- -
- {/* --- Homepage --- */} {homepages && Object.keys(homepages).length > 1 && (
)} + + {/* --- Language --- */} +
+ +
} /> -- 2.45.3 From 4e0434d5867484cf22c9d3203e91c3a7a95508ca Mon Sep 17 00:00:00 2001 From: infinite-persistence Date: Thu, 5 Aug 2021 20:39:08 +0800 Subject: [PATCH 23/58] [Appearance] factor out ThemeSelector and use it here --- ui/component/settingAppearance/view.jsx | 5 + ui/component/themeSelector/index.js | 20 ++++ ui/component/themeSelector/view.jsx | 128 ++++++++++++++++++++++++ ui/page/settings/index.js | 6 -- ui/page/settings/view.jsx | 117 ---------------------- 5 files changed, 153 insertions(+), 123 deletions(-) create mode 100644 ui/component/themeSelector/index.js create mode 100644 ui/component/themeSelector/view.jsx diff --git a/ui/component/settingAppearance/view.jsx b/ui/component/settingAppearance/view.jsx index 109c103a0..2aa59bfe7 100644 --- a/ui/component/settingAppearance/view.jsx +++ b/ui/component/settingAppearance/view.jsx @@ -3,6 +3,7 @@ import React from 'react'; import Card from 'component/common/card'; import HomepageSelector from 'component/homepageSelector'; import SettingLanguage from 'component/settingLanguage'; +import ThemeSelector from 'component/themeSelector'; // $FlowFixMe import homepages from 'homepages'; @@ -27,6 +28,10 @@ export default function SettingAppearance(props: Props) {
+ + + + } /> diff --git a/ui/component/themeSelector/index.js b/ui/component/themeSelector/index.js new file mode 100644 index 000000000..926a41546 --- /dev/null +++ b/ui/component/themeSelector/index.js @@ -0,0 +1,20 @@ +import { connect } from 'react-redux'; +import { SETTINGS } from 'lbry-redux'; +import { doSetClientSetting, doSetDarkTime } from 'redux/actions/settings'; +import { makeSelectClientSetting } from 'redux/selectors/settings'; +import ThemeSelector from './view'; + +const select = (state) => ({ + currentTheme: makeSelectClientSetting(SETTINGS.THEME)(state), + themes: makeSelectClientSetting(SETTINGS.THEMES)(state), + automaticDarkModeEnabled: makeSelectClientSetting(SETTINGS.AUTOMATIC_DARK_MODE_ENABLED)(state), + darkModeTimes: makeSelectClientSetting(SETTINGS.DARK_MODE_TIMES)(state), + clock24h: makeSelectClientSetting(SETTINGS.CLOCK_24H)(state), +}); + +const perform = (dispatch) => ({ + setClientSetting: (key, value) => dispatch(doSetClientSetting(key, value)), + setDarkTime: (time, options) => dispatch(doSetDarkTime(time, options)), +}); + +export default connect(select, perform)(ThemeSelector); diff --git a/ui/component/themeSelector/view.jsx b/ui/component/themeSelector/view.jsx new file mode 100644 index 000000000..2f7985d16 --- /dev/null +++ b/ui/component/themeSelector/view.jsx @@ -0,0 +1,128 @@ +// @flow +import React from 'react'; +import { SETTINGS } from 'lbry-redux'; +import { FormField } from 'component/common/form'; + +type SetDaemonSettingArg = boolean | string | number; + +type DarkModeTimes = { + from: { hour: string, min: string, formattedTime: string }, + to: { hour: string, min: string, formattedTime: string }, +}; + +type OptionTimes = { + fromTo: string, + time: string, +}; + +type Props = { + currentTheme: string, + themes: Array, + automaticDarkModeEnabled: boolean, + darkModeTimes: DarkModeTimes, + clock24h: boolean, + setClientSetting: (string, SetDaemonSettingArg) => void, + setDarkTime: (string, {}) => void, +}; + +export default function ThemeSelector(props: Props) { + const { + currentTheme, + themes, + automaticDarkModeEnabled, + darkModeTimes, + clock24h, + setClientSetting, + setDarkTime, + } = props; + + const startHours = ['18', '19', '20', '21']; + const endHours = ['5', '6', '7', '8']; + + function onThemeChange(event: SyntheticInputEvent<*>) { + const { value } = event.target; + if (value === 'dark') { + onAutomaticDarkModeChange(false); + } + setClientSetting(SETTINGS.THEME, value); + } + + function onAutomaticDarkModeChange(value: boolean) { + setClientSetting(SETTINGS.AUTOMATIC_DARK_MODE_ENABLED, value); + } + + function onChangeTime(event: SyntheticInputEvent<*>, options: OptionTimes) { + setDarkTime(event.target.value, options); + } + + function formatHour(time: string, clock24h: boolean) { + if (clock24h) { + return `${time}:00`; + } + + const now = new Date(0, 0, 0, Number(time)); + return now.toLocaleTimeString('en-US', { hour12: true, hour: '2-digit' }); + } + + return ( + <> + + + {themes.map((theme) => ( + + ))} + + + + + onAutomaticDarkModeChange(!automaticDarkModeEnabled)} + checked={automaticDarkModeEnabled} + label={__('Automatic dark mode')} + /> + + {automaticDarkModeEnabled && ( + + onChangeTime(value, { fromTo: 'from', time: 'hour' })} + value={darkModeTimes.from.hour} + label={__('From --[initial time]--')} + > + {startHours.map((time) => ( + + ))} + + + onChangeTime(value, { fromTo: 'to', time: 'hour' })} + value={darkModeTimes.to.hour} + > + {endHours.map((time) => ( + + ))} + + + )} + + + ); +} diff --git a/ui/page/settings/index.js b/ui/page/settings/index.js index 5e0e13d0b..48965eaf2 100644 --- a/ui/page/settings/index.js +++ b/ui/page/settings/index.js @@ -5,7 +5,6 @@ import { doSetDaemonSetting, doClearDaemonSetting, doSetClientSetting, - doSetDarkTime, doEnterSettingsPage, doExitSettingsPage, } from 'redux/actions/settings'; @@ -20,16 +19,12 @@ const select = (state) => ({ allowAnalytics: selectAllowAnalytics(state), isAuthenticated: selectUserVerifiedEmail(state), showNsfw: selectShowMatureContent(state), - currentTheme: makeSelectClientSetting(SETTINGS.THEME)(state), - themes: makeSelectClientSetting(SETTINGS.THEMES)(state), - automaticDarkModeEnabled: makeSelectClientSetting(SETTINGS.AUTOMATIC_DARK_MODE_ENABLED)(state), clock24h: makeSelectClientSetting(SETTINGS.CLOCK_24H)(state), autoplay: makeSelectClientSetting(SETTINGS.AUTOPLAY)(state), autoDownload: makeSelectClientSetting(SETTINGS.AUTO_DOWNLOAD)(state), hideBalance: makeSelectClientSetting(SETTINGS.HIDE_BALANCE)(state), floatingPlayer: makeSelectClientSetting(SETTINGS.FLOATING_PLAYER)(state), hideReposts: makeSelectClientSetting(SETTINGS.HIDE_REPOSTS)(state), - darkModeTimes: makeSelectClientSetting(SETTINGS.DARK_MODE_TIMES)(state), myChannelUrls: selectMyChannelUrls(state), user: selectUser(state), }); @@ -40,7 +35,6 @@ const perform = (dispatch) => ({ toggle3PAnalytics: (allow) => dispatch(doToggle3PAnalytics(allow)), setClientSetting: (key, value) => dispatch(doSetClientSetting(key, value)), clearPlayingUri: () => dispatch(doSetPlayingUri({ uri: null })), - setDarkTime: (time, options) => dispatch(doSetDarkTime(time, options)), openModal: (id, params) => dispatch(doOpenModal(id, params)), enterSettings: () => dispatch(doEnterSettingsPage()), exitSettings: () => dispatch(doExitSettingsPage()), diff --git a/ui/page/settings/view.jsx b/ui/page/settings/view.jsx index dfd6aad60..6ab968cac 100644 --- a/ui/page/settings/view.jsx +++ b/ui/page/settings/view.jsx @@ -25,16 +25,6 @@ type Price = { type SetDaemonSettingArg = boolean | string | number; -type DarkModeTimes = { - from: { hour: string, min: string, formattedTime: string }, - to: { hour: string, min: string, formattedTime: string }, -}; - -type OptionTimes = { - fromTo: string, - time: string, -}; - type DaemonSettings = { download_dir: string, share_usage_data: boolean, @@ -51,16 +41,11 @@ type Props = { isAuthenticated: boolean, instantPurchaseEnabled: boolean, instantPurchaseMax: Price, - currentTheme: string, - themes: Array, - automaticDarkModeEnabled: boolean, clock24h: boolean, autoplay: boolean, floatingPlayer: boolean, hideReposts: ?boolean, clearPlayingUri: () => void, - darkModeTimes: DarkModeTimes, - setDarkTime: (string, {}) => void, openModal: (string) => void, enterSettings: () => void, exitSettings: () => void, @@ -69,14 +54,6 @@ type Props = { }; class SettingsPage extends React.PureComponent { - constructor(props: Props) { - super(props); - - (this: any).onThemeChange = this.onThemeChange.bind(this); - (this: any).onAutomaticDarkModeChange = this.onAutomaticDarkModeChange.bind(this); - (this: any).onChangeTime = this.onChangeTime.bind(this); - } - componentDidMount() { const { enterSettings } = this.props; enterSettings(); @@ -87,42 +64,10 @@ class SettingsPage extends React.PureComponent { exitSettings(); } - onThemeChange(event: SyntheticInputEvent<*>) { - const { value } = event.target; - - if (value === 'dark') { - this.onAutomaticDarkModeChange(false); - } - - this.props.setClientSetting(SETTINGS.THEME, value); - } - - onAutomaticDarkModeChange(value: boolean) { - this.props.setClientSetting(SETTINGS.AUTOMATIC_DARK_MODE_ENABLED, value); - } - onClock24hChange(value: boolean) { this.props.setClientSetting(SETTINGS.CLOCK_24H, value); } - onChangeTime(event: SyntheticInputEvent<*>, options: OptionTimes) { - const { value } = event.target; - - this.props.setDarkTime(value, options); - } - - formatHour(time: string, clock24h: boolean) { - if (clock24h) { - return `${time}:00`; - } - - const now = new Date(0, 0, 0, Number(time)); - - const hour = now.toLocaleTimeString('en-US', { hour12: true, hour: '2-digit' }); - - return hour; - } - setDaemonSetting(name: string, value: ?SetDaemonSettingArg): void { this.props.setDaemonSetting(name, value); } @@ -137,9 +82,6 @@ class SettingsPage extends React.PureComponent { allowAnalytics, showNsfw, isAuthenticated, - currentTheme, - themes, - automaticDarkModeEnabled, clock24h, autoplay, // autoDownload, @@ -149,17 +91,13 @@ class SettingsPage extends React.PureComponent { floatingPlayer, hideReposts, clearPlayingUri, - darkModeTimes, openModal, myChannelUrls, user, } = this.props; const noDaemonSettings = !daemonSettings || Object.keys(daemonSettings).length === 0; - const startHours = ['18', '19', '20', '21']; - const endHours = ['5', '6', '7', '8']; const newStyle = true; - return newStyle ? ( @@ -219,61 +157,6 @@ class SettingsPage extends React.PureComponent { title={__('Appearance')} actions={ - - - {themes.map((theme) => ( - - ))} - - - - this.onAutomaticDarkModeChange(!automaticDarkModeEnabled)} - checked={automaticDarkModeEnabled} - label={__('Automatic dark mode')} - /> - {automaticDarkModeEnabled && ( - - this.onChangeTime(value, { fromTo: 'from', time: 'hour' })} - value={darkModeTimes.from.hour} - label={__('From --[initial time]--')} - > - {startHours.map((time) => ( - - ))} - - this.onChangeTime(value, { fromTo: 'to', time: 'hour' })} - value={darkModeTimes.to.hour} - > - {endHours.map((time) => ( - - ))} - - - )} - Date: Thu, 5 Aug 2021 20:48:04 +0800 Subject: [PATCH 24/58] [Appearance] grab 24h clock setting --- ui/component/settingAppearance/index.js | 11 +++++++++-- ui/component/settingAppearance/view.jsx | 20 ++++++++++++++++++-- ui/page/settings/index.js | 1 - ui/page/settings/view.jsx | 23 ----------------------- 4 files changed, 27 insertions(+), 28 deletions(-) diff --git a/ui/component/settingAppearance/index.js b/ui/component/settingAppearance/index.js index 30230b578..609263f25 100644 --- a/ui/component/settingAppearance/index.js +++ b/ui/component/settingAppearance/index.js @@ -1,8 +1,15 @@ import { connect } from 'react-redux'; +import { SETTINGS } from 'lbry-redux'; +import { doSetClientSetting } from 'redux/actions/settings'; +import { makeSelectClientSetting } from 'redux/selectors/settings'; import SettingAppearance from './view'; -const select = (state) => ({}); +const select = (state) => ({ + clock24h: makeSelectClientSetting(SETTINGS.CLOCK_24H)(state), +}); -const perform = (dispatch) => ({}); +const perform = (dispatch) => ({ + setClientSetting: (key, value) => dispatch(doSetClientSetting(key, value)), +}); export default connect(select, perform)(SettingAppearance); diff --git a/ui/component/settingAppearance/view.jsx b/ui/component/settingAppearance/view.jsx index 2aa59bfe7..0a3d42616 100644 --- a/ui/component/settingAppearance/view.jsx +++ b/ui/component/settingAppearance/view.jsx @@ -1,15 +1,22 @@ // @flow import React from 'react'; +import { SETTINGS } from 'lbry-redux'; import Card from 'component/common/card'; +import { FormField } from 'component/common/form'; import HomepageSelector from 'component/homepageSelector'; import SettingLanguage from 'component/settingLanguage'; import ThemeSelector from 'component/themeSelector'; // $FlowFixMe import homepages from 'homepages'; -type Props = {}; +type Props = { + clock24h: boolean, + setClientSetting: (string, boolean | string | number) => void, +}; export default function SettingAppearance(props: Props) { + const { clock24h, setClientSetting } = props; + return (
- + SettingsRow title={__('Theme')}> + + + setClientSetting(SETTINGS.CLOCK_24H, !clock24h)} + checked={clock24h} + /> + } /> diff --git a/ui/page/settings/index.js b/ui/page/settings/index.js index 48965eaf2..c72fc75ba 100644 --- a/ui/page/settings/index.js +++ b/ui/page/settings/index.js @@ -19,7 +19,6 @@ const select = (state) => ({ allowAnalytics: selectAllowAnalytics(state), isAuthenticated: selectUserVerifiedEmail(state), showNsfw: selectShowMatureContent(state), - clock24h: makeSelectClientSetting(SETTINGS.CLOCK_24H)(state), autoplay: makeSelectClientSetting(SETTINGS.AUTOPLAY)(state), autoDownload: makeSelectClientSetting(SETTINGS.AUTO_DOWNLOAD)(state), hideBalance: makeSelectClientSetting(SETTINGS.HIDE_BALANCE)(state), diff --git a/ui/page/settings/view.jsx b/ui/page/settings/view.jsx index 6ab968cac..6c91aa7b2 100644 --- a/ui/page/settings/view.jsx +++ b/ui/page/settings/view.jsx @@ -41,7 +41,6 @@ type Props = { isAuthenticated: boolean, instantPurchaseEnabled: boolean, instantPurchaseMax: Price, - clock24h: boolean, autoplay: boolean, floatingPlayer: boolean, hideReposts: ?boolean, @@ -64,10 +63,6 @@ class SettingsPage extends React.PureComponent { exitSettings(); } - onClock24hChange(value: boolean) { - this.props.setClientSetting(SETTINGS.CLOCK_24H, value); - } - setDaemonSetting(name: string, value: ?SetDaemonSettingArg): void { this.props.setDaemonSetting(name, value); } @@ -82,7 +77,6 @@ class SettingsPage extends React.PureComponent { allowAnalytics, showNsfw, isAuthenticated, - clock24h, autoplay, // autoDownload, setDaemonSetting, @@ -153,23 +147,6 @@ class SettingsPage extends React.PureComponent { /> {/* @endif */} - - - this.onClock24hChange(!clock24h)} - checked={clock24h} - label={__('24-hour clock')} - /> - -
- } - /> - Date: Thu, 5 Aug 2021 21:16:10 +0800 Subject: [PATCH 25/58] Move combobox to right | Move "Search only in language" into separate row --- static/app-strings.json | 2 +- ui/component/homepageSelector/view.jsx | 9 ++----- ui/component/settingAppearance/index.js | 2 ++ ui/component/settingAppearance/view.jsx | 31 ++++++++++++++++++------- ui/component/settingLanguage/index.js | 13 ++++------- ui/component/settingLanguage/view.jsx | 18 +++----------- 6 files changed, 36 insertions(+), 39 deletions(-) diff --git a/static/app-strings.json b/static/app-strings.json index 0558bba20..b983ff095 100644 --- a/static/app-strings.json +++ b/static/app-strings.json @@ -1610,7 +1610,7 @@ "None selected": "None selected", "Secondary Language": "Secondary Language", "Your other content language": "Your other content language", - "Search only in this language by default": "Search only in this language by default", + "Search only in the selected language by default": "Search only in the selected language by default", "This link leads to an external website.": "This link leads to an external website.", "No Content Found": "No Content Found", "No Lists Found": "No Lists Found", diff --git a/ui/component/homepageSelector/view.jsx b/ui/component/homepageSelector/view.jsx index ce7e15e48..b8eb7adef 100644 --- a/ui/component/homepageSelector/view.jsx +++ b/ui/component/homepageSelector/view.jsx @@ -22,12 +22,7 @@ function SelectHomepage(props: Props) { return null; } return ( -
-
-

{__('Homepage')}

-

{__('Tailor your experience.')}

-
- + ))} -
+ ); } diff --git a/ui/component/settingAppearance/index.js b/ui/component/settingAppearance/index.js index 609263f25..54db43d7f 100644 --- a/ui/component/settingAppearance/index.js +++ b/ui/component/settingAppearance/index.js @@ -6,10 +6,12 @@ import SettingAppearance from './view'; const select = (state) => ({ clock24h: makeSelectClientSetting(SETTINGS.CLOCK_24H)(state), + searchInLanguage: makeSelectClientSetting(SETTINGS.SEARCH_IN_LANGUAGE)(state), }); const perform = (dispatch) => ({ setClientSetting: (key, value) => dispatch(doSetClientSetting(key, value)), + setSearchInLanguage: (value) => dispatch(doSetClientSetting(SETTINGS.SEARCH_IN_LANGUAGE, value)), }); export default connect(select, perform)(SettingAppearance); diff --git a/ui/component/settingAppearance/view.jsx b/ui/component/settingAppearance/view.jsx index 0a3d42616..f9f674da9 100644 --- a/ui/component/settingAppearance/view.jsx +++ b/ui/component/settingAppearance/view.jsx @@ -5,17 +5,20 @@ import Card from 'component/common/card'; import { FormField } from 'component/common/form'; import HomepageSelector from 'component/homepageSelector'; import SettingLanguage from 'component/settingLanguage'; +import SettingsRow from 'component/settingsRow'; import ThemeSelector from 'component/themeSelector'; // $FlowFixMe import homepages from 'homepages'; type Props = { clock24h: boolean, + searchInLanguage: boolean, setClientSetting: (string, boolean | string | number) => void, + setSearchInLanguage: (boolean) => void, }; export default function SettingAppearance(props: Props) { - const { clock24h, setClientSetting } = props; + const { clock24h, searchInLanguage, setClientSetting, setSearchInLanguage } = props; return ( - {/* --- Homepage --- */} {homepages && Object.keys(homepages).length > 1 && ( -
+ -
+ )} - {/* --- Language --- */} -
+ -
+ - SettingsRow title={__('Theme')}> + + setSearchInLanguage(!searchInLanguage)} + /> + + + @@ -53,3 +63,8 @@ export default function SettingAppearance(props: Props) { /> ); } + +// prettier-disable +const HELP = { + LANGUAGE: 'Multi-language support is brand new and incomplete. Switching your language may have unintended consequences, like glossolalia.', +}; diff --git a/ui/component/settingLanguage/index.js b/ui/component/settingLanguage/index.js index 5a3d60abe..34ee83fd5 100644 --- a/ui/component/settingLanguage/index.js +++ b/ui/component/settingLanguage/index.js @@ -1,17 +1,14 @@ import { connect } from 'react-redux'; -import { SETTINGS } from 'lbry-redux'; -import { doSetLanguage, doSetClientSetting } from 'redux/actions/settings'; -import { makeSelectClientSetting, selectLanguage } from 'redux/selectors/settings'; +import { doSetLanguage } from 'redux/actions/settings'; +import { selectLanguage } from 'redux/selectors/settings'; import SettingLanguage from './view'; -const select = state => ({ +const select = (state) => ({ language: selectLanguage(state), - searchInLanguage: makeSelectClientSetting(SETTINGS.SEARCH_IN_LANGUAGE)(state), }); -const perform = dispatch => ({ - setLanguage: value => dispatch(doSetLanguage(value)), - setSearchInLanguage: value => dispatch(doSetClientSetting(SETTINGS.SEARCH_IN_LANGUAGE, value)), +const perform = (dispatch) => ({ + setLanguage: (value) => dispatch(doSetLanguage(value)), }); export default connect(select, perform)(SettingLanguage); diff --git a/ui/component/settingLanguage/view.jsx b/ui/component/settingLanguage/view.jsx index cb58a7f19..515970d6e 100644 --- a/ui/component/settingLanguage/view.jsx +++ b/ui/component/settingLanguage/view.jsx @@ -10,12 +10,10 @@ import { getDefaultLanguage, sortLanguageMap } from 'util/default-languages'; type Props = { language: string, setLanguage: (string) => void, - searchInLanguage: boolean, - setSearchInLanguage: (boolean) => void, }; function SettingLanguage(props: Props) { - const { language, setLanguage, searchInLanguage, setSearchInLanguage } = props; + const { language, setLanguage } = props; const [previousLanguage, setPreviousLanguage] = useState(null); if (previousLanguage && language !== previousLanguage) { @@ -37,15 +35,13 @@ function SettingLanguage(props: Props) { return ( + {previousLanguage && } + {sortLanguageMap(SUPPORTED_LANGUAGES).map(([langKey, langName]) => ( ))} - {previousLanguage && } - setSearchInLanguage(!searchInLanguage)} - /> ); } -- 2.45.3 From 859ccf5ea906f45fd6986f9ea1e114115edceee8 Mon Sep 17 00:00:00 2001 From: infinite-persistence Date: Fri, 6 Aug 2021 10:41:37 +0800 Subject: [PATCH 26/58] [Content] grab original "Content Settings" --- ui/component/settingContent/index.js | 24 ++++++ ui/component/settingContent/view.jsx | 115 +++++++++++++++++++++++++++ ui/page/settings/index.js | 13 +-- ui/page/settings/view.jsx | 96 +--------------------- 4 files changed, 143 insertions(+), 105 deletions(-) create mode 100644 ui/component/settingContent/index.js create mode 100644 ui/component/settingContent/view.jsx diff --git a/ui/component/settingContent/index.js b/ui/component/settingContent/index.js new file mode 100644 index 000000000..50860ae69 --- /dev/null +++ b/ui/component/settingContent/index.js @@ -0,0 +1,24 @@ +import { connect } from 'react-redux'; +import { SETTINGS } from 'lbry-redux'; +import { doOpenModal } from 'redux/actions/app'; +import { doSetPlayingUri } from 'redux/actions/content'; +import { doSetClientSetting } from 'redux/actions/settings'; +import { selectShowMatureContent, makeSelectClientSetting } from 'redux/selectors/settings'; +import { selectUserVerifiedEmail } from 'redux/selectors/user'; +import SettingContent from './view'; + +const select = (state) => ({ + isAuthenticated: selectUserVerifiedEmail(state), + floatingPlayer: makeSelectClientSetting(SETTINGS.FLOATING_PLAYER)(state), + autoplay: makeSelectClientSetting(SETTINGS.AUTOPLAY)(state), + hideReposts: makeSelectClientSetting(SETTINGS.HIDE_REPOSTS)(state), + showNsfw: selectShowMatureContent(state), +}); + +const perform = (dispatch) => ({ + setClientSetting: (key, value) => dispatch(doSetClientSetting(key, value)), + clearPlayingUri: () => dispatch(doSetPlayingUri({ uri: null })), + openModal: (id, params) => dispatch(doOpenModal(id, params)), +}); + +export default connect(select, perform)(SettingContent); diff --git a/ui/component/settingContent/view.jsx b/ui/component/settingContent/view.jsx new file mode 100644 index 000000000..c8c258f60 --- /dev/null +++ b/ui/component/settingContent/view.jsx @@ -0,0 +1,115 @@ +// @flow +import React from 'react'; +import { SETTINGS } from 'lbry-redux'; +import { Lbryio } from 'lbryinc'; +import { SIMPLE_SITE } from 'config'; +import * as MODALS from 'constants/modal_types'; +import Card from 'component/common/card'; +import { FormField } from 'component/common/form'; +import MaxPurchasePrice from 'component/maxPurchasePrice'; +import SettingsRow from 'component/settingsRow'; + +const HELP_FLOATING_PLAYER = 'Keep content playing in the corner when navigating to a different page.'; +const HELP_AUTOPLAY = + 'Autoplay video and audio files when navigating to a file, as well as the next related item when a file finishes playing.'; +const HELP_HIDE_REPOSTS = 'You will not see reposts by people you follow or receive email notifying about them.'; +const HELP_SHOW_MATURE = + 'Mature content may include nudity, intense sexuality, profanity, or other adult content. By displaying mature content, you are affirming you are of legal age to view mature content in your country or jurisdiction. '; + +type Props = { + isAuthenticated: boolean, + floatingPlayer: boolean, + autoplay: boolean, + hideReposts: ?boolean, + showNsfw: boolean, + setClientSetting: (string, boolean | string | number) => void, + clearPlayingUri: () => void, + openModal: (string) => void, +}; + +export default function SettingContent(props: Props) { + const { + isAuthenticated, + floatingPlayer, + autoplay, + hideReposts, + showNsfw, + setClientSetting, + clearPlayingUri, + openModal, + } = props; + + return ( + + + { + setClientSetting(SETTINGS.FLOATING_PLAYER, !floatingPlayer); + clearPlayingUri(); + }} + checked={floatingPlayer} + /> + + + + setClientSetting(SETTINGS.AUTOPLAY, !autoplay)} + checked={autoplay} + /> + + + {!SIMPLE_SITE && ( + <> + + { + if (isAuthenticated) { + let param = e.target.checked ? { add: 'noreposts' } : { remove: 'noreposts' }; + Lbryio.call('user_tag', 'edit', param); + } + setClientSetting(SETTINGS.HIDE_REPOSTS, !hideReposts); + }} + /> + + + {/* + + setClientSetting(SETTINGS.SHOW_ANONYMOUS, !showAnonymous)} + checked={showAnonymous} + /> + + */} + + + + !IS_WEB || showNsfw + ? setClientSetting(SETTINGS.SHOW_MATURE, !showNsfw) + : openModal(MODALS.CONFIRM_AGE) + } + /> + + + )} + + } + /> + ); +} diff --git a/ui/page/settings/index.js b/ui/page/settings/index.js index c72fc75ba..8a6043086 100644 --- a/ui/page/settings/index.js +++ b/ui/page/settings/index.js @@ -1,15 +1,13 @@ import { connect } from 'react-redux'; -import { doToggle3PAnalytics, doOpenModal } from 'redux/actions/app'; +import { doToggle3PAnalytics } from 'redux/actions/app'; import { selectAllowAnalytics } from 'redux/selectors/app'; import { doSetDaemonSetting, doClearDaemonSetting, - doSetClientSetting, doEnterSettingsPage, doExitSettingsPage, } from 'redux/actions/settings'; -import { doSetPlayingUri } from 'redux/actions/content'; -import { makeSelectClientSetting, selectDaemonSettings, selectShowMatureContent } from 'redux/selectors/settings'; +import { makeSelectClientSetting, selectDaemonSettings } from 'redux/selectors/settings'; import { selectMyChannelUrls, SETTINGS } from 'lbry-redux'; import SettingsPage from './view'; import { selectUserVerifiedEmail, selectUser } from 'redux/selectors/user'; @@ -18,12 +16,8 @@ const select = (state) => ({ daemonSettings: selectDaemonSettings(state), allowAnalytics: selectAllowAnalytics(state), isAuthenticated: selectUserVerifiedEmail(state), - showNsfw: selectShowMatureContent(state), - autoplay: makeSelectClientSetting(SETTINGS.AUTOPLAY)(state), autoDownload: makeSelectClientSetting(SETTINGS.AUTO_DOWNLOAD)(state), hideBalance: makeSelectClientSetting(SETTINGS.HIDE_BALANCE)(state), - floatingPlayer: makeSelectClientSetting(SETTINGS.FLOATING_PLAYER)(state), - hideReposts: makeSelectClientSetting(SETTINGS.HIDE_REPOSTS)(state), myChannelUrls: selectMyChannelUrls(state), user: selectUser(state), }); @@ -32,9 +26,6 @@ const perform = (dispatch) => ({ setDaemonSetting: (key, value) => dispatch(doSetDaemonSetting(key, value)), clearDaemonSetting: (key) => dispatch(doClearDaemonSetting(key)), toggle3PAnalytics: (allow) => dispatch(doToggle3PAnalytics(allow)), - setClientSetting: (key, value) => dispatch(doSetClientSetting(key, value)), - clearPlayingUri: () => dispatch(doSetPlayingUri({ uri: null })), - openModal: (id, params) => dispatch(doOpenModal(id, params)), enterSettings: () => dispatch(doEnterSettingsPage()), exitSettings: () => dispatch(doExitSettingsPage()), }); diff --git a/ui/page/settings/view.jsx b/ui/page/settings/view.jsx index 6c91aa7b2..c224c15ce 100644 --- a/ui/page/settings/view.jsx +++ b/ui/page/settings/view.jsx @@ -1,20 +1,17 @@ // @flow import * as PAGES from 'constants/pages'; -import * as MODALS from 'constants/modal_types'; import * as ICONS from 'constants/icons'; import * as React from 'react'; -import { SETTINGS } from 'lbry-redux'; import { FormField } from 'component/common/form'; import Button from 'component/button'; import Page from 'component/page'; import SettingAccount from 'component/settingAccount'; import SettingAppearance from 'component/settingAppearance'; +import SettingContent from 'component/settingContent'; import SettingSystem from 'component/settingSystem'; import FileSelector from 'component/common/file-selector'; import Card from 'component/common/card'; import classnames from 'classnames'; -import { SIMPLE_SITE } from 'config'; -import { Lbryio } from 'lbryinc'; import Yrbl from 'component/yrbl'; import { getStripeEnvironment } from 'util/stripe'; @@ -33,18 +30,12 @@ type DaemonSettings = { type Props = { setDaemonSetting: (string, ?SetDaemonSettingArg) => void, clearDaemonSetting: (string) => void, - setClientSetting: (string, SetDaemonSettingArg) => void, toggle3PAnalytics: (boolean) => void, daemonSettings: DaemonSettings, allowAnalytics: boolean, - showNsfw: boolean, isAuthenticated: boolean, instantPurchaseEnabled: boolean, instantPurchaseMax: Price, - autoplay: boolean, - floatingPlayer: boolean, - hideReposts: ?boolean, - clearPlayingUri: () => void, openModal: (string) => void, enterSettings: () => void, exitSettings: () => void, @@ -75,17 +66,10 @@ class SettingsPage extends React.PureComponent { const { daemonSettings, allowAnalytics, - showNsfw, isAuthenticated, - autoplay, // autoDownload, setDaemonSetting, - setClientSetting, toggle3PAnalytics, - floatingPlayer, - hideReposts, - clearPlayingUri, - openModal, myChannelUrls, user, } = this.props; @@ -96,6 +80,7 @@ class SettingsPage extends React.PureComponent { + ) : ( @@ -147,83 +132,6 @@ class SettingsPage extends React.PureComponent { /> {/* @endif */} - - { - setClientSetting(SETTINGS.FLOATING_PLAYER, !floatingPlayer); - clearPlayingUri(); - }} - checked={floatingPlayer} - label={__('Floating video player')} - helper={__('Keep content playing in the corner when navigating to a different page.')} - /> - - setClientSetting(SETTINGS.AUTOPLAY, !autoplay)} - checked={autoplay} - label={__('Autoplay media files')} - helper={__( - 'Autoplay video and audio files when navigating to a file, as well as the next related item when a file finishes playing.' - )} - /> - {!SIMPLE_SITE && ( - <> - { - if (isAuthenticated) { - let param = e.target.checked ? { add: 'noreposts' } : { remove: 'noreposts' }; - Lbryio.call('user_tag', 'edit', param); - } - - setClientSetting(SETTINGS.HIDE_REPOSTS, !hideReposts); - }} - checked={hideReposts} - label={__('Hide reposts')} - helper={__( - 'You will not see reposts by people you follow or receive email notifying about them.' - )} - /> - - {/* - setClientSetting(SETTINGS.SHOW_ANONYMOUS, !showAnonymous)} - checked={showAnonymous} - label={__('Show anonymous content')} - helper={__('Anonymous content is published without a channel.')} - /> - */} - - - !IS_WEB || showNsfw - ? setClientSetting(SETTINGS.SHOW_MATURE, !showNsfw) - : openModal(MODALS.CONFIRM_AGE) - } - checked={showNsfw} - label={__('Show mature content')} - helper={__( - 'Mature content may include nudity, intense sexuality, profanity, or other adult content. By displaying mature content, you are affirming you are of legal age to view mature content in your country or jurisdiction. ' - )} - /> - - )} - - } - /> - {/* @if TARGET='app' */} Date: Fri, 6 Aug 2021 13:58:34 +0800 Subject: [PATCH 27/58] [Content] refactor and grab Max Purchase Price --- ui/component/maxPurchasePrice/index.js | 13 +++++ ui/component/maxPurchasePrice/view.jsx | 72 ++++++++++++++++++++++++++ ui/component/settingContent/view.jsx | 8 +++ ui/page/settingsAdvanced/index.js | 2 - ui/page/settingsAdvanced/view.jsx | 55 -------------------- 5 files changed, 93 insertions(+), 57 deletions(-) create mode 100644 ui/component/maxPurchasePrice/index.js create mode 100644 ui/component/maxPurchasePrice/view.jsx diff --git a/ui/component/maxPurchasePrice/index.js b/ui/component/maxPurchasePrice/index.js new file mode 100644 index 000000000..ed04f6cfe --- /dev/null +++ b/ui/component/maxPurchasePrice/index.js @@ -0,0 +1,13 @@ +import { connect } from 'react-redux'; +import { doSetDaemonSetting } from 'redux/actions/settings'; +import { selectDaemonSettings } from 'redux/selectors/settings'; +import MaxPurchasePrice from './view'; + +const select = (state) => ({ + daemonSettings: selectDaemonSettings(state), +}); +const perform = (dispatch) => ({ + setDaemonSetting: (key, value) => dispatch(doSetDaemonSetting(key, value)), +}); + +export default connect(select, perform)(MaxPurchasePrice); diff --git a/ui/component/maxPurchasePrice/view.jsx b/ui/component/maxPurchasePrice/view.jsx new file mode 100644 index 000000000..bd163ec81 --- /dev/null +++ b/ui/component/maxPurchasePrice/view.jsx @@ -0,0 +1,72 @@ +// @flow +import React from 'react'; +import { FormField, FormFieldPrice } from 'component/common/form'; + +type Price = { + currency: string, + amount: number, +}; + +type DaemonSettings = { + download_dir: string, + share_usage_data: boolean, + max_key_fee?: Price, + max_connections_per_download?: number, + save_files: boolean, + save_blobs: boolean, + ffmpeg_path: string, +}; + +type SetDaemonSettingArg = boolean | string | number | Price; + +type Props = { + daemonSettings: DaemonSettings, + setDaemonSetting: (string, ?SetDaemonSettingArg) => void, +}; + +export default function MaxPurchasePrice(props: Props) { + const { daemonSettings, setDaemonSetting } = props; + + const defaultMaxKeyFee = { currency: 'USD', amount: 50 }; + const disableMaxKeyFee = !(daemonSettings && daemonSettings.max_key_fee); + + function onKeyFeeDisableChange(isDisabled: boolean) { + if (isDisabled) { + setDaemonSetting('max_key_fee'); + } + } + + function onKeyFeeChange(newValue: Price) { + setDaemonSetting('max_key_fee', newValue); + } + + return ( + <> + onKeyFeeDisableChange(true)} + /> + { + onKeyFeeDisableChange(false); + onKeyFeeChange(defaultMaxKeyFee); + }} + label={__('Choose limit')} + /> + + + + ); +} diff --git a/ui/component/settingContent/view.jsx b/ui/component/settingContent/view.jsx index c8c258f60..49fee1e42 100644 --- a/ui/component/settingContent/view.jsx +++ b/ui/component/settingContent/view.jsx @@ -15,6 +15,8 @@ const HELP_AUTOPLAY = const HELP_HIDE_REPOSTS = 'You will not see reposts by people you follow or receive email notifying about them.'; const HELP_SHOW_MATURE = 'Mature content may include nudity, intense sexuality, profanity, or other adult content. By displaying mature content, you are affirming you are of legal age to view mature content in your country or jurisdiction. '; +const HELP_MAX_PURCHASE_PRICE = + 'This will prevent you from purchasing any content over a certain cost, as a safety measure.'; type Props = { isAuthenticated: boolean, @@ -108,6 +110,12 @@ export default function SettingContent(props: Props) { )} + + {/* @if TARGET='app' */} + + + + {/* @endif */} } /> diff --git a/ui/page/settingsAdvanced/index.js b/ui/page/settingsAdvanced/index.js index c42fac57f..83af06a5f 100644 --- a/ui/page/settingsAdvanced/index.js +++ b/ui/page/settingsAdvanced/index.js @@ -11,7 +11,6 @@ import { } from 'redux/actions/settings'; import { makeSelectClientSetting, - selectLanguage, selectDaemonSettings, selectFfmpegStatus, selectFindingFFmpeg, @@ -30,7 +29,6 @@ const select = (state) => ({ hideBalance: makeSelectClientSetting(SETTINGS.HIDE_BALANCE)(state), ffmpegStatus: selectFfmpegStatus(state), findingFFmpeg: selectFindingFFmpeg(state), - language: selectLanguage(state), syncEnabled: makeSelectClientSetting(SETTINGS.ENABLE_SYNC)(state), }); diff --git a/ui/page/settingsAdvanced/view.jsx b/ui/page/settingsAdvanced/view.jsx index c4a380751..60facac50 100644 --- a/ui/page/settingsAdvanced/view.jsx +++ b/ui/page/settingsAdvanced/view.jsx @@ -48,7 +48,6 @@ type Props = { ffmpegStatus: { available: boolean, which: string }, findingFFmpeg: boolean, findFFmpeg: () => void, - language?: string, syncEnabled: boolean, enterSettings: () => void, exitSettings: () => void, @@ -68,9 +67,7 @@ class SettingsAdvancedPage extends React.PureComponent { storedPassword: false, }; - (this: any).onKeyFeeChange = this.onKeyFeeChange.bind(this); (this: any).onMaxConnectionsChange = this.onMaxConnectionsChange.bind(this); - (this: any).onKeyFeeDisableChange = this.onKeyFeeDisableChange.bind(this); (this: any).onInstantPurchaseMaxChange = this.onInstantPurchaseMaxChange.bind(this); (this: any).onThemeChange = this.onThemeChange.bind(this); (this: any).onAutomaticDarkModeChange = this.onAutomaticDarkModeChange.bind(this); @@ -112,19 +109,11 @@ class SettingsAdvancedPage extends React.PureComponent { this.findFFmpeg(); } - onKeyFeeChange(newValue: Price) { - this.setDaemonSetting('max_key_fee', newValue); - } - onMaxConnectionsChange(event: SyntheticInputEvent<*>) { const { value } = event.target; this.setDaemonSetting('max_connections_per_download', value); } - onKeyFeeDisableChange(isDisabled: boolean) { - if (isDisabled) this.setDaemonSetting('max_key_fee'); - } - onThemeChange(event: SyntheticInputEvent<*>) { const { value } = event.target; @@ -189,13 +178,10 @@ class SettingsAdvancedPage extends React.PureComponent { setClientSetting, hideBalance, findingFFmpeg, - language, } = this.props; const { storedPassword } = this.state; const noDaemonSettings = !daemonSettings || Object.keys(daemonSettings).length === 0; - const defaultMaxKeyFee = { currency: 'USD', amount: 50 }; - const disableMaxKeyFee = !(daemonSettings && daemonSettings.max_key_fee); const connectionOptions = [1, 2, 4, 6, 10, 20]; // @if TARGET='app' const { available: ffmpegAvailable, which: ffmpegPath } = ffmpegStatus; @@ -249,47 +235,6 @@ class SettingsAdvancedPage extends React.PureComponent { } /> - - - { - this.onKeyFeeDisableChange(true); - }} - /> - { - this.onKeyFeeDisableChange(false); - this.onKeyFeeChange(defaultMaxKeyFee); - }} - label={__('Choose limit')} - /> - - {!disableMaxKeyFee && ( - - )} - -

- {__('This will prevent you from purchasing any content over a certain cost, as a safety measure.')} -

- - } - /> {/* @endif */} Date: Fri, 6 Aug 2021 15:43:21 +0800 Subject: [PATCH 28/58] [Account] grab stripe-related settings --- ui/component/settingAccount/index.js | 3 +- ui/component/settingAccount/view.jsx | 40 ++++++++++++++++++++++++++- ui/page/settings/index.js | 3 +- ui/page/settings/view.jsx | 41 ---------------------------- 4 files changed, 42 insertions(+), 45 deletions(-) diff --git a/ui/component/settingAccount/index.js b/ui/component/settingAccount/index.js index 9abbe808b..596776c1f 100644 --- a/ui/component/settingAccount/index.js +++ b/ui/component/settingAccount/index.js @@ -1,11 +1,12 @@ import { connect } from 'react-redux'; import { doWalletStatus, selectWalletIsEncrypted } from 'lbry-redux'; -import { selectUserVerifiedEmail } from 'redux/selectors/user'; +import { selectUser, selectUserVerifiedEmail } from 'redux/selectors/user'; import SettingAccount from './view'; const select = (state) => ({ isAuthenticated: selectUserVerifiedEmail(state), walletEncrypted: selectWalletIsEncrypted(state), + user: selectUser(state), }); const perform = (dispatch) => ({ diff --git a/ui/component/settingAccount/view.jsx b/ui/component/settingAccount/view.jsx index 4097b532d..a1ea5a347 100644 --- a/ui/component/settingAccount/view.jsx +++ b/ui/component/settingAccount/view.jsx @@ -1,20 +1,26 @@ // @flow +import * as ICONS from 'constants/icons'; +import * as PAGES from 'constants/pages'; import React from 'react'; +import Button from 'component/button'; import Card from 'component/common/card'; import SettingAccountPassword from 'component/settingAccountPassword'; +import SettingsRow from 'component/settingsRow'; import SyncToggle from 'component/syncToggle'; import { getPasswordFromCookie } from 'util/saved-passwords'; +import { getStripeEnvironment } from 'util/stripe'; type Props = { // --- select --- isAuthenticated: boolean, walletEncrypted: boolean, + user: User, // --- perform --- doWalletStatus: () => void, }; export default function SettingAccount(props: Props) { - const { isAuthenticated, walletEncrypted, doWalletStatus } = props; + const { isAuthenticated, walletEncrypted, user, doWalletStatus } = props; const [storedPassword, setStoredPassword] = React.useState(false); // Determine if password is stored. @@ -48,6 +54,38 @@ export default function SettingAccount(props: Props) {
{/* @endif */} + + {/* @if TARGET='web' */} + {user && getStripeEnvironment() && ( + +
- } - /> - )} - {/* @endif */} - - {/* @if TARGET='web' */} - {isAuthenticated && getStripeEnvironment() && ( - -
- } - /> - )} - {/* @endif */} - {(isAuthenticated || !IS_WEB) && ( <> Date: Fri, 6 Aug 2021 15:56:48 +0800 Subject: [PATCH 29/58] [Content] grab Notifications, Block/Muted, Creator Settings --- ui/component/settingContent/index.js | 3 +- ui/component/settingContent/view.jsx | 56 +++++++++++++++++++++++----- ui/page/settings/index.js | 3 +- ui/page/settings/view.jsx | 46 ----------------------- 4 files changed, 50 insertions(+), 58 deletions(-) diff --git a/ui/component/settingContent/index.js b/ui/component/settingContent/index.js index 50860ae69..073cb4915 100644 --- a/ui/component/settingContent/index.js +++ b/ui/component/settingContent/index.js @@ -1,5 +1,5 @@ import { connect } from 'react-redux'; -import { SETTINGS } from 'lbry-redux'; +import { selectMyChannelUrls, SETTINGS } from 'lbry-redux'; import { doOpenModal } from 'redux/actions/app'; import { doSetPlayingUri } from 'redux/actions/content'; import { doSetClientSetting } from 'redux/actions/settings'; @@ -13,6 +13,7 @@ const select = (state) => ({ autoplay: makeSelectClientSetting(SETTINGS.AUTOPLAY)(state), hideReposts: makeSelectClientSetting(SETTINGS.HIDE_REPOSTS)(state), showNsfw: selectShowMatureContent(state), + myChannelUrls: selectMyChannelUrls(state), }); const perform = (dispatch) => ({ diff --git a/ui/component/settingContent/view.jsx b/ui/component/settingContent/view.jsx index 49fee1e42..5df04f286 100644 --- a/ui/component/settingContent/view.jsx +++ b/ui/component/settingContent/view.jsx @@ -1,29 +1,24 @@ // @flow +import * as ICONS from 'constants/icons'; +import * as PAGES from 'constants/pages'; import React from 'react'; import { SETTINGS } from 'lbry-redux'; import { Lbryio } from 'lbryinc'; import { SIMPLE_SITE } from 'config'; import * as MODALS from 'constants/modal_types'; +import Button from 'component/button'; import Card from 'component/common/card'; import { FormField } from 'component/common/form'; import MaxPurchasePrice from 'component/maxPurchasePrice'; import SettingsRow from 'component/settingsRow'; -const HELP_FLOATING_PLAYER = 'Keep content playing in the corner when navigating to a different page.'; -const HELP_AUTOPLAY = - 'Autoplay video and audio files when navigating to a file, as well as the next related item when a file finishes playing.'; -const HELP_HIDE_REPOSTS = 'You will not see reposts by people you follow or receive email notifying about them.'; -const HELP_SHOW_MATURE = - 'Mature content may include nudity, intense sexuality, profanity, or other adult content. By displaying mature content, you are affirming you are of legal age to view mature content in your country or jurisdiction. '; -const HELP_MAX_PURCHASE_PRICE = - 'This will prevent you from purchasing any content over a certain cost, as a safety measure.'; - type Props = { isAuthenticated: boolean, floatingPlayer: boolean, autoplay: boolean, hideReposts: ?boolean, showNsfw: boolean, + myChannelUrls: ?Array, setClientSetting: (string, boolean | string | number) => void, clearPlayingUri: () => void, openModal: (string) => void, @@ -36,6 +31,7 @@ export default function SettingContent(props: Props) { autoplay, hideReposts, showNsfw, + myChannelUrls, setClientSetting, clearPlayingUri, openModal, @@ -111,6 +107,39 @@ export default function SettingContent(props: Props) { )} + {(isAuthenticated || !IS_WEB) && ( + <> + +
- } - /> - - -
- } - /> - - {myChannelUrls && myChannelUrls.length > 0 && ( - -
- } - /> - )} - Date: Fri, 6 Aug 2021 16:25:37 +0800 Subject: [PATCH 30/58] [System] grab Network & Data Settings --- ui/component/settingSystem/index.js | 7 ++- ui/component/settingSystem/view.jsx | 70 ++++++++++++++++++++++++++--- ui/page/settingsAdvanced/index.js | 2 - ui/page/settingsAdvanced/view.jsx | 38 +--------------- 4 files changed, 70 insertions(+), 47 deletions(-) diff --git a/ui/component/settingSystem/index.js b/ui/component/settingSystem/index.js index ccd1fbaab..0c27e9c92 100644 --- a/ui/component/settingSystem/index.js +++ b/ui/component/settingSystem/index.js @@ -1,10 +1,15 @@ import { connect } from 'react-redux'; import { doClearCache } from 'redux/actions/app'; +import { doSetDaemonSetting } from 'redux/actions/settings'; +import { selectDaemonSettings } from 'redux/selectors/settings'; import SettingSystem from './view'; -const select = (state) => ({}); +const select = (state) => ({ + daemonSettings: selectDaemonSettings(state), +}); const perform = (dispatch) => ({ + setDaemonSetting: (key, value) => dispatch(doSetDaemonSetting(key, value)), clearCache: () => dispatch(doClearCache()), }); diff --git a/ui/component/settingSystem/view.jsx b/ui/component/settingSystem/view.jsx index a91803aec..48b922d0d 100644 --- a/ui/component/settingSystem/view.jsx +++ b/ui/component/settingSystem/view.jsx @@ -3,6 +3,7 @@ import { ALERT } from 'constants/icons'; import React from 'react'; import Button from 'component/button'; import Card from 'component/common/card'; +import { FormField } from 'component/common/form'; import SettingAutoLaunch from 'component/settingAutoLaunch'; import SettingClosingBehavior from 'component/settingClosingBehavior'; import SettingsRow from 'component/settingsRow'; @@ -11,12 +12,31 @@ import SettingsRow from 'component/settingsRow'; const IS_MAC = process.platform === 'darwin'; // @endif +type Price = { + currency: string, + amount: number, +}; + +type SetDaemonSettingArg = boolean | string | number | Price; + +type DaemonSettings = { + download_dir: string, + share_usage_data: boolean, + max_key_fee?: Price, + max_connections_per_download?: number, + save_files: boolean, + save_blobs: boolean, + ffmpeg_path: string, +}; + type Props = { + daemonSettings: DaemonSettings, + setDaemonSetting: (string, ?SetDaemonSettingArg) => void, clearCache: () => Promise, }; export default function SettingSystem(props: Props) { - const { clearCache } = props; + const { daemonSettings, setDaemonSetting, clearCache } = props; const [clearingCache, setClearingCache] = React.useState(false); return ( @@ -26,10 +46,47 @@ export default function SettingSystem(props: Props) { isBodyList body={ <> + {/* @if TARGET='app' */} + + setDaemonSetting('save_files', !daemonSettings.save_files)} + checked={daemonSettings.save_files} + /> + + + {__("If disabled, LBRY will be very sad and you won't be helping improve the network.")}{' '} +
)} -- 2.45.3 From 96ac5a899752de0c667d12e06087060d38d4bc8d Mon Sep 17 00:00:00 2001 From: infinite-persistence Date: Sat, 7 Aug 2021 21:35:11 +0800 Subject: [PATCH 34/58] [System] grab "ffmpeg" --- ui/component/settingSystem/index.js | 8 +- ui/component/settingSystem/view.jsx | 99 ++++++++++++++++++++++++- ui/page/settingsAdvanced/index.js | 19 +---- ui/page/settingsAdvanced/view.jsx | 110 +--------------------------- 4 files changed, 108 insertions(+), 128 deletions(-) diff --git a/ui/component/settingSystem/index.js b/ui/component/settingSystem/index.js index 0c27e9c92..a8b195d78 100644 --- a/ui/component/settingSystem/index.js +++ b/ui/component/settingSystem/index.js @@ -1,16 +1,20 @@ import { connect } from 'react-redux'; import { doClearCache } from 'redux/actions/app'; -import { doSetDaemonSetting } from 'redux/actions/settings'; -import { selectDaemonSettings } from 'redux/selectors/settings'; +import { doSetDaemonSetting, doClearDaemonSetting, doFindFFmpeg } from 'redux/actions/settings'; +import { selectDaemonSettings, selectFfmpegStatus, selectFindingFFmpeg } from 'redux/selectors/settings'; import SettingSystem from './view'; const select = (state) => ({ daemonSettings: selectDaemonSettings(state), + ffmpegStatus: selectFfmpegStatus(state), + findingFFmpeg: selectFindingFFmpeg(state), }); const perform = (dispatch) => ({ setDaemonSetting: (key, value) => dispatch(doSetDaemonSetting(key, value)), + clearDaemonSetting: (key) => dispatch(doClearDaemonSetting(key)), clearCache: () => dispatch(doClearCache()), + findFFmpeg: () => dispatch(doFindFFmpeg()), }); export default connect(select, perform)(SettingSystem); diff --git a/ui/component/settingSystem/view.jsx b/ui/component/settingSystem/view.jsx index 770a31c80..e0ff6e775 100644 --- a/ui/component/settingSystem/view.jsx +++ b/ui/component/settingSystem/view.jsx @@ -4,11 +4,14 @@ import React from 'react'; import Button from 'component/button'; import Card from 'component/common/card'; import { FormField } from 'component/common/form'; +import FileSelector from 'component/common/file-selector'; +import I18nMessage from 'component/i18nMessage'; import SettingAutoLaunch from 'component/settingAutoLaunch'; import SettingClosingBehavior from 'component/settingClosingBehavior'; import SettingCommentsServer from 'component/settingCommentsServer'; import SettingsRow from 'component/settingsRow'; import SettingWalletServer from 'component/settingWalletServer'; +import Spinner from 'component/spinner'; // @if TARGET='app' const IS_MAC = process.platform === 'darwin'; @@ -32,15 +35,46 @@ type DaemonSettings = { }; type Props = { + // --- select --- daemonSettings: DaemonSettings, + ffmpegStatus: { available: boolean, which: string }, + findingFFmpeg: boolean, + // --- perform --- setDaemonSetting: (string, ?SetDaemonSettingArg) => void, + clearDaemonSetting: (string) => void, clearCache: () => Promise, + findFFmpeg: () => void, }; export default function SettingSystem(props: Props) { - const { daemonSettings, setDaemonSetting, clearCache } = props; + const { + daemonSettings, + ffmpegStatus, + findingFFmpeg, + setDaemonSetting, + clearDaemonSetting, + clearCache, + findFFmpeg, + } = props; const [clearingCache, setClearingCache] = React.useState(false); + // @if TARGET='app' + const { available: ffmpegAvailable, which: ffmpegPath } = ffmpegStatus; + // @endif + + React.useEffect(() => { + // @if TARGET='app' + const { available } = ffmpegStatus; + const { ffmpeg_path: ffmpegPath } = daemonSettings; + if (!available) { + if (ffmpegPath) { + clearDaemonSetting('ffmpeg_path'); + } + findFFmpeg(); + } + // @endif + }, []); // eslint-disable-line react-hooks/exhaustive-deps + return ( {/* @endif */} + {/* @if TARGET='app' */} + + {__('Automatic transcoding')} + {findingFFmpeg && } +
+ } + > + { + // $FlowFixMe + setDaemonSetting('ffmpeg_path', newDirectory.path); + findFFmpeg(); + }} + disabled={Boolean(ffmpegPath)} + /> +

+ {ffmpegAvailable ? ( + + ), + }} + > + FFmpeg is correctly configured. %learn_more% + + ) : ( + findFFmpeg()} + disabled={findingFFmpeg} + /> + ), + learn_more: ( +