diff --git a/src/components/auth/AuthMasterPasswordPopover.tsx b/src/components/auth/AuthMasterPasswordPopover.tsx index 7a921dc..118d124 100644 --- a/src/components/auth/AuthMasterPasswordPopover.tsx +++ b/src/components/auth/AuthMasterPasswordPopover.tsx @@ -5,7 +5,7 @@ import { Popover, Button, Input, Form } from "antd"; import { TooltipPlacement } from "antd/lib/tooltip"; -import { useDispatch, useSelector, shallowEqual } from "react-redux"; +import { useSelector, shallowEqual } from "react-redux"; import { RootState } from "../../store"; import { useTranslation } from "react-i18next"; @@ -26,7 +26,6 @@ export const AuthMasterPasswordPopover: FunctionComponent = ({ encrypt, onSubmit, placement, children }) => { const { salt, tester } = useSelector((s: RootState) => s.walletManager, shallowEqual); - const dispatch = useDispatch(); const { t } = useTranslation(); const [form] = Form.useForm(); @@ -35,7 +34,7 @@ async function onFinish(values: FormValues) { try { - await authMasterPassword(dispatch, salt, tester, values.masterPassword); + await authMasterPassword(salt, tester, values.masterPassword); onSubmit(); } catch (e) { const message = e.message // Translate the error if we can diff --git a/src/components/auth/ForcedAuth.tsx b/src/components/auth/ForcedAuth.tsx index 4d0018b..936e0bf 100644 --- a/src/components/auth/ForcedAuth.tsx +++ b/src/components/auth/ForcedAuth.tsx @@ -4,20 +4,19 @@ import { message } from "antd"; import { useTranslation, TFunction } from "react-i18next"; -import { useDispatch, useSelector, shallowEqual } from "react-redux"; +import { useSelector, shallowEqual } from "react-redux"; import { RootState } from "../../store"; -import { AppDispatch } from "../../App"; import { authMasterPassword } from "../../krist/wallets/WalletManager"; import { useMountEffect } from "../../utils"; -async function forceAuth(t: TFunction, dispatch: AppDispatch, salt: string, tester: string): Promise { +async function forceAuth(t: TFunction, salt: string, tester: string): Promise { try { const password = localStorage.getItem("forcedAuth"); if (!password) return; - await authMasterPassword(dispatch, salt, tester, password); + await authMasterPassword(salt, tester, password); message.warning(t("masterPassword.forcedAuthWarning")); } catch (e) { console.error(e); @@ -29,13 +28,12 @@ export function ForcedAuth(): JSX.Element | null { const { isAuthed, hasMasterPassword, salt, tester } = useSelector((s: RootState) => s.walletManager, shallowEqual); - const dispatch = useDispatch(); const { t } = useTranslation(); useMountEffect(() => { if (isAuthed || !hasMasterPassword || !salt || !tester) return; - forceAuth(t, dispatch, salt, tester); + forceAuth(t, salt, tester); }); return null; diff --git a/src/components/auth/SetMasterPasswordModal.tsx b/src/components/auth/SetMasterPasswordModal.tsx index acc96ef..58052c2 100644 --- a/src/components/auth/SetMasterPasswordModal.tsx +++ b/src/components/auth/SetMasterPasswordModal.tsx @@ -4,7 +4,6 @@ import React, { useRef } from "react"; import { Modal, Form, Input, Button } from "antd"; import { useTranslation, Trans } from "react-i18next"; -import { useDispatch } from "react-redux"; import { FakeUsernameInput } from "./FakeUsernameInput"; import { getMasterPasswordInput } from "./MasterPasswordInput"; @@ -18,8 +17,6 @@ } export function SetMasterPasswordModal({ visible, onCancel, onSubmit }: Props): JSX.Element { - const dispatch = useDispatch(); - const { t } = useTranslation(); const [form] = Form.useForm(); const inputRef = useRef(null); @@ -28,7 +25,7 @@ const values = await form.validateFields(); form.resetFields(); - await setMasterPassword(dispatch, values.masterPassword); + await setMasterPassword(values.masterPassword); onSubmit(); } diff --git a/src/components/wallets/SyncWallets.tsx b/src/components/wallets/SyncWallets.tsx index 422edcc..e5574a3 100644 --- a/src/components/wallets/SyncWallets.tsx +++ b/src/components/wallets/SyncWallets.tsx @@ -1,26 +1,23 @@ // Copyright (c) 2020-2021 Drew Lemmy // This file is part of KristWeb 2 under GPL-3.0. // Full details: https://github.com/tmpim/KristWeb2/blob/master/LICENSE.txt -import { useEffect } from "react"; - -import { useDispatch, useSelector } from "react-redux"; +import { useSelector } from "react-redux"; import { RootState } from "../../store"; import { syncWallets } from "../../krist/wallets/Wallet"; +import { useMountEffect } from "../../utils"; /** Sync the wallets with the Krist node on startup. */ export function SyncWallets(): JSX.Element | null { const { wallets } = useSelector((s: RootState) => s.wallets); - const syncNode = useSelector((s: RootState) => s.node.syncNode); - const dispatch = useDispatch(); // 'wallets' is not a dependency here, we don't want to re-fetch on every - // wallet update, just the initial startup - useEffect(() => { + // wallet update, just the initial startup. We'll leave fetching wallets when + // the syncNode changes to the WebsocketService. + useMountEffect(() => { // TODO: show errors to the user? - syncWallets(dispatch, syncNode, wallets).catch(console.error); - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [dispatch, syncNode]); + syncWallets(wallets).catch(console.error); + }); return null; } diff --git a/src/components/ws/SyncMOTD.tsx b/src/components/ws/SyncMOTD.tsx index 87eb9e6..9e39446 100644 --- a/src/components/ws/SyncMOTD.tsx +++ b/src/components/ws/SyncMOTD.tsx @@ -3,11 +3,11 @@ // Full details: https://github.com/tmpim/KristWeb2/blob/master/LICENSE.txt import { useEffect } from "react"; -import { useDispatch, useSelector, shallowEqual } from "react-redux"; +import { useSelector, shallowEqual } from "react-redux"; import { RootState } from "../../store"; import * as nodeActions from "../../store/actions/NodeActions"; -import { AppDispatch } from "../../App"; +import { store } from "../../App"; import * as api from "../../krist/api/api"; import { KristMOTD } from "../../krist/api/types"; @@ -17,13 +17,13 @@ import Debug from "debug"; const debug = Debug("kristweb:sync-motd"); -export async function updateMOTD(dispatch: AppDispatch, syncNode: string): Promise { +export async function updateMOTD(): Promise { debug("updating motd"); - const data = await api.get(syncNode, "motd"); + const data = await api.get("motd"); debug("motd: %s", data.motd); - dispatch(nodeActions.setCurrency(data.currency)); - dispatch(nodeActions.setConstants(data.constants)); + store.dispatch(nodeActions.setCurrency(data.currency)); + store.dispatch(nodeActions.setConstants(data.constants)); } /** Sync the MOTD with the Krist node on startup. */ @@ -36,20 +36,18 @@ const masterPassword = useSelector((s: RootState) => s.walletManager.masterPassword); const wallets = useSelector((s: RootState) => s.wallets.wallets, shallowEqual); - const dispatch = useDispatch(); - // Update the MOTD when the sync node changes, and on startup useEffect(() => { if (connectionState !== "connected") return; - updateMOTD(dispatch, syncNode).catch(console.error); - }, [dispatch, syncNode, connectionState]); + updateMOTD().catch(console.error); + }, [syncNode, connectionState]); // When the currency's address prefix changes, or our master password appears, // recalculate the addresses if necessary useEffect(() => { if (!addressPrefix || !masterPassword) return; - recalculateWallets(dispatch, masterPassword, wallets, addressPrefix).catch(console.error); - }, [dispatch, addressPrefix, masterPassword, wallets]); + recalculateWallets(masterPassword, wallets, addressPrefix).catch(console.error); + }, [addressPrefix, masterPassword, wallets]); return null; } diff --git a/src/components/ws/SyncWork.tsx b/src/components/ws/SyncWork.tsx index a01b935..5fd4b68 100644 --- a/src/components/ws/SyncWork.tsx +++ b/src/components/ws/SyncWork.tsx @@ -3,11 +3,11 @@ // Full details: https://github.com/tmpim/KristWeb2/blob/master/LICENSE.txt import { useEffect } from "react"; -import { useDispatch, useSelector } from "react-redux"; +import { useSelector } from "react-redux"; import { RootState } from "../../store"; import * as nodeActions from "../../store/actions/NodeActions"; -import { AppDispatch } from "../../App"; +import { store } from "../../App"; import * as api from "../../krist/api/api"; import { KristWorkDetailed } from "../../krist/api/types"; @@ -15,23 +15,22 @@ import Debug from "debug"; const debug = Debug("kristweb:sync-work"); -export async function updateDetailedWork(dispatch: AppDispatch, syncNode: string): Promise { +export async function updateDetailedWork(): Promise { debug("updating detailed work"); - const data = await api.get(syncNode, "work/detailed"); + const data = await api.get("work/detailed"); debug("work: %d", data.work); - dispatch(nodeActions.setDetailedWork(data)); + store.dispatch(nodeActions.setDetailedWork(data)); } /** Sync the work with the Krist node on startup. */ export function SyncWork(): JSX.Element | null { - const { lastBlockID, syncNode } = useSelector((s: RootState) => s.node); - const dispatch = useDispatch(); + const { lastBlockID } = useSelector((s: RootState) => s.node); useEffect(() => { // TODO: show errors to the user? - updateDetailedWork(dispatch, syncNode).catch(console.error); - }, [dispatch, lastBlockID, syncNode]); + updateDetailedWork().catch(console.error); + }, [lastBlockID]); return null; } diff --git a/src/components/ws/WebsocketService.tsx b/src/components/ws/WebsocketService.tsx index aa98e14..4862149 100644 --- a/src/components/ws/WebsocketService.tsx +++ b/src/components/ws/WebsocketService.tsx @@ -3,8 +3,8 @@ // Full details: https://github.com/tmpim/KristWeb2/blob/master/LICENSE.txt import { useState, useEffect } from "react"; -import { useSelector, shallowEqual, useDispatch } from "react-redux"; -import { AppDispatch } from "../../App"; +import { useSelector, shallowEqual } from "react-redux"; +import { store } from "../../App"; import { RootState } from "../../store"; import { WalletMap } from "../../store/reducers/WalletsReducer"; import * as wsActions from "../../store/actions/WebsocketActions"; @@ -37,7 +37,7 @@ // TODO: automatically clean this up? private refreshThrottles: Record void> = {}; - constructor(private dispatch: AppDispatch, public syncNode: string) { + constructor(public syncNode: string) { debug("WS component init"); this.attemptConnect(); } @@ -51,7 +51,7 @@ this.setConnectionState("disconnected"); // Get a websocket token - const { url } = await api.post<{ url: string }>(this.syncNode, "ws/start"); + const { url } = await api.post<{ url: string }>("ws/start"); this.setConnectionState("connecting"); @@ -109,7 +109,7 @@ } private setConnectionState(state: WSConnectionState) { - this.dispatch(wsActions.setConnectionState(state)); + store.dispatch(wsActions.setConnectionState(state)); } handleMessage(data: WSIncomingMessage) { @@ -138,7 +138,7 @@ if (!wallet) return; debug("syncing %s to %s (balance: %d)", address.address, wallet.id, address.balance); - syncWalletUpdate(this.dispatch, wallet, address); + syncWalletUpdate(wallet, address); } else if (data.type === "event" && data.event && this.wallets) { // Handle events switch (data.event) { @@ -155,8 +155,8 @@ // Update the name counts using the address lookup case "name_purchase": case "name_transfer": - if (fromWallet) syncWallet(this.dispatch, this.syncNode, fromWallet); - if (toWallet) syncWallet(this.dispatch, this.syncNode, toWallet); + if (fromWallet) syncWallet(fromWallet); + if (toWallet) syncWallet(toWallet); break; // Any other transaction; refresh the balances via the websocket @@ -174,7 +174,7 @@ const block = data.block as KristBlock; debug("block id now %d", block.height); - this.dispatch(nodeActions.setLastBlockID(block.height)); + store.dispatch(nodeActions.setLastBlockID(block.height)); break; } @@ -228,7 +228,6 @@ export function WebsocketService(): JSX.Element | null { const { wallets } = useSelector((s: RootState) => s.wallets, shallowEqual); const syncNode = useSelector((s: RootState) => s.node.syncNode); - const dispatch = useDispatch(); const [connection, setConnection] = useState(); @@ -243,13 +242,13 @@ if (connection) connection.forceClose(); // Connect to the Krist websocket server - setConnection(new WebsocketConnection(dispatch, syncNode)); + setConnection(new WebsocketConnection(syncNode)); // On unmount, force close the existing connection return () => { if (connection) connection.forceClose(); }; - }, [dispatch, syncNode, connection]); + }, [syncNode, connection]); // If the wallets change, let the websocket service know so that it can keep // track of events related to any new wallets diff --git a/src/krist/api/api.ts b/src/krist/api/api.ts index 0574344..9a43a9f 100644 --- a/src/krist/api/api.ts +++ b/src/krist/api/api.ts @@ -1,6 +1,8 @@ import { notification } from "antd"; import i18n from "../../utils/i18n"; +import { store } from "../../App"; + import { APIResponse } from "./types"; import { throttle } from "lodash-es"; @@ -18,7 +20,9 @@ notification.error({ message: i18n.t("rateLimitTitle"), description: i18n.t("rateLimitDescription") }); const notifyRateLimit = throttle(_notifyRateLimit, 5000); -export async function request(syncNode: string, method: string, endpoint: string, options?: RequestInit): Promise> { +export async function request(method: string, endpoint: string, options?: RequestInit): Promise> { + const syncNode = store.getState().node.syncNode; + // Let the fetch bubble its error upwards const res = await fetch(syncNode + "/" + endpoint, { method, @@ -37,7 +41,7 @@ return data; } -export const get = (syncNode: string, endpoint: string, options?: RequestInit): Promise> => - request(syncNode, "GET", endpoint, options); -export const post = (syncNode: string, endpoint: string, options?: RequestInit): Promise> => - request(syncNode, "POST", endpoint, options); +export const get = (endpoint: string, options?: RequestInit): Promise> => + request("GET", endpoint, options); +export const post = (endpoint: string, options?: RequestInit): Promise> => + request("POST", endpoint, options); diff --git a/src/krist/api/lookup.ts b/src/krist/api/lookup.ts index aaea9b1..f94d138 100644 --- a/src/krist/api/lookup.ts +++ b/src/krist/api/lookup.ts @@ -13,12 +13,11 @@ export interface KristAddressWithNames extends KristAddress { names?: number } export type AddressLookupResults = Record; -export async function lookupAddresses(syncNode: string, addresses: string[], fetchNames?: boolean): Promise { +export async function lookupAddresses(addresses: string[], fetchNames?: boolean): Promise { if (!addresses || addresses.length === 0) return {}; try { const data = await api.get( - syncNode, "lookup/addresses/" + encodeURIComponent(addresses.join(",")) + (fetchNames ? "?fetchNames" : "") @@ -47,7 +46,7 @@ transactions: KristTransaction[]; } -export async function lookupTransactions(syncNode: string, addresses: string[], opts: LookupTransactionsOptions): Promise { +export async function lookupTransactions(addresses: string[], opts: LookupTransactionsOptions): Promise { if (!addresses || addresses.length === 0) return { count: 0, total: 0, transactions: [] }; const qs = new URLSearchParams(); @@ -58,7 +57,6 @@ if (opts.order) qs.append("order", opts.order); return await api.get( - syncNode, "lookup/transactions/" + encodeURIComponent(addresses.join(",")) + "?" + qs diff --git a/src/krist/api/search.ts b/src/krist/api/search.ts index bffadc8..6ce8399 100644 --- a/src/krist/api/search.ts +++ b/src/krist/api/search.ts @@ -35,12 +35,12 @@ }; } -export async function search(syncNode: string, query?: string): Promise { +export async function search(query?: string): Promise { if (!query) return; - return api.get(syncNode, "search?q=" + encodeURIComponent(query)); + return api.get("search?q=" + encodeURIComponent(query)); } -export async function searchExtended(syncNode: string, query?: string): Promise { +export async function searchExtended(query?: string): Promise { if (!query || query.length < 3) return; - return api.get(syncNode, "search/extended?q=" + encodeURIComponent(query)); + return api.get("search/extended?q=" + encodeURIComponent(query)); } diff --git a/src/krist/wallets/Wallet.ts b/src/krist/wallets/Wallet.ts index 1750418..99519ff 100644 --- a/src/krist/wallets/Wallet.ts +++ b/src/krist/wallets/Wallet.ts @@ -10,7 +10,7 @@ import { KristAddressWithNames, lookupAddresses } from "../api/lookup"; -import { AppDispatch } from "../../App"; +import { store } from "../../App"; import * as actions from "../../store/actions/WalletsActions"; import { WalletMap } from "../../store/reducers/WalletsReducer"; @@ -138,20 +138,20 @@ /** Sync the data for a single wallet from the sync node, save it to local * storage, and dispatch the change to the Redux store. */ -export async function syncWallet(dispatch: AppDispatch, syncNode: string, wallet: Wallet): Promise { +export async function syncWallet(wallet: Wallet): Promise { // Fetch the data from the sync node (e.g. balance) const { address } = wallet; - const lookupResults = await lookupAddresses(syncNode, [address], true); + const lookupResults = await lookupAddresses([address], true); const kristAddress = lookupResults[address]; if (!kristAddress) return; // Skip unsyncable wallet - syncWalletUpdate(dispatch, wallet, kristAddress); + syncWalletUpdate(wallet, kristAddress); } /** Given an already synced wallet, save it to local storage, and dispatch the * change to the Redux store. */ -export function syncWalletUpdate(dispatch: AppDispatch, wallet: Wallet, address: KristAddressWithNames): void { +export function syncWalletUpdate(wallet: Wallet, address: KristAddressWithNames): void { const syncTime = new Date(); const updatedWallet = syncWalletProperties(wallet, address, syncTime); @@ -159,17 +159,17 @@ saveWallet(updatedWallet); // Dispatch the change to the Redux store - dispatch(actions.syncWallet(wallet.id, updatedWallet)); + store.dispatch(actions.syncWallet(wallet.id, updatedWallet)); } /** Sync the data for all the wallets from the sync node, save it to local * storage, and dispatch the changes to the Redux store. */ -export async function syncWallets(dispatch: AppDispatch, syncNode: string, wallets: WalletMap): Promise { +export async function syncWallets(wallets: WalletMap): Promise { const syncTime = new Date(); // Fetch all the data from the sync node (e.g. balances) const addresses = Object.values(wallets).map(w => w.address); - const lookupResults = await lookupAddresses(syncNode, addresses, true); + const lookupResults = await lookupAddresses(addresses, true); // Create a WalletMap with the updated wallet properties const updatedWallets = Object.entries(wallets).map(([_, wallet]) => { @@ -182,16 +182,13 @@ Object.values(updatedWallets).forEach(w => saveWallet(w as Wallet)); // Dispatch the changes to the Redux store - dispatch(actions.syncWallets(updatedWallets)); + store.dispatch(actions.syncWallets(updatedWallets)); } /** * Adds a new wallet, encrypting its privatekey and password, saving it to * local storage, and dispatching the changes to the Redux store. * - * @param dispatch - The AppDispatch instance used to dispatch the new wallet to - * the Redux store. - * @param syncNode - The Krist sync node to fetch the wallet data from. * @param addressPrefix - The prefixes of addresses on this node. * @param masterPassword - The master password used to encrypt the wallet * password and privatekey. @@ -200,8 +197,6 @@ * @param save - Whether or not to save this wallet to local storage. */ export async function addWallet( - dispatch: AppDispatch, - syncNode: string, addressPrefix: string, masterPassword: string, wallet: WalletNew, @@ -236,18 +231,15 @@ if (save) saveWallet(newWallet); // Dispatch the changes to the redux store - dispatch(actions.addWallet(newWallet)); + store.dispatch(actions.addWallet(newWallet)); - syncWallet(dispatch, syncNode, newWallet); + syncWallet(newWallet); } /** * Edits a new wallet, encrypting its privatekey and password, saving it to * local storage, and dispatching the changes to the Redux store. * - * @param dispatch - The AppDispatch instance used to dispatch the new wallet to - * the Redux store. - * @param syncNode - The Krist sync node to fetch the wallet data from. * @param addressPrefix - The prefixes of addresses on this node. * @param masterPassword - The master password used to encrypt the wallet * password and privatekey. @@ -256,8 +248,6 @@ * @param password - The password of the updated wallet. */ export async function editWallet( - dispatch: AppDispatch, - syncNode: string, addressPrefix: string, masterPassword: string, wallet: Wallet, @@ -289,18 +279,18 @@ saveWallet(finalWallet); // Dispatch the changes to the redux store - dispatch(actions.updateWallet(wallet.id, finalWallet)); + store.dispatch(actions.updateWallet(wallet.id, finalWallet)); - syncWallet(dispatch, syncNode, finalWallet); + syncWallet(finalWallet); } /** Deletes a wallet, removing it from local storage and dispatching the change * to the Redux store. */ -export function deleteWallet(dispatch: AppDispatch, wallet: Wallet): void { +export function deleteWallet(wallet: Wallet): void { const key = getWalletKey(wallet); localStorage.removeItem(key); - dispatch(actions.removeWallet(wallet.id)); + store.dispatch(actions.removeWallet(wallet.id)); } /** Decrypts a wallet's password and privatekey. */ @@ -335,7 +325,7 @@ * decrypted, recalculate all the addresses with the new prefix. If the prefix * is unchanged, this does nothing. The changes will be dispatched to the * Redux store. */ -export async function recalculateWallets(dispatch: AppDispatch, masterPassword: string, wallets: WalletMap, addressPrefix: string): Promise { +export async function recalculateWallets(masterPassword: string, wallets: WalletMap, addressPrefix: string): Promise { const lastPrefix = localStorage.getItem("lastAddressPrefix") || "k"; if (addressPrefix === lastPrefix) return; debug("address prefix changed from %s to %s, waiting for mutex...", lastPrefix, addressPrefix); @@ -380,7 +370,7 @@ } // Apply all the changes to the Redux store - dispatch(actions.recalculateWallets(updatedWallets)); + store.dispatch(actions.recalculateWallets(updatedWallets)); debug("recalculation done, saving prefix"); localStorage.setItem("lastAddressPrefix", addressPrefix); diff --git a/src/krist/wallets/WalletManager.ts b/src/krist/wallets/WalletManager.ts index 5a9564c..64d0b2d 100644 --- a/src/krist/wallets/WalletManager.ts +++ b/src/krist/wallets/WalletManager.ts @@ -4,13 +4,12 @@ import { toHex } from "../../utils"; import { aesGcmEncrypt, aesGcmDecrypt } from "../../utils/crypto"; -import { AppDispatch } from "../../App"; +import { store } from "../../App"; import * as actions from "../../store/actions/WalletManagerActions"; /** Verifies that the given master password is correct, and dispatches the * auth action to the Redux store. */ export async function authMasterPassword( - dispatch: AppDispatch, salt: string | undefined, tester: string | undefined, password: string @@ -32,12 +31,12 @@ } // Dispatch the auth state changes to the Redux store - dispatch(actions.authMasterPassword(password)); + store.dispatch(actions.authMasterPassword(password)); } /** Generates a salt and tester, sets the master password, and dispatches the * action to the Redux store. */ -export async function setMasterPassword(dispatch: AppDispatch, password: string): Promise { +export async function setMasterPassword(password: string): Promise { if (!password) throw new Error("masterPassword.errorPasswordRequired"); // Generate the salt (to be encrypted with the master password) @@ -52,5 +51,5 @@ localStorage.setItem("tester", tester); // Dispatch the auth state changes to the Redux store - dispatch(actions.setMasterPassword(saltHex, tester, password)); + store.dispatch(actions.setMasterPassword(saltHex, tester, password)); } diff --git a/src/pages/dashboard/BlockDifficultyCard.tsx b/src/pages/dashboard/BlockDifficultyCard.tsx index d70c177..f17f671 100644 --- a/src/pages/dashboard/BlockDifficultyCard.tsx +++ b/src/pages/dashboard/BlockDifficultyCard.tsx @@ -107,9 +107,9 @@ }; const WORK_THROTTLE = 500; -async function _fetchWorkOverTime(syncNode: string, constants: KristConstants): Promise<{ x: Date; y: number }[]> { +async function _fetchWorkOverTime(constants: KristConstants): Promise<{ x: Date; y: number }[]> { debug("fetching work over time"); - const data = await api.get<{ work: number[] }>(syncNode, "work/day"); + const data = await api.get<{ work: number[] }>("work/day"); // Convert the array indices to Dates, based on the fact that the array // should contain one block per secondsPerBlock (typically 1440 elements, @@ -142,7 +142,7 @@ // changing, which is handled by WebsocketService. useEffect(() => { if (!syncNode) return; - fetchWorkOverTime(syncNode, constants); + fetchWorkOverTime(constants); }, [syncNode, lastBlockID, constants, constants.seconds_per_block, fetchWorkOverTime]); function chart(): JSX.Element { diff --git a/src/pages/dashboard/TransactionsCard.tsx b/src/pages/dashboard/TransactionsCard.tsx index 4952a52..534f3b5 100644 --- a/src/pages/dashboard/TransactionsCard.tsx +++ b/src/pages/dashboard/TransactionsCard.tsx @@ -21,11 +21,10 @@ const debug = Debug("kristweb:transactions-card"); const TRANSACTION_THROTTLE = 300; -async function _fetchTransactions(syncNode: string, wallets: WalletMap): Promise { +async function _fetchTransactions(wallets: WalletMap): Promise { debug("fetching transactions"); return lookupTransactions( - syncNode, Object.values(wallets).map(w => w.address), { includeMined: true, limit: 5, orderBy: "id", order: "DESC" } ); @@ -44,7 +43,7 @@ useEffect(() => { if (!syncNode || !wallets) return; - fetchTxs(syncNode, wallets); + fetchTxs(wallets); }, [syncNode, wallets, fetchTxs]); const walletAddressMap = Object.values(wallets) diff --git a/src/pages/settings/SettingBoolean.tsx b/src/pages/settings/SettingBoolean.tsx index ad8a47d..1179383 100644 --- a/src/pages/settings/SettingBoolean.tsx +++ b/src/pages/settings/SettingBoolean.tsx @@ -5,7 +5,7 @@ import { Switch } from "antd"; import { useTranslation } from "react-i18next"; -import { useDispatch, useSelector } from "react-redux"; +import { useSelector } from "react-redux"; import { RootState } from "../../store"; import { SettingName, setBooleanSetting } from "../../utils/settings"; @@ -18,12 +18,11 @@ export function SettingBoolean({ setting, title, titleKey }: Props): JSX.Element { const settingValue = useSelector((s: RootState) => s.settings[setting]); - const dispatch = useDispatch(); const { t } = useTranslation(); function onChange(value: boolean) { - setBooleanSetting(dispatch, setting, value); + setBooleanSetting(setting, value); } return
s.walletManager, shallowEqual); // Required to check for existing wallets const { wallets } = useSelector((s: RootState) => s.wallets, shallowEqual); - const syncNode = useSelector((s: RootState) => s.node.syncNode); const addressPrefix = useSelector((s: RootState) => s.node.currency.address_prefix); - const dispatch = useDispatch(); const { t } = useTranslation(); const bps = useBreakpoint(); @@ -104,7 +102,7 @@ }); } - await editWallet(dispatch, syncNode, addressPrefix, masterPassword, editing, values, values.password); + await editWallet(addressPrefix, masterPassword, editing, values, values.password); message.success(t("addWallet.messageSuccessEdit")); closeModal(); @@ -125,7 +123,7 @@ }); } - await addWallet(dispatch, syncNode, addressPrefix, masterPassword, values, values.password, values.save ?? true); + await addWallet(addressPrefix, masterPassword, values, values.password, values.save ?? true); message.success(create ? t("addWallet.messageSuccessCreate") : t("addWallet.messageSuccessAdd")); closeModal(); diff --git a/src/pages/wallets/WalletsTable.tsx b/src/pages/wallets/WalletsTable.tsx index 4c7e5d8..7b3344b 100644 --- a/src/pages/wallets/WalletsTable.tsx +++ b/src/pages/wallets/WalletsTable.tsx @@ -5,7 +5,7 @@ import { Table, Tooltip, Dropdown, Tag, Menu, Popconfirm } from "antd"; import { EditOutlined, DeleteOutlined } from "@ant-design/icons"; -import { useDispatch, useSelector, shallowEqual } from "react-redux"; +import { useSelector, shallowEqual } from "react-redux"; import { RootState } from "../../store"; import { useTranslation } from "react-i18next"; @@ -19,13 +19,11 @@ import { keyedNullSort, localeSort } from "../../utils"; function WalletActions({ wallet }: { wallet: Wallet }): JSX.Element { - const dispatch = useDispatch(); - const { t } = useTranslation(); const [editWalletVisible, setEditWalletVisible] = useState(false); function onDeleteWallet() { - deleteWallet(dispatch, wallet); + deleteWallet(wallet); } return <> diff --git a/src/utils/settings.ts b/src/utils/settings.ts index 440630c..a1083d7 100644 --- a/src/utils/settings.ts +++ b/src/utils/settings.ts @@ -3,7 +3,7 @@ // Full details: https://github.com/tmpim/KristWeb2/blob/master/LICENSE.txt import { PickByValue } from "utility-types"; -import { AppDispatch } from "../App"; +import { store } from "../App"; import * as actions from "../store/actions/SettingsActions"; export interface SettingsState { @@ -43,9 +43,9 @@ return settings; } -export function setBooleanSetting(dispatch: AppDispatch, settingName: SettingName, value: boolean): void { +export function setBooleanSetting(settingName: SettingName, value: boolean): void { localStorage.setItem(getSettingKey(settingName), value ? "true" : "false"); - dispatch(actions.setBooleanSetting(settingName, value)); + store.dispatch(actions.setBooleanSetting(settingName, value)); } export function isValidSyncNode(syncNode?: string): boolean {