Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
80 commits
Select commit Hold shift + click to select a range
c4498a9
start
youngcw Apr 15, 2025
9f1d815
small fix
youngcw Apr 15, 2025
150280c
clean
youngcw Apr 15, 2025
40a3ea6
working for regular transactions
youngcw Apr 18, 2025
99491af
working for schedules
youngcw Apr 18, 2025
ad76770
cleanup
youngcw Apr 18, 2025
b949acb
typing
youngcw Apr 18, 2025
dec7d05
cleanup
youngcw Apr 18, 2025
02e067d
cleanup
youngcw Apr 18, 2025
13a99f9
vrt
youngcw Apr 19, 2025
4da8509
Merge branch 'master' into youngcw/mobile-running-balance
youngcw Apr 19, 2025
e95a125
bunny
youngcw Apr 19, 2025
31a671c
Merge branch 'master' into youngcw/mobile-running-balance
youngcw Apr 28, 2025
87e8946
Merge branch 'master' into youngcw/mobile-running-balance
youngcw May 5, 2025
e63cd5a
use pref
youngcw May 6, 2025
34ad284
use pref right, lint
youngcw May 6, 2025
7fa1013
more lint
youngcw May 6, 2025
872f389
vrt
youngcw May 6, 2025
01f7f78
Merge branch 'master' into youngcw/mobile-running-balance
youngcw May 12, 2025
b1f7b8b
pass hasInitialBalances to isLoading
youngcw May 12, 2025
f7a1c41
remove comment
youngcw May 12, 2025
4ff2385
Merge branch 'master' into youngcw/mobile-running-balance
youngcw May 13, 2025
c1f8c0b
Add option to calculate running balances in useTransactions hook
joel-jeremy May 14, 2025
4cc7072
Fix typecheck error
joel-jeremy May 14, 2025
d69ba46
Fix lint error
joel-jeremy May 14, 2025
288b81a
Merge remote-tracking branch 'origin/useTransactions-runningBalances'…
youngcw May 14, 2025
2feb3fd
use the updated hook
youngcw May 14, 2025
3099cbb
typecheck
youngcw May 14, 2025
13725f7
Merge branch 'master' into youngcw/mobile-running-balance
youngcw May 14, 2025
3a4ceba
simplify
youngcw May 14, 2025
e4fc3a0
don't show balances when searching
youngcw May 14, 2025
7b18655
Add runningBalances to usePreviewTransactions and an option to set th…
joel-jeremy May 15, 2025
2d56a9a
Add filter to usePreviewTransactions and set startingBalance to accou…
joel-jeremy May 15, 2025
3f86a01
Merge remote-tracking branch 'origin/usePreviewTransactions-runningBa…
youngcw May 15, 2025
1bdd678
use runningbalance from preview transactions hook
youngcw May 15, 2025
efd3592
Merge branch 'master' into youngcw/mobile-running-balance
youngcw May 15, 2025
fc2baa2
lint
youngcw May 15, 2025
411b534
lint;typecheck
youngcw May 15, 2025
bfdccdc
Merge branch 'master' into youngcw/mobile-running-balance
youngcw May 15, 2025
490e7c6
Merge branch 'master' into youngcw/mobile-running-balance
youngcw May 15, 2025
5ad3cd7
remove initial from preview balances
youngcw May 15, 2025
762f3aa
Merge remote-tracking branch 'origin/master' into youngcw/mobile-runn…
youngcw May 15, 2025
bd0b26f
remove unneeded type
youngcw May 15, 2025
208a031
Apply suggestions from code review
youngcw May 15, 2025
2364ef1
typecheck; align right; change color
youngcw May 15, 2025
55d2eaf
types
youngcw May 15, 2025
2ff18f9
add a menu item
youngcw May 24, 2025
899612d
cleanup
youngcw May 24, 2025
7b980c7
Merge branch 'master' into youngcw/mobile-running-balance
youngcw Jun 5, 2025
39ee67e
fix for loot-core migrated files
youngcw Jun 5, 2025
02131fd
Merge branch 'master' into youngcw/mobile-running-balance
youngcw Jun 5, 2025
4a0d803
lint;type
youngcw Jun 5, 2025
8502695
fix import
youngcw Jun 5, 2025
5993cab
Merge branch 'master' into youngcw/mobile-running-balance
youngcw Jun 17, 2025
90c1a69
only schedules need fixed
youngcw Jun 17, 2025
fa562ef
lint
youngcw Jun 17, 2025
a9c020a
it works
youngcw Jun 19, 2025
cd2f271
cleanup
youngcw Jun 19, 2025
765beef
make lint happy
youngcw Jun 19, 2025
b0a13d9
[autofix.ci] apply automated fixes
autofix-ci[bot] Jun 19, 2025
037f5e3
simplify a bit
youngcw Jun 19, 2025
fc4dbb8
Merge branch 'master' into youngcw/mobile-running-balance
youngcw Jun 19, 2025
0909792
fix import
youngcw Jun 19, 2025
61c1493
feedback
youngcw Jun 19, 2025
3dc25a7
fixed regular transaction balance calculation
youngcw Jun 21, 2025
282944e
fix numbers not showing
youngcw Jun 21, 2025
f4a22d5
fix schedule running balance
youngcw Jun 21, 2025
860ff75
note
youngcw Jun 21, 2025
327d04a
attempt to update properly
youngcw Jun 21, 2025
95ca333
type
youngcw Jun 21, 2025
de2e1ae
remove the useEffect that I don't think should be requred
youngcw Jun 21, 2025
60e0ea9
remove old note
youngcw Jun 21, 2025
2b42bb1
cleanup
youngcw Jun 21, 2025
78b624b
Merge branch 'master' into youngcw/mobile-running-balance
youngcw Jun 21, 2025
1bf7847
Merge branch 'master' into youngcw/mobile-running-balance
youngcw Jun 29, 2025
e25fe10
typeing
youngcw Jul 1, 2025
b058fc4
I FINALLY FOUND THE PROBLEM
youngcw Jul 1, 2025
663b98f
cleaner balance calculation
youngcw Jul 1, 2025
11782dd
fixes
youngcw Jul 1, 2025
3b130b0
fix zeros
youngcw Jul 1, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { View } from '@actual-app/components/view';
import { listen, send } from 'loot-core/platform/client/fetch';
import { type Query } from 'loot-core/shared/query';
import { isPreviewId } from 'loot-core/shared/transactions';
import { type IntegerAmount } from 'loot-core/shared/util';
import {
type AccountEntity,
type TransactionEntity,
Expand All @@ -31,8 +32,9 @@ import { SchedulesProvider } from '@desktop-client/hooks/useCachedSchedules';
import { useDateFormat } from '@desktop-client/hooks/useDateFormat';
import { useFailedAccounts } from '@desktop-client/hooks/useFailedAccounts';
import { useNavigate } from '@desktop-client/hooks/useNavigate';
import { useTransactions } from '@desktop-client/hooks/usePreviewTransactions';
import { accountSchedulesQuery } from '@desktop-client/hooks/useSchedules';
import { useTransactions } from '@desktop-client/hooks/useTransactions';
import { useSyncedPref } from '@desktop-client/hooks/useSyncedPref';
import { useTransactionsSearch } from '@desktop-client/hooks/useTransactionsSearch';
import {
collapseModals,
Expand Down Expand Up @@ -148,6 +150,19 @@ function AccountHeader({ account }: { readonly account: AccountEntity }) {
dispatch(reopenAccount({ id: account.id }));
}, [account.id, dispatch]);

const [showBalances, setBalances] = useSyncedPref(
`show-balances-${account.id}`,
);
const onToggleRunningBalance = useCallback(() => {
const newVal = showBalances === 'true' ? 'false' : 'true';
setBalances(newVal);
dispatch(
collapseModals({
rootModalName: 'account-menu',
}),
);
}, [showBalances, setBalances, dispatch]);

const onClick = useCallback(() => {
dispatch(
pushModal({
Expand All @@ -159,6 +174,7 @@ function AccountHeader({ account }: { readonly account: AccountEntity }) {
onEditNotes,
onCloseAccount,
onReopenAccount,
onToggleRunningBalance,
},
},
}),
Expand All @@ -170,6 +186,7 @@ function AccountHeader({ account }: { readonly account: AccountEntity }) {
onEditNotes,
onReopenAccount,
onSave,
onToggleRunningBalance,
]);

return (
Expand Down Expand Up @@ -241,39 +258,73 @@ function TransactionListWithPreviews({
readonly accountName: AccountEntity['name'] | string;
}) {
const { t } = useTranslation();
const dateFormat = useDateFormat() || 'MM/dd/yyyy';
const dispatch = useDispatch();
const navigate = useNavigate();

const onRefresh = useCallback(() => {
if (accountId) {
dispatch(syncAndDownload({ accountId }));
}
}, [accountId, dispatch]);

const baseTransactionsQuery = useCallback(
() =>
queries.transactions(accountId).options({ splits: 'all' }).select('*'),
[accountId],
);

const runningBalancesQuery = useCallback(
() =>
queries
.transactions(accountId)
.options({ splits: 'none' })
.select({ balance: { $sumOver: '$amount' } }),
[accountId],
);

const [showBalances] = useSyncedPref(`show-balances-${accountId}`);
const [transactionsQuery, setTransactionsQuery] = useState<Query>(
baseTransactionsQuery(),
);
const [balancesQuery] = useState<Query>(runningBalancesQuery);
const {
transactions,
runningBalances,
isLoading: isTransactionsLoading,
reload: reloadTransactions,
isLoadingMore,
loadMore: loadMoreTransactions,
} = useTransactions({
query: transactionsQuery,
runningBalanceQuery: balancesQuery,
options: {
calculateRunningBalances: true,
},
});

const { previewTransactions, isLoading: isPreviewTransactionsLoading } =
useAccountPreviewTransactions({
accountId: account?.id,
});
const { isSearching, search: onSearch } = useTransactionsSearch({
updateQuery: setTransactionsQuery,
resetQuery: () => setTransactionsQuery(baseTransactionsQuery()),
dateFormat,
});

const dateFormat = useDateFormat() || 'MM/dd/yyyy';
const dispatch = useDispatch();
const navigate = useNavigate();
const {
previewTransactions,
runningBalances: previewRunningBalances,
isLoading: isPreviewTransactionsLoading,
} = useAccountPreviewTransactions({
accountId: account?.id,
});

const onRefresh = useCallback(() => {
if (accountId) {
dispatch(syncAndDownload({ accountId }));
}
}, [accountId, dispatch]);
const allBalances = useMemo(
() =>
new Map<TransactionEntity['id'], IntegerAmount>([
...previewRunningBalances,
...runningBalances,
]),
[runningBalances, previewRunningBalances],
);

useEffect(() => {
if (accountId) {
Expand All @@ -296,12 +347,6 @@ function TransactionListWithPreviews({
});
}, [dispatch, reloadTransactions]);

const { isSearching, search: onSearch } = useTransactionsSearch({
updateQuery: setTransactionsQuery,
resetQuery: () => setTransactionsQuery(baseTransactionsQuery()),
dateFormat,
});

const onOpenTransaction = useCallback(
(transaction: TransactionEntity) => {
if (!isPreviewId(transaction.id)) {
Expand Down Expand Up @@ -370,6 +415,8 @@ function TransactionListWithPreviews({
balance={balanceQueries.balance}
balanceCleared={balanceQueries.cleared}
balanceUncleared={balanceQueries.uncleared}
runningBalances={allBalances}
showBalances={isSearching ? false : showBalances === 'true'}
isLoadingMore={isLoadingMore}
onLoadMore={loadMoreTransactions}
searchPlaceholder={t('Search {{accountName}}', { accountName })}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,7 @@ function TransactionListWithPreviews({
balance={balance}
balanceCleared={balanceCleared}
balanceUncleared={balanceUncleared}
runningBalances={undefined}
searchPlaceholder={`Search ${category.name}`}
onSearch={onSearch}
isLoadingMore={isLoadingMore}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,11 @@ import { View } from '@actual-app/components/view';
import * as monthUtils from 'loot-core/shared/months';
import { isPreviewId } from 'loot-core/shared/transactions';
import { validForTransfer } from 'loot-core/shared/transfer';
import { groupById, integerToCurrency } from 'loot-core/shared/util';
import {
groupById,
type IntegerAmount,
integerToCurrency,
} from 'loot-core/shared/util';
import {
type AccountEntity,
type TransactionEntity,
Expand Down Expand Up @@ -84,6 +88,8 @@ function Loading({ style, 'aria-label': ariaLabel }: LoadingProps) {
type TransactionListProps = {
isLoading: boolean;
transactions: readonly TransactionEntity[];
showBalances?: boolean;
runningBalances?: Map<TransactionEntity['id'], IntegerAmount>;
onOpenTransaction?: (transaction: TransactionEntity) => void;
isLoadingMore: boolean;
onLoadMore: () => void;
Expand All @@ -93,6 +99,8 @@ type TransactionListProps = {
export function TransactionList({
isLoading,
transactions,
showBalances,
runningBalances,
onOpenTransaction,
isLoadingMore,
onLoadMore,
Expand Down Expand Up @@ -198,10 +206,13 @@ export function TransactionList({
t => !isPreviewId(t.id) || !t.is_child,
)}
addIdAndValue
dependencies={[transactions, showBalances, runningBalances]}
>
{transaction => (
<TransactionListItem
key={transaction.id}
showBalance={showBalances}
balance={runningBalances?.get(transaction.id)}
value={transaction}
onPress={trans => onTransactionPress(trans)}
onLongPress={trans => onTransactionPress(trans, true)}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,18 @@ import {
} from '@react-aria/interactions';

import { isPreviewId } from 'loot-core/shared/transactions';
import { integerToCurrency } from 'loot-core/shared/util';
import { type IntegerAmount, integerToCurrency } from 'loot-core/shared/util';
import {
type AccountEntity,
type TransactionEntity,
} from 'loot-core/types/models';

import { lookupName, Status } from './TransactionEdit';

import { makeAmountFullStyle } from '@desktop-client/components/budget/util';
import {
makeAmountFullStyle,
makeBalanceAmountStyle,
} from '@desktop-client/components/budget/util';
import { useAccount } from '@desktop-client/hooks/useAccount';
import { useCachedSchedules } from '@desktop-client/hooks/useCachedSchedules';
import { useCategories } from '@desktop-client/hooks/useCategories';
Expand Down Expand Up @@ -73,11 +76,15 @@ const getScheduleIconStyle = ({ isPreview }: { isPreview: boolean }) => ({
type TransactionListItemProps = ComponentPropsWithoutRef<
typeof ListBoxItem<TransactionEntity>
> & {
showBalance?: boolean;
balance?: IntegerAmount;
onPress: (transaction: TransactionEntity) => void;
onLongPress: (transaction: TransactionEntity) => void;
};

export function TransactionListItem({
showBalance,
balance,
onPress,
onLongPress,
...props
Expand Down Expand Up @@ -282,7 +289,7 @@ export function TransactionListItem({
</TextOneLine>
)}
</View>
<View style={{ justifyContent: 'center' }}>
<View style={{ textAlign: 'right' }}>
<Text
style={{
...textStyle,
Expand All @@ -291,6 +298,17 @@ export function TransactionListItem({
>
{integerToCurrency(amount)}
</Text>
{showBalance && (
<Text
style={{
fontSize: 11,
fontWeight: '400',
...makeBalanceAmountStyle(balance || 0),
}}
>
{integerToCurrency(balance || 0)}
</Text>
)}
</View>
</View>
</Button>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { styles } from '@actual-app/components/styles';
import { theme } from '@actual-app/components/theme';
import { View } from '@actual-app/components/view';

import { type IntegerAmount } from 'loot-core/shared/util';
import {
type AccountEntity,
type TransactionEntity,
Expand Down Expand Up @@ -86,6 +87,8 @@ type TransactionListWithBalancesProps = {
balanceUncleared?:
| Binding<'category', 'balanceUncleared'>
| Binding<'account', 'balanceUncleared'>;
showBalances?: boolean;
runningBalances?: Map<TransactionEntity['id'], IntegerAmount>;
searchPlaceholder: string;
onSearch: (searchText: string) => void;
isLoadingMore: boolean;
Expand All @@ -101,6 +104,8 @@ export function TransactionListWithBalances({
balance,
balanceCleared,
balanceUncleared,
showBalances,
runningBalances,
searchPlaceholder = 'Search...',
onSearch,
isLoadingMore,
Expand Down Expand Up @@ -148,6 +153,8 @@ export function TransactionListWithBalances({
<TransactionList
isLoading={isLoading}
transactions={transactions}
showBalances={showBalances}
runningBalances={runningBalances}
isLoadingMore={isLoadingMore}
onLoadMore={onLoadMore}
onOpenTransaction={onOpenTransaction}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import { validateAccountName } from '@desktop-client/components/util/accountVali
import { useAccount } from '@desktop-client/hooks/useAccount';
import { useAccounts } from '@desktop-client/hooks/useAccounts';
import { useNotes } from '@desktop-client/hooks/useNotes';
import { useSyncedPref } from '@desktop-client/hooks/useSyncedPref';
import { type Modal as ModalType } from '@desktop-client/modals/modalsSlice';

type AccountMenuModalProps = Extract<
Expand All @@ -47,6 +48,7 @@ export function AccountMenuModal({
onReopenAccount,
onEditNotes,
onClose,
onToggleRunningBalance,
}: AccountMenuModalProps) {
const { t } = useTranslation();
const account = useAccount(accountId);
Expand Down Expand Up @@ -124,6 +126,7 @@ export function AccountMenuModal({
account={account}
onClose={onCloseAccount}
onReopen={onReopenAccount}
onToggleRunningBalance={onToggleRunningBalance}
/>
}
title={
Expand Down Expand Up @@ -158,7 +161,7 @@ export function AccountMenuModal({
notes={
originalNotes && originalNotes.length > 0
? originalNotes
: 'No notes'
: t('No notes')
}
editable={false}
focused={false}
Expand Down Expand Up @@ -201,12 +204,14 @@ type AdditionalAccountMenuProps = {
account: AccountEntity;
onClose?: (accountId: string) => void;
onReopen?: (accountId: string) => void;
onToggleRunningBalance?: () => void;
};

function AdditionalAccountMenu({
account,
onClose,
onReopen,
onToggleRunningBalance,
}: AdditionalAccountMenuProps) {
const { t } = useTranslation();
const triggerRef = useRef(null);
Expand All @@ -220,6 +225,7 @@ function AdditionalAccountMenu({
...itemStyle,
...(item.name === 'close' && { color: theme.errorTextMenu }),
});
const [showBalances] = useSyncedPref(`show-balances-${account.id}`);

return (
<View>
Expand All @@ -245,6 +251,13 @@ function AdditionalAccountMenu({
<Menu
getItemStyle={getItemStyle}
items={[
{
name: 'balance',
text:
showBalances === 'true'
? t('Hide running balance')
: t('Show running balance'),
},
account.closed
? {
name: 'reopen',
Expand All @@ -268,6 +281,9 @@ function AdditionalAccountMenu({
case 'reopen':
onReopen?.(account.id);
break;
case 'balance':
onToggleRunningBalance?.();
break;
default:
throw new Error(`Unrecognized menu option: ${name}`);
}
Expand Down
Loading
Loading