From c5205693ea103678b9ba456904684af126a67ffc Mon Sep 17 00:00:00 2001 From: Chi Kei Chan Date: Fri, 11 Jun 2021 17:23:02 +0800 Subject: [PATCH 1/2] yourBids: add filter by bid status --- app/background/wallet/service.js | 48 ++++++++++++++++++- app/ducks/bids.js | 58 +++++++++++++++++++---- app/ducks/walletActions.js | 16 +++++-- app/pages/App/index.js | 4 +- app/pages/YourBids/BidAction.js | 2 - app/pages/YourBids/index.js | 76 +++++++++++++++++++++++++++---- app/pages/YourBids/your-bids.scss | 17 +++++++ 7 files changed, 195 insertions(+), 26 deletions(-) diff --git a/app/background/wallet/service.js b/app/background/wallet/service.js index 389ae0c6c..4a2e962c2 100644 --- a/app/background/wallet/service.js +++ b/app/background/wallet/service.js @@ -25,6 +25,7 @@ import {renewMany} from "./bulk-renewal"; import {getStats} from "./stats"; import {get, put} from "../db/service"; import hsdLedger from 'hsd-ledger'; +import {NAME_STATES} from "../../ducks/names"; const WalletNode = require('hsd/lib/wallet/node'); const TX = require('hsd/lib/primitives/tx'); @@ -308,10 +309,55 @@ class WalletService { return wallet.getPending('default'); }; + makeBidsFilter = async (bids = []) => { + const index = { + [NAME_STATES.OPENING]: [], + [NAME_STATES.BIDDING]: [], + [NAME_STATES.REVEAL]: [], + [NAME_STATES.CLOSED]: [], + [NAME_STATES.TRANSFER]: [], + }; + + const map = {}; + + const wallet = await this.node.wdb.get(this.name); + + for (let i = 0; i < bids.length; i++) { + const bid = bids[i]; + const name = bid.name.toString('utf-8'); + + let json; + + if (map[name]) { + json = map[name]; + } else { + const ns = await wallet.getNameStateByName(name); + json = ns?.getJSON(this.lastKnownChainHeight, this.network); + map[name] = json; + } + + const { state } = json || {}; + + switch (state) { + case NAME_STATES.OPENING: + case NAME_STATES.BIDDING: + case NAME_STATES.REVEAL: + case NAME_STATES.CLOSED: + case NAME_STATES.TRANSFER: + index[state].push(bid.prevout.hash.toString('hex') + bid.prevout.index); + break; + } + } + + return index; + }; + getBids = async () => { await this._ensureClient(); const wallet = await this.node.wdb.get(this.name); - return wallet.getBids(); + const bids = await wallet.getBids(); + const filter = await this.makeBidsFilter(bids); + return {bids, filter}; }; getMasterHDKey = () => this._ledgerDisabled( diff --git a/app/ducks/bids.js b/app/ducks/bids.js index 8a95a870f..bdbcbd447 100644 --- a/app/ducks/bids.js +++ b/app/ducks/bids.js @@ -1,23 +1,57 @@ import walletClient from '../utils/walletClient'; const SET_YOUR_BIDS = 'app/bids/setYourBids'; +const SET_BIDS_FILTER = 'app/bids/setBidsFilter'; const initialState = { - yourBids: [], + map: {}, + order: [], + filter: { + OPENING: [], + BIDDING: [], + REVEAL: [], + CLOSED: [], + TRANSFER: [], + }, }; -export const setYourBids = (bids = []) => ({ +export const setYourBids = ({ order, map }) => ({ type: SET_YOUR_BIDS, - payload: bids, + payload: { + order, + map, + }, +}); + +export const setFilter = (filter = {}) => ({ + type: SET_BIDS_FILTER, + payload: filter, }); export const getYourBids = () => async (dispatch) => { - const result = await walletClient.getBids(); + const {bids, filter} = await walletClient.getBids(); + + const yourBids = bids.filter(({ own }) => own); + + const order = yourBids.map(bid => { + return bid.prevout.hash + bid.prevout.index; + }); - const yourBids = result.filter(({ own }) => own); + const map = yourBids.reduce((acc, bid) => { + const id = bid.prevout.hash + bid.prevout.index; + acc[id] = bid; + return acc; + }, {}); - if (result && result.length) { - dispatch(setYourBids(yourBids)); + if (yourBids && yourBids.length) { + dispatch(setYourBids({ order, map })); + dispatch(setFilter({ + OPENING: filter.OPENING.filter(id => !!map[id]), + BIDDING: filter.BIDDING.filter(id => !!map[id]), + REVEAL: filter.REVEAL.filter(id => !!map[id]), + CLOSED: filter.CLOSED.filter(id => !!map[id]), + TRANSFER: filter.TRANSFER.filter(id => !!map[id]), + })); } }; @@ -26,7 +60,15 @@ export default function bidsReducer(state = initialState, action) { switch (type) { case SET_YOUR_BIDS: - return {...state, yourBids: payload}; + return { + ...state, + ...payload, + }; + case SET_BIDS_FILTER: + return { + ...state, + filter: payload, + }; default: return state; } diff --git a/app/ducks/walletActions.js b/app/ducks/walletActions.js index 3ed1c59d1..c58929cc0 100644 --- a/app/ducks/walletActions.js +++ b/app/ducks/walletActions.js @@ -22,7 +22,7 @@ import { } from './walletReducer'; import { NEW_BLOCK_STATUS } from './nodeReducer'; import {setNames} from "./myDomains"; -import {setYourBids} from "./bids"; +import {setFilter, setYourBids} from "./bids"; let idleInterval; @@ -142,7 +142,17 @@ export const unlockWallet = (name, passphrase) => async (dispatch, getState) => }); dispatch(setNames({})); - dispatch(setYourBids([])); + dispatch(setYourBids({ + order: [], + map: {}, + })); + dispatch(setFilter({ + OPENING: [], + BIDDING: [], + REVEAL: [], + CLOSED: [], + TRANSFER: [], + })) } dispatch({ @@ -411,7 +421,7 @@ async function parseInputsOutputs(net, tx) { // If yes, sum all outputs to others' addresses (payment made to sender) const containsOtherOutputs = tx.outputs.findIndex(x => x.covenant.action == 'NONE' && x.path !== null) !== -1; if (containsOtherOutputs) covValue = -tx.outputs.reduce((sum, op) => !op.path ? (sum+op.value) : sum, 0); - } + } } // Renewals and Updates have a value, but it doesn't diff --git a/app/pages/App/index.js b/app/pages/App/index.js index 521130b5a..f1e14e240 100644 --- a/app/pages/App/index.js +++ b/app/pages/App/index.js @@ -199,8 +199,8 @@ class App extends Component { isReveal(this.props.domain); diff --git a/app/pages/YourBids/index.js b/app/pages/YourBids/index.js index 40d8637ff..3252c3676 100644 --- a/app/pages/YourBids/index.js +++ b/app/pages/YourBids/index.js @@ -19,6 +19,7 @@ import c from "classnames"; import * as nameActions from "../../ducks/names"; import * as notifActions from "../../ducks/notifications"; import dbClient from "../../utils/dbClient"; +import {NAME_STATES} from "../../ducks/names"; const analytics = aClientStub(() => require('electron').ipcRenderer); @@ -33,7 +34,8 @@ const YOUR_BIDS_ITEMS_PER_PAGE_KEY = 'your-bids-items-per-page'; class YourBids extends Component { static propTypes = { - yourBids: PropTypes.array.isRequired, + order: PropTypes.array.isRequired, + map: PropTypes.object.isRequired, getYourBids: PropTypes.func.isRequired, sendRedeemAll: PropTypes.func.isRequired, sendRevealAll: PropTypes.func.isRequired, @@ -43,18 +45,22 @@ class YourBids extends Component { state = { isShowingNameClaimForPayment: false, + activeFilter: '', currentPageIndex: 0, itemsPerPage: 10, query: '', + loading: true, }; async componentDidMount() { analytics.screenView('Your Bids'); - this.props.getYourBids(); + this.props.getYourBids() + .then(() => this.setState({ loading: false })); const itemsPerPage = await dbClient.get(YOUR_BIDS_ITEMS_PER_PAGE_KEY); - + console.log(this.props.match.params.filterType) this.setState({ itemsPerPage: itemsPerPage || 10, + activeFilter: this.props.match.params.filterType || '', }); } @@ -107,6 +113,17 @@ class YourBids extends Component { } }; + getCurrentBids() { + const {order, map, filter} = this.props; + const {activeFilter} = this.state; + + if (activeFilter) { + return filter[activeFilter]?.map(id => map[id]) || []; + } else { + return order?.map(id => map[id]) || []; + } + } + render() { return (
@@ -137,6 +154,12 @@ class YourBids extends Component {
+
+ {this.renderFilter('ALL', '')} + {this.renderFilter(NAME_STATES.BIDDING, NAME_STATES.BIDDING)} + {this.renderFilter(NAME_STATES.REVEAL, NAME_STATES.REVEAL)} + {this.renderFilter(NAME_STATES.CLOSED, NAME_STATES.CLOSED)} +
{this.renderRows()} @@ -146,9 +169,26 @@ class YourBids extends Component { ); } + renderFilter = (label, value) => { + const {activeFilter} = this.state; + const { filter, order } = this.props; + const count = value ? filter[value].length : order.length; + + return ( +
this.setState({ activeFilter: value })} + > + {`${label} (${count})`} +
+ ) + }; + renderGoTo() { const { currentPageIndex, itemsPerPage } = this.state; - const { yourBids } = this.props; + const yourBids = this.getCurrentBids(); const totalPages = Math.ceil(yourBids.length / itemsPerPage); return (
@@ -186,9 +226,8 @@ class YourBids extends Component { currentPageIndex, itemsPerPage, } = this.state; - const { - yourBids, - } = this.props; + + const yourBids = this.getCurrentBids(); const totalPages = Math.ceil(yourBids.length / itemsPerPage); const pageIndices = getPageIndices(yourBids, itemsPerPage, currentPageIndex); @@ -234,8 +273,14 @@ class YourBids extends Component { } renderRows() { - const { yourBids, history } = this.props; - const { query, currentPageIndex: s, itemsPerPage: n } = this.state; + const { history } = this.props; + const { query, currentPageIndex: s, itemsPerPage: n, loading } = this.state; + + if (loading) { + return ; + } + + const yourBids = this.getCurrentBids(); if (!yourBids.length) { return ; @@ -272,7 +317,9 @@ class YourBids extends Component { export default withRouter( connect( state => ({ - yourBids: state.bids.yourBids, + order: state.bids.order, + map: state.bids.map, + filter: state.bids.filter, }), dispatch => ({ getYourBids: () => dispatch(bidsActions.getYourBids()), @@ -306,3 +353,12 @@ function EmptyResult() { ); } + + +function LoadingResult() { + return ( + + Loading Bids... + + ); +} diff --git a/app/pages/YourBids/your-bids.scss b/app/pages/YourBids/your-bids.scss index b0ae9da79..44973a11c 100644 --- a/app/pages/YourBids/your-bids.scss +++ b/app/pages/YourBids/your-bids.scss @@ -21,6 +21,23 @@ } } + &__filters { + @extend %row-nowrap; + flex-wrap: wrap; + margin: 1rem 0; + } + + &__filter { + margin-right: 1rem; + cursor: pointer; + color: $azure-blue; + + &--active { + cursor: default; + color: $black; + } + } + &__search { margin: 1rem 0; width: 10rem; From 07883eb0e82ee95671ff264e1dde24f4431a2004 Mon Sep 17 00:00:00 2001 From: Chi Kei Chan Date: Sun, 13 Jun 2021 22:24:52 +0800 Subject: [PATCH 2/2] remove console.log --- app/pages/YourBids/index.js | 1 - 1 file changed, 1 deletion(-) diff --git a/app/pages/YourBids/index.js b/app/pages/YourBids/index.js index 3252c3676..f6bb52412 100644 --- a/app/pages/YourBids/index.js +++ b/app/pages/YourBids/index.js @@ -57,7 +57,6 @@ class YourBids extends Component { this.props.getYourBids() .then(() => this.setState({ loading: false })); const itemsPerPage = await dbClient.get(YOUR_BIDS_ITEMS_PER_PAGE_KEY); - console.log(this.props.match.params.filterType) this.setState({ itemsPerPage: itemsPerPage || 10, activeFilter: this.props.match.params.filterType || '',