diff --git a/app/history.go b/app/history.go index f770b77..0c31628 100644 --- a/app/history.go +++ b/app/history.go @@ -50,8 +50,9 @@ func (a *App) GetHistoryPage(addr string, first, pageSize int) []TransactionEx { addrToHistoryMap[address] = append(addrToHistoryMap[address], *txEx) if len(addrToHistoryMap[address])%pageSize == 0 { a.SendMessage(address, Progress, &ProgressMsg{ - Have: int64(len(addrToHistoryMap[address])), - Want: nItems, + Address: address, + Have: int64(len(addrToHistoryMap[address])), + Want: nItems, }) } m.Unlock() diff --git a/app/message.go b/app/message.go index 89cd78f..851d8a7 100644 --- a/app/message.go +++ b/app/message.go @@ -15,8 +15,9 @@ const ( ) type ProgressMsg struct { - Have int64 `json:"have"` - Want int64 `json:"want"` + Address base.Address `json:"address"` + Have int64 `json:"have"` + Want int64 `json:"want"` } func (a *App) MessageType(msg Message) string { diff --git a/frontend/src/components/view/ViewStatus.tsx b/frontend/src/components/view/ViewStatus.tsx index 5fc1724..f643fb1 100644 --- a/frontend/src/components/view/ViewStatus.tsx +++ b/frontend/src/components/view/ViewStatus.tsx @@ -5,6 +5,7 @@ import { Text } from "@mantine/core"; import { MessageType } from "@gocode/app/App"; type Progress = { + address: string; have: number; want: number; }; @@ -20,7 +21,7 @@ export function ViewStatus() { }; const handleProgress = (p: Progress) => { - setStatusMessage(`Progress: ${p.have}/${p.want}`); + setStatusMessage(`Progress (${p.address}): ${p.have}/${p.want}`); setColor(classes.green); }; diff --git a/frontend/src/hooks/useKeyboardPaging.tsx b/frontend/src/hooks/useKeyboardPaging.tsx index acca409..a3df420 100644 --- a/frontend/src/hooks/useKeyboardPaging.tsx +++ b/frontend/src/hooks/useKeyboardPaging.tsx @@ -1,7 +1,7 @@ import { useEffect, useState, DependencyList } from "react"; import { useHotkeys } from "react-hotkeys-hook"; -export function useKeyboardPaging2(items: T[], nItems: number, deps: DependencyList = [], perPage: number = 20) { +export function useKeyboardPaging(items: T[], nItems: number, deps: DependencyList = [], perPage: number = 20) { const [curItem, setCurItem] = useState(0); useHotkeys("left", (event) => { @@ -37,66 +37,5 @@ export function useKeyboardPaging2(items: T[], nItems: number, deps: Dependen setCurItem(0); }, deps); - return { items, nItems, perPage, curItem }; -} - -type FetchItemsFn = (curItem: number, perPage: number) => Promise; -type FetchCountFn = () => Promise; - -export function useKeyboardPaging( - fetchItems: FetchItemsFn, - fetchCount: FetchCountFn, - dependency?: any, - perPage: number = 20 -) { - const [items, setItems] = useState([]); - const [nItems, setNItems] = useState(0); - const [curItem, setCurItem] = useState(0); - - useHotkeys("left", (event) => { - setCurItem((cur) => Math.max(cur - 1, 0)); - event.preventDefault(); - }); - useHotkeys("up", (event) => { - setCurItem((cur) => Math.max(cur - perPage, 0)); - event.preventDefault(); - }); - useHotkeys("home", (event) => { - setCurItem(0); - event.preventDefault(); - }); - - useHotkeys("right", (event) => { - var max = Math.max(nItems - perPage, 0); - setCurItem((cur) => Math.min(max, cur + 1)); - event.preventDefault(); - }); - useHotkeys("down", (event) => { - var max = Math.max(nItems - perPage, 0); - setCurItem((cur) => Math.min(max, cur + perPage)); - event.preventDefault(); - }); - useHotkeys("end", (event) => { - var max = Math.max(nItems - perPage, 0); - setCurItem(max); - event.preventDefault(); - }); - - useEffect(() => { - const fetch = async () => { - const fetchedItems = await fetchItems(curItem, perPage); - console.log("fetchedItems", fetchedItems.length); - setItems(fetchedItems); - const cnt = await fetchCount(); - console.log("cnt", cnt); - setNItems(cnt); - }; - fetch(); - }, [curItem, perPage, dependency]); - - useEffect(() => { - setCurItem(0); - }, [dependency]); - - return { items, nItems, curItem }; + return { curItem, perPage }; } diff --git a/frontend/src/views/History/HistoryView.module.css b/frontend/src/views/Columns.module.css similarity index 100% rename from frontend/src/views/History/HistoryView.module.css rename to frontend/src/views/Columns.module.css diff --git a/frontend/src/views/CustomMeta.tsx b/frontend/src/views/CustomMeta.tsx new file mode 100644 index 0000000..d63446b --- /dev/null +++ b/frontend/src/views/CustomMeta.tsx @@ -0,0 +1,5 @@ +import React from "react"; + +export interface CustomMeta { + className?: string; +} diff --git a/frontend/src/views/History/HistoryTable.tsx b/frontend/src/views/History/HistoryTable.tsx index f49b069..c178c10 100644 --- a/frontend/src/views/History/HistoryTable.tsx +++ b/frontend/src/views/History/HistoryTable.tsx @@ -2,11 +2,7 @@ import React from "react"; import { IconCircleCheck } from "@tabler/icons-react"; import { app } from "@gocode/models"; import { createColumnHelper, ColumnDef } from "@tanstack/react-table"; -import classes from "./HistoryTable.module.scss"; - -export interface CustomMeta { - className?: string; -} +import { CustomMeta } from "../CustomMeta"; type CustomColumnDef = ColumnDef & { meta?: CustomMeta; diff --git a/frontend/src/views/History/HistoryView.tsx b/frontend/src/views/History/HistoryView.tsx index f1869fa..04c86ab 100644 --- a/frontend/src/views/History/HistoryView.tsx +++ b/frontend/src/views/History/HistoryView.tsx @@ -1,14 +1,14 @@ import React, { useState, useEffect } from "react"; import classes from "@/App.module.css"; -import lClasses from "./HistoryView.module.css"; +import lClasses from "../Columns.module.css"; import { GetHistoryPage, GetHistoryCnt } from "@gocode/app/App"; import { app } from "@gocode/models"; import { flexRender, getCoreRowModel, useReactTable } from "@tanstack/react-table"; -import { useHotkeys } from "react-hotkeys-hook"; import { Stack, Table, Title } from "@mantine/core"; -import { txColumns, CustomMeta } from "./HistoryTable"; +import { txColumns } from "./HistoryTable"; +import { CustomMeta } from "../CustomMeta"; import { EditableSelect, View, ViewStatus } from "@components"; -import { useKeyboardPaging2 } from "@hooks"; +import { useKeyboardPaging } from "@hooks"; export function HistoryView() { const [address, setAddress] = useState("trueblocks.eth"); @@ -16,7 +16,7 @@ export function HistoryView() { const [loading, setLoading] = useState(false); const [loaded, setLoaded] = useState(false); const [items, setItems] = useState([]); - const { curItem, perPage } = useKeyboardPaging2(items, count, [address]); + const { curItem, perPage } = useKeyboardPaging(items, count, [address]); useEffect(() => { if (loaded && !loading) { @@ -31,11 +31,11 @@ export function HistoryView() { useEffect(() => { setLoading(true); try { - const fetch = async (addr: string, currentItem: number, itemsPerPage: number) => { + const fetch = async (addr: string) => { const cnt = await GetHistoryCnt(addr); setCount(cnt); }; - fetch(address, curItem, perPage); + fetch(address); setLoaded(true); } finally { setLoading(false); diff --git a/frontend/src/views/Names/NameTable.tsx b/frontend/src/views/Names/NameTable.tsx index de0db00..5d83ea8 100644 --- a/frontend/src/views/Names/NameTable.tsx +++ b/frontend/src/views/Names/NameTable.tsx @@ -1,49 +1,62 @@ import React from "react"; import { IconCircleCheck } from "@tabler/icons-react"; import { types } from "@gocode/models"; -import { createColumnHelper } from "@tanstack/react-table"; +import { createColumnHelper, ColumnDef } from "@tanstack/react-table"; +import { CustomMeta } from "../CustomMeta"; + +type CustomColumnDef = ColumnDef & { + meta?: CustomMeta; +}; const nameColumnHelper = createColumnHelper(); -export const nameColumns = [ +export const nameColumns: CustomColumnDef[] = [ nameColumnHelper.accessor("address", { header: () => "Address", - cell: (info) => info.getValue(), + cell: (info) => info.renderValue(), size: 100, + meta: { className: "wide" }, }), nameColumnHelper.accessor("tags", { header: () => "Tags", cell: (info) => info.renderValue(), size: 100, + meta: { className: "wide" }, }), nameColumnHelper.accessor("name", { header: () => "Name", cell: (info) => info.renderValue(), size: 100, + meta: { className: "wide" }, }), nameColumnHelper.accessor("symbol", { header: () => "Symbol", cell: (info) => info.renderValue(), size: 100, + meta: { className: "small" }, }), nameColumnHelper.accessor("decimals", { header: () => "Decimals", cell: (info) => info.renderValue(), size: 100, + meta: { className: "small" }, }), nameColumnHelper.accessor("isContract", { header: () => "isContract", cell: (info) => (info.getValue() ? : ""), size: 100, + meta: { className: "small-centered" }, }), nameColumnHelper.accessor("isErc20", { header: () => "isErc20", cell: (info) => (info.getValue() ? : ""), size: 100, + meta: { className: "small-centered" }, }), nameColumnHelper.accessor("isErc721", { header: () => "isErc721", cell: (info) => (info.getValue() ? : ""), size: 100, + meta: { className: "small-centered" }, }), ]; diff --git a/frontend/src/views/Names/NamesView.tsx b/frontend/src/views/Names/NamesView.tsx index 97d4a56..3ea9959 100644 --- a/frontend/src/views/Names/NamesView.tsx +++ b/frontend/src/views/Names/NamesView.tsx @@ -1,34 +1,74 @@ import React, { useState, useEffect } from "react"; import classes from "@/App.module.css"; +import lClasses from "../Columns.module.css"; import { GetNames, GetNamesCnt } from "@gocode/app/App"; import { types } from "@gocode/models"; import { flexRender, getCoreRowModel, useReactTable } from "@tanstack/react-table"; -import { useHotkeys } from "react-hotkeys-hook"; import { Stack, Table, Title } from "@mantine/core"; import { nameColumns } from "./NameTable"; +import { CustomMeta } from "../CustomMeta"; import { View, ViewStatus } from "@components"; import { useKeyboardPaging } from "@hooks"; export function NamesView() { - const { items, nItems, curItem } = useKeyboardPaging(GetNames, GetNamesCnt, undefined, 20); + const [count, setCount] = useState(0); + const [loading, setLoading] = useState(false); + const [loaded, setLoaded] = useState(false); + const [items, setItems] = useState([]); + const { curItem, perPage } = useKeyboardPaging(items, count); + + useEffect(() => { + if (loaded && !loading) { + const fetch = async (currentItem: number, itemsPerPage: number) => { + const newItems = await GetNames(currentItem, itemsPerPage); + setItems(newItems); + }; + fetch(curItem, perPage); + } + }, [count, curItem, perPage]); + + useEffect(() => { + setLoading(true); + try { + const fetch = async () => { + const cnt = await GetNamesCnt(); + setCount(cnt); + }; + fetch(); + setLoaded(true); + } finally { + setLoading(false); + } + }, []); + const table = useReactTable({ data: items, columns: nameColumns, getCoreRowModel: getCoreRowModel(), }); + if (loading) { + return ( + + + Loading... + + + ); + } + return ( - Names {curItem} of {nItems} + Names: showing record {curItem + 1}-{curItem + 1 + perPage - 1} of {count} {table.getHeaderGroups().map((headerGroup) => ( {headerGroup.headers.map((header) => ( - + {header.isPlaceholder ? null : flexRender(header.column.columnDef.header, header.getContext())} ))} @@ -38,11 +78,14 @@ export function NamesView() { {table.getRowModel().rows.map((row) => ( - {row.getVisibleCells().map((cell) => ( - - {flexRender(cell.column.columnDef.cell, cell.getContext())} - - ))} + {row.getVisibleCells().map((cell) => { + var meta = cell.column.columnDef.meta as CustomMeta; + return ( + + {flexRender(cell.column.columnDef.cell, cell.getContext())} + + ); + })} ))}