mirror of
https://github.com/priyanshujain/sanderling.git
synced 2026-10-02 19:17:10 +00:00
feat(folio): close the submit window on the account's own screens
submitCommitsOneTransactionPerAction now states its rule over two windows: the Home counts it already compared, and the account balance the ledger and the add-transaction screen redraw on nearly every frame of the transaction flow. Same rule, and the second window is usually one action wide.
This commit is contained in:
1 parent
2d789d7d17
commit
0e096c00b3
1 file changed
+57
-1
@@ -17,6 +17,7 @@ import {
|
|||||||
cardAccountName,
|
cardAccountName,
|
||||||
cardBalanceText,
|
cardBalanceText,
|
||||||
cardTxnCount,
|
cardTxnCount,
|
||||||
|
committedAmountExceedsOneSubmit,
|
||||||
committedTransactionsExceedSubmits,
|
committedTransactionsExceedSubmits,
|
||||||
countSubmitsInWindow,
|
countSubmitsInWindow,
|
||||||
createdAccountHasNonZeroBalance,
|
createdAccountHasNonZeroBalance,
|
||||||
@@ -25,6 +26,7 @@ import {
|
|||||||
oncePerFrame,
|
oncePerFrame,
|
||||||
parseDollarCents,
|
parseDollarCents,
|
||||||
parseTypedAmount,
|
parseTypedAmount,
|
||||||
|
readAccountBalance,
|
||||||
readHomeCards,
|
readHomeCards,
|
||||||
readHomeTotalBalance,
|
readHomeTotalBalance,
|
||||||
routeOfFrame,
|
routeOfFrame,
|
||||||
@@ -181,6 +183,44 @@ const submitsSinceCounts = extract("submitsSinceCounts", s => {
|
|||||||
return window.reported;
|
return window.reported;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// The account's own balance, off whichever of its two screens is up. The routes
|
||||||
|
// are exclusive, so at most one of these resolves and the reading is always one
|
||||||
|
// account's number. Its carrier is dropped on every other route, which is what
|
||||||
|
// keeps two readings from spanning two accounts: see readAccountBalance.
|
||||||
|
const accountBalanceText = (s: State) =>
|
||||||
|
on("ledger", "LedgerBalance")(s)?.text ?? on("add-transaction", "TxnCurrentBalance")(s)?.text;
|
||||||
|
|
||||||
|
let lastAccountBalance: number | null = null;
|
||||||
|
const accountBalance = extract<number | null>("accountBalance", s => {
|
||||||
|
const reading = readAccountBalance({
|
||||||
|
route: routeOf(s),
|
||||||
|
balanceText: accountBalanceText(s),
|
||||||
|
previousCarrier: lastAccountBalance,
|
||||||
|
});
|
||||||
|
lastAccountBalance = reading.carrier;
|
||||||
|
return reading.value;
|
||||||
|
});
|
||||||
|
|
||||||
|
// A third window, for the same reason the counting invariant has its own: it
|
||||||
|
// closes on this reading's freshness, which is a different event again. The
|
||||||
|
// transaction flow redraws this balance on nearly every frame, so this window
|
||||||
|
// is the narrow one, usually a single action wide.
|
||||||
|
let submitsSinceAccountBalance = 0;
|
||||||
|
const submitsSinceBalance = extract("submitsSinceAccountBalance", s => {
|
||||||
|
const fresh = readAccountBalance({
|
||||||
|
route: routeOf(s),
|
||||||
|
balanceText: accountBalanceText(s),
|
||||||
|
previousCarrier: null,
|
||||||
|
}).fresh;
|
||||||
|
const window = countSubmitsInWindow({
|
||||||
|
previousCount: submitsSinceAccountBalance,
|
||||||
|
lastAction: s.lastAction,
|
||||||
|
fresh,
|
||||||
|
});
|
||||||
|
submitsSinceAccountBalance = window.next;
|
||||||
|
return window.reported;
|
||||||
|
});
|
||||||
|
|
||||||
const lastAction = extract("lastAction", s => s.lastAction);
|
const lastAction = extract("lastAction", s => s.lastAction);
|
||||||
|
|
||||||
const loginEmailField = extract("loginEmailField", on("login", "LoginEmail"));
|
const loginEmailField = extract("loginEmailField", on("login", "LoginEmail"));
|
||||||
@@ -232,12 +272,28 @@ const submitMovesBalanceByTypedAmount = always(
|
|||||||
// stays sound however wide the window between two Home readings gets, because
|
// stays sound however wide the window between two Home readings gets, because
|
||||||
// both sides of the comparison accumulate over the same window. It is the
|
// both sides of the comparison accumulate over the same window. It is the
|
||||||
// double-submit stated directly: one tap, two rows.
|
// double-submit stated directly: one tap, two rows.
|
||||||
|
//
|
||||||
|
// One rule, two windows. The counting form can only compare two Home readings,
|
||||||
|
// and a walk that stays inside the transaction flow gives it a window hundreds
|
||||||
|
// of steps and dozens of submits wide, which is sound and says nothing. The
|
||||||
|
// second form says the same thing in money about the one account whose screen
|
||||||
|
// the walk is on, and that window is usually a single action, so it can still
|
||||||
|
// tell one commit from two: see committedAmountExceedsOneSubmit.
|
||||||
const submitCommitsOneTransactionPerAction = always(
|
const submitCommitsOneTransactionPerAction = always(
|
||||||
next(() =>
|
next(
|
||||||
|
() =>
|
||||||
!committedTransactionsExceedSubmits({
|
!committedTransactionsExceedSubmits({
|
||||||
countsBefore: homeTxnCounts.previous ?? null,
|
countsBefore: homeTxnCounts.previous ?? null,
|
||||||
countsAfter: homeTxnCounts.current,
|
countsAfter: homeTxnCounts.current,
|
||||||
submitsInWindow: submitsSinceCounts.current,
|
submitsInWindow: submitsSinceCounts.current,
|
||||||
|
}) &&
|
||||||
|
!committedAmountExceedsOneSubmit({
|
||||||
|
route: route.current,
|
||||||
|
lastAction: lastAction.current,
|
||||||
|
submitsInWindow: submitsSinceBalance.current,
|
||||||
|
typedAmount: parseTypedAmount(txnAmountField.previous?.text),
|
||||||
|
prevAccountBalance: accountBalance.previous ?? null,
|
||||||
|
currAccountBalance: accountBalance.current,
|
||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in new issue
Block a user