From 0e539d91fe295c124e2850bd81d69b9bdc131f3c Mon Sep 17 00:00:00 2001 From: Matiss Janis Aboltins <matiss@mja.lv> Date: Thu, 7 Sep 2023 06:56:02 +0100 Subject: [PATCH] :sparkles: (mobile) pull down to trigger bank-sync (#1663) * :sparkles: (mobile) pull down to trigger bank-sync * Release notes * Remove canSync checks --- packages/desktop-client/package.json | 1 + .../src/components/accounts/MobileAccount.js | 77 ++++------ .../accounts/MobileAccountDetails.js | 34 +++-- .../src/components/accounts/MobileAccounts.js | 135 ++++++------------ .../transactions/MobileTransaction.js | 8 +- upcoming-release-notes/1663.md | 6 + yarn.lock | 11 ++ 7 files changed, 117 insertions(+), 155 deletions(-) create mode 100644 upcoming-release-notes/1663.md diff --git a/packages/desktop-client/package.json b/packages/desktop-client/package.json index ffa368101..b8dc8f842 100644 --- a/packages/desktop-client/package.json +++ b/packages/desktop-client/package.json @@ -53,6 +53,7 @@ "react-redux": "7.2.1", "react-router-dom": "6.11.2", "react-scripts": "^5.0.1", + "react-simple-pull-to-refresh": "^1.3.3", "react-spring": "^9.7.1", "react-virtualized-auto-sizer": "^1.0.2", "redux": "^4.0.5", diff --git a/packages/desktop-client/src/components/accounts/MobileAccount.js b/packages/desktop-client/src/components/accounts/MobileAccount.js index c206fca0e..83a3f6c5b 100644 --- a/packages/desktop-client/src/components/accounts/MobileAccount.js +++ b/packages/desktop-client/src/components/accounts/MobileAccount.js @@ -19,11 +19,9 @@ import { ungroupTransactions, } from 'loot-core/src/shared/transactions'; -import { useActions } from '../../hooks/useActions'; import useCategories from '../../hooks/useCategories'; import { useSetThemeColor } from '../../hooks/useSetThemeColor'; import { theme } from '../../style'; -import SyncRefresh from '../SyncRefresh'; import AccountDetails from './MobileAccountDetails'; @@ -71,7 +69,6 @@ let paged; export default function Account(props) { const accounts = useSelector(state => state.queries.accounts); - const { syncAndDownload } = useActions(); const navigate = useNavigate(); const [transactions, setTransactions] = useState([]); @@ -191,54 +188,40 @@ export default function Account(props) { } }; - const onRefresh = async () => { - await syncAndDownload(); - }; - let balance = queries.accountBalance(account); let numberFormat = state.prefs.numberFormat || 'comma-dot'; let hideFraction = state.prefs.hideFraction || false; return ( - <SyncRefresh onSync={onRefresh}> - {({ refreshing, onRefresh }) => ( - <SchedulesProvider - transform={getSchedulesTransform(accountId, searchText !== '')} - > - <PreviewTransactions accountId={props.accountId}> - {prependTransactions => - prependTransactions == null ? null : ( - <AccountDetails - // This key forces the whole table rerender when the number - // format changes - {...state} - {...actionCreators} - key={numberFormat + hideFraction} - account={account} - accounts={accounts} - categories={categories.list} - payees={state.payees} - transactions={transactions} - prependTransactions={prependTransactions || []} - balance={balance} - isNewTransaction={isNewTransaction} - // refreshControl={ - // <RefreshControl - // refreshing={refreshing} - // onRefresh={onRefresh} - // /> - // } - onLoadMore={() => { - paged?.fetchNext(); - }} - onSearch={onSearch} - onSelectTransaction={onSelectTransaction} - /> - ) - } - </PreviewTransactions> - </SchedulesProvider> - )} - </SyncRefresh> + <SchedulesProvider + transform={getSchedulesTransform(accountId, searchText !== '')} + > + <PreviewTransactions accountId={props.accountId}> + {prependTransactions => + prependTransactions == null ? null : ( + <AccountDetails + // This key forces the whole table rerender when the number + // format changes + {...state} + {...actionCreators} + key={numberFormat + hideFraction} + account={account} + accounts={accounts} + categories={categories.list} + payees={state.payees} + transactions={transactions} + prependTransactions={prependTransactions || []} + balance={balance} + isNewTransaction={isNewTransaction} + onLoadMore={() => { + paged?.fetchNext(); + }} + onSearch={onSearch} + onSelectTransaction={onSelectTransaction} + /> + ) + } + </PreviewTransactions> + </SchedulesProvider> ); } diff --git a/packages/desktop-client/src/components/accounts/MobileAccountDetails.js b/packages/desktop-client/src/components/accounts/MobileAccountDetails.js index 611b87778..e3dd20985 100644 --- a/packages/desktop-client/src/components/accounts/MobileAccountDetails.js +++ b/packages/desktop-client/src/components/accounts/MobileAccountDetails.js @@ -1,6 +1,8 @@ import React, { useState, useMemo } from 'react'; import { Link } from 'react-router-dom'; +import PullToRefresh from 'react-simple-pull-to-refresh'; +import { useActions } from '../../hooks/useActions'; import Add from '../../icons/v1/Add'; import CheveronLeft from '../../icons/v1/CheveronLeft'; import SearchAlternate from '../../icons/v2/SearchAlternate'; @@ -75,12 +77,16 @@ export default function AccountDetails({ onSearch, onSelectTransaction, pushModal, - // refreshControl }) { let allTransactions = useMemo(() => { return prependTransactions.concat(transactions); }, [prependTransactions, transactions]); + const { syncAndDownload } = useActions(); + const onRefresh = async () => { + await syncAndDownload(account.id); + }; + return ( <View style={{ @@ -161,18 +167,20 @@ export default function AccountDetails({ onSearch={onSearch} /> </View> - <TransactionList - transactions={allTransactions} - categories={categories} - accounts={accounts} - payees={payees} - showCategory={!account.offbudget} - isNew={isNewTransaction} - // refreshControl={refreshControl} - onLoadMore={onLoadMore} - onSelect={onSelectTransaction} - pushModal={pushModal} - /> + + <PullToRefresh onRefresh={onRefresh}> + <TransactionList + transactions={allTransactions} + categories={categories} + accounts={accounts} + payees={payees} + showCategory={!account.offbudget} + isNew={isNewTransaction} + onLoadMore={onLoadMore} + onSelect={onSelectTransaction} + pushModal={pushModal} + /> + </PullToRefresh> </View> ); } diff --git a/packages/desktop-client/src/components/accounts/MobileAccounts.js b/packages/desktop-client/src/components/accounts/MobileAccounts.js index 07902c091..457c645a4 100644 --- a/packages/desktop-client/src/components/accounts/MobileAccounts.js +++ b/packages/desktop-client/src/components/accounts/MobileAccounts.js @@ -1,6 +1,7 @@ -import React, { Component, useEffect, useState } from 'react'; +import React, { useEffect, useState } from 'react'; import { useSelector } from 'react-redux'; import { useNavigate } from 'react-router-dom'; +import PullToRefresh from 'react-simple-pull-to-refresh'; import * as queries from 'loot-core/src/client/queries'; @@ -149,93 +150,58 @@ function EmptyMessage({ onAdd }) { ); } -class AccountList extends Component { - isNewTransaction = id => { - return this.props.newTransactions.includes(id); - }; +function AccountList({ + accounts, + updatedAccounts, + getBalanceQuery, + getOnBudgetBalance, + getOffBudgetBalance, + onAddAccount, + onSelectAccount, +}) { + const { syncAndDownload } = useActions(); - render() { - const { - accounts, - updatedAccounts, - // transactions, - // categories, - getBalanceQuery, - getOnBudgetBalance, - getOffBudgetBalance, - onAddAccount, - onSelectAccount, - // onSelectTransaction, - // refreshControl - } = this.props; - const budgetedAccounts = accounts.filter( - account => account.offbudget === 0, - ); - const offbudgetAccounts = accounts.filter( - account => account.offbudget === 1, - ); + const budgetedAccounts = accounts.filter(account => account.offbudget === 0); + const offbudgetAccounts = accounts.filter(account => account.offbudget === 1); - // If there are no accounts, show a helpful message - if (accounts.length === 0) { - return <EmptyMessage onAdd={onAddAccount} />; - } + // If there are no accounts, show a helpful message + if (accounts.length === 0) { + return <EmptyMessage onAdd={onAddAccount} />; + } - const accountContent = ( + return ( + <View style={{ flex: 1 }}> <Page title="Accounts"> - <AccountHeader name="For Budget" amount={getOnBudgetBalance()} /> - {budgetedAccounts.map((acct, idx) => ( - <AccountCard - account={acct} - key={acct.id} - updated={updatedAccounts.includes(acct.id)} - getBalanceQuery={getBalanceQuery} - onSelect={onSelectAccount} - /> - ))} + <PullToRefresh onRefresh={syncAndDownload}> + <AccountHeader name="For Budget" amount={getOnBudgetBalance()} /> + {budgetedAccounts.map(acct => ( + <AccountCard + account={acct} + key={acct.id} + updated={updatedAccounts.includes(acct.id)} + getBalanceQuery={getBalanceQuery} + onSelect={onSelectAccount} + /> + ))} - <AccountHeader - name="Off budget" - amount={getOffBudgetBalance()} - style={{ marginTop: 30 }} - /> - {offbudgetAccounts.map((acct, idx) => ( - <AccountCard - account={acct} - key={acct.id} - updated={updatedAccounts.includes(acct.id)} - getBalanceQuery={getBalanceQuery} - onSelect={onSelectAccount} + <AccountHeader + name="Off budget" + amount={getOffBudgetBalance()} + style={{ marginTop: 30 }} /> - ))} - - {/*<Label - title="RECENT TRANSACTIONS" - style={{ - textAlign: 'center', - marginTop: 50, - marginBottom: 20, - marginLeft: 10 - }} - />*/} + {offbudgetAccounts.map(acct => ( + <AccountCard + account={acct} + key={acct.id} + updated={updatedAccounts.includes(acct.id)} + getBalanceQuery={getBalanceQuery} + onSelect={onSelectAccount} + /> + ))} + </PullToRefresh> </Page> - ); - - return ( - <View style={{ flex: 1 }}> - {/* <TransactionList - transactions={transactions} - categories={categories} - isNew={this.isNewTransaction} - scrollProps={{ - ListHeaderComponent: accountContent - }} - // refreshControl={refreshControl} - onSelect={onSelectTransaction} - /> */} - {accountContent} - </View> - ); - } + </View> + ); } export default function Accounts() { @@ -259,10 +225,6 @@ export default function Accounts() { (async () => getAccounts())(); }, []); - // const sync = async () => { - // await props.syncAndDownload(); - // }; - const onSelectAccount = id => { navigate(`/accounts/${id}`); }; @@ -290,9 +252,6 @@ export default function Accounts() { onAddAccount={() => {}} // () => navigate('AddAccountModal') onSelectAccount={onSelectAccount} onSelectTransaction={onSelectTransaction} - // refreshControl={ - // <RefreshControl refreshing={refreshing} onRefresh={onRefresh} /> - // } /> </View> ); diff --git a/packages/desktop-client/src/components/transactions/MobileTransaction.js b/packages/desktop-client/src/components/transactions/MobileTransaction.js index 65aa9a3e2..12120b578 100644 --- a/packages/desktop-client/src/components/transactions/MobileTransaction.js +++ b/packages/desktop-client/src/components/transactions/MobileTransaction.js @@ -934,7 +934,6 @@ class Transaction extends PureComponent { backgroundColor: 'white', border: 'none', width: '100%', - '&:active': { opacity: 0.1 }, }} > <ListItem @@ -1057,12 +1056,7 @@ export class TransactionList extends Component { }); render() { - const { - transactions, - scrollProps = {}, - onLoadMore, - // refreshControl - } = this.props; + const { transactions, scrollProps = {}, onLoadMore } = this.props; const sections = this.makeData(transactions); diff --git a/upcoming-release-notes/1663.md b/upcoming-release-notes/1663.md new file mode 100644 index 000000000..02f02c0d2 --- /dev/null +++ b/upcoming-release-notes/1663.md @@ -0,0 +1,6 @@ +--- +category: Features +authors: [MatissJanis] +--- + +Mobile: pull down to trigger a bank-sync diff --git a/yarn.lock b/yarn.lock index 691518072..b0c828515 100644 --- a/yarn.lock +++ b/yarn.lock @@ -99,6 +99,7 @@ __metadata: react-redux: 7.2.1 react-router-dom: 6.11.2 react-scripts: ^5.0.1 + react-simple-pull-to-refresh: ^1.3.3 react-spring: ^9.7.1 react-virtualized-auto-sizer: ^1.0.2 redux: ^4.0.5 @@ -16797,6 +16798,16 @@ __metadata: languageName: node linkType: hard +"react-simple-pull-to-refresh@npm:^1.3.3": + version: 1.3.3 + resolution: "react-simple-pull-to-refresh@npm:1.3.3" + peerDependencies: + react: ^16.10.2 || ^17.0.0 || ^18.0.0 + react-dom: ^16.10.2 || ^17.0.0 || ^18.0.0 + checksum: 8b04ec1ccf9eae2d7bf9d8304c5a49ddb0a00c0289f703ba780e74af174df234642449ad26813daf146c3991999d8fdcbb75e8fca90e2d11d6239b91d033a666 + languageName: node + linkType: hard + "react-spring@npm:^9.7.1": version: 9.7.1 resolution: "react-spring@npm:9.7.1" -- GitLab