Skip to content

Commit

Permalink
UI: Fixed react leak on identities page (#3104)
Browse files Browse the repository at this point in the history
* UI: Fixed react leak on identities page

* pretty now? yas
  • Loading branch information
hozzjss committed Aug 13, 2021
1 parent 216e1c7 commit 1b723b1
Show file tree
Hide file tree
Showing 3 changed files with 82 additions and 58 deletions.
32 changes: 19 additions & 13 deletions packages/sourcecred/src/ui/components/AccountOverview.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// @flow

import React, {type Node as ReactNode} from "react";
import React, {type Node as ReactNode, useMemo} from "react";
import Table from "@material-ui/core/Table";
import TableBody from "@material-ui/core/TableBody";
import TableCell from "@material-ui/core/TableCell";
Expand All @@ -26,6 +26,13 @@ const useStyles = makeStyles(() => {
};
});

function comparator(a: Account, b: Account) {
if (a.balance === b.balance) {
return 0;
}
return G.gt(a.paid, b.paid) ? -1 : 1;
}

export const AccountOverview = ({
currency: {
name: currencyName,
Expand All @@ -37,20 +44,19 @@ export const AccountOverview = ({
const classes = useStyles();

const lastDistributionTimestamp = ledger.lastDistributionTimestamp();
const lastPayoutMessage =
lastDistributionTimestamp === null
? ""
: `Last distribution: ${formatTimestamp(lastDistributionTimestamp)}`;
const lastPayoutMessage = useMemo(
() =>
lastDistributionTimestamp === null
? ""
: `Last distribution: ${formatTimestamp(lastDistributionTimestamp)}`,
[lastDistributionTimestamp]
);

const accounts = ledger.accounts();
function comparator(a: Account, b: Account) {
if (a.balance === b.balance) {
return 0;
}
return G.gt(a.paid, b.paid) ? -1 : 1;
}
const accounts = useMemo(() => ledger.accounts(), []);

const sortedAccounts = accounts.slice().sort(comparator);
const sortedAccounts = useMemo(() => accounts.slice().sort(comparator), [
accounts,
]);
return (
<>
<TableContainer component={Paper} className={classes.container}>
Expand Down
49 changes: 25 additions & 24 deletions packages/sourcecred/src/ui/components/IdentityListItems.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// @flow
import React, {type Node as ReactNode} from "react";
import React, {type Node as ReactNode, useMemo} from "react";
import {Divider, ListItem, ListItemText, Checkbox} from "@material-ui/core";
import {type Identity, type IdentityId} from "../../core/identity";
import {type Account} from "../../core/ledger/ledger";
Expand All @@ -16,28 +16,29 @@ export const IdentityListItems = ({
onCheckbox,
}: IdentityListItemsProps): ReactNode => {
const lastIndex = accounts.length - 1;

if (lastIndex > -1) {
return accounts.map((account, index) => (
<React.Fragment key={account.identity.id}>
<ListItem button onClick={() => onClick(account.identity)}>
<ListItemText primary={account.identity.name} />
<Checkbox
onClick={(e) => e.stopPropagation()}
onChange={() => onCheckbox(account.identity.id)}
checked={account.active}
name="active"
color="primary"
/>
return useMemo(() => {
if (lastIndex > -1) {
return accounts.map((account, index) => (
<React.Fragment key={account.identity.id}>
<ListItem button onClick={() => onClick(account.identity)}>
<ListItemText primary={account.identity.name} />
<Checkbox
onClick={(e) => e.stopPropagation()}
onChange={() => onCheckbox(account.identity.id)}
checked={account.active}
name="active"
color="primary"
/>
</ListItem>
{index < lastIndex && <Divider />}
</React.Fragment>
));
} else {
return (
<ListItem button key="no_results">
<em>No results</em>
</ListItem>
{index < lastIndex && <Divider />}
</React.Fragment>
));
} else {
return (
<ListItem button key="no_results">
<em>No results</em>
</ListItem>
);
}
);
}
}, [accounts]);
};
59 changes: 38 additions & 21 deletions packages/sourcecred/src/ui/components/LedgerAdmin.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
// @flow

import React, {useState, useMemo, type Node as ReactNode} from "react";
import React, {
useState,
useMemo,
type Node as ReactNode,
useCallback,
} from "react";
import {makeStyles} from "@material-ui/core/styles";
import ButtonGroup from "@material-ui/core/ButtonGroup";
import {
Expand All @@ -12,7 +17,9 @@ import {
TextField,
ListSubheader,
Divider,
debounce,
} from "@material-ui/core";

import {useLedger} from "../utils/LedgerContext";
import {useTableState} from "../../webutil/tableState";
import {IdentityMerger} from "./IdentityMerger";
Expand Down Expand Up @@ -94,27 +101,30 @@ export const LedgerAdmin = (): ReactNode => {
updateLedger(ledger);
};

const toggleIdentityActivation = (id: IdentityId) => {
let nextLedger;
if (ledger.account(id).active) {
nextLedger = ledger.deactivate(id);
} else {
nextLedger = ledger.activate(id);
}
updateLedger(nextLedger);
};
const toggleIdentityActivation = useCallback(
(id: IdentityId) => {
let nextLedger;
if (ledger.account(id).active) {
nextLedger = ledger.deactivate(id);
} else {
nextLedger = ledger.activate(id);
}
updateLedger(nextLedger);
},
[ledger]
);

const resetIdentity = () => {
setIdentityName("");
setSelectedId(null);
setPromptString("Add Identity: ");
};

const setActiveIdentity = (identity: Identity) => {
const setActiveIdentity = useCallback((identity: Identity) => {
setIdentityName(identity.name);
setSelectedId(identity.id);
setPromptString("Update Identity: ");
};
}, []);

const filterIdentities = (event: SyntheticInputEvent<HTMLInputElement>) => {
// fuzzy match letters "in order, but not necessarily sequentially", per issue #2490
Expand All @@ -123,13 +133,23 @@ export const LedgerAdmin = (): ReactNode => {
.toLowerCase()
.split("")
.join("+.*");
const regex = new RegExp(filterString);

accountsTableState.createOrUpdateFilterFn("filterIdentities", (account) =>
regex.test(account.identity.name.toLowerCase())
);
searchAccounts(filterString);
};

const searchAccounts = useCallback(
debounce((filterString) => {
const regex = new RegExp(filterString);
accountsTableState.createOrUpdateFilterFn("filterIdentities", (account) =>
regex.test(account.identity.name.toLowerCase())
);
}, 400),
[]
);

const nameIsEmpty = useMemo(() => nextIdentityName.trim().length === 0, [
nextIdentityName,
]);

return (
<Container className={classes.root}>
<span className={classes.centerRow}>
Expand Down Expand Up @@ -163,10 +183,7 @@ export const LedgerAdmin = (): ReactNode => {
)}
</div>
<ButtonGroup color="primary" variant="contained">
<Button
onClick={createOrUpdateIdentity}
disabled={nextIdentityName.trim().length === 0}
>
<Button onClick={createOrUpdateIdentity} disabled={nameIsEmpty}>
{selectedId ? "update username" : "create identity"}
</Button>
<Button onClick={saveToDisk}>save ledger to disk</Button>
Expand Down

0 comments on commit 1b723b1

Please sign in to comment.