Commit 9db64f4e authored by zeroleak's avatar zeroleak
Browse files

ui/ux

parent dc09ec80
...@@ -25,7 +25,7 @@ class MixStatus extends React.PureComponent { ...@@ -25,7 +25,7 @@ class MixStatus extends React.PureComponent {
{mixService.getThreads().map((utxo,i) => { {mixService.getThreads().map((utxo,i) => {
const message = utils.utxoMessage(utxo) const message = utils.utxoMessage(utxo)
let progressLabel = <div> let progressLabel = <div>
<small>{utils.toBtc(utxo.value)}</small> <strong>{utils.statusLabel(utxo)}</strong><br/> <small>{utils.toBtc(utxo.value)}</small> <strong>{utils.statusLabel(utxo, false)}</strong><br/>
{message && <small>{message}</small>} {message && <small>{message}</small>}
</div> </div>
const progressPercent = utxo.progressPercent ? utxo.progressPercent : 0 const progressPercent = utxo.progressPercent ? utxo.progressPercent : 0
......
import React, { useEffect, useState } from 'react'; import React from 'react';
import BTable from 'react-bootstrap/Table'; import BTable from 'react-bootstrap/Table';
import { useRowSelect, useSortBy, useTable } from 'react-table'; import { useRowSelect, useSortBy, useTable } from 'react-table';
import * as Icon from 'react-feather'; import * as Icon from 'react-feather';
...@@ -20,18 +20,11 @@ const IndeterminateCheckbox = React.forwardRef( ...@@ -20,18 +20,11 @@ const IndeterminateCheckbox = React.forwardRef(
} }
) )
export default function TableGeneric({ columns, data, tableKey, size='sm', /*onFetchData, pageIndex, pageSize, filters, */sortBy, getRowStyle=()=>{}, getRowClassName=()=>{}, onSelect=undefined, className=undefined }) { export default function TableGeneric({ columns, data, size='sm', /*onFetchData, pageIndex, pageSize, filters, */sortBy, getRowStyle=()=>{}, getRowClassName=()=>{}, onSelect=undefined, className=undefined }) {
if (!data) { if (!data) {
return return
} }
const [lastTableKey, setLastTableKey] = useState()
const resetTable = !lastTableKey || lastTableKey != tableKey
useEffect(() => {
setLastTableKey(tableKey)
}, [tableKey])
const initialState = {}; const initialState = {};
if (sortBy) { if (sortBy) {
initialState.sortBy = sortBy; initialState.sortBy = sortBy;
...@@ -43,13 +36,13 @@ export default function TableGeneric({ columns, data, tableKey, size='sm', /*onF ...@@ -43,13 +36,13 @@ export default function TableGeneric({ columns, data, tableKey, size='sm', /*onF
columns, columns,
data, data,
initialState, initialState,
autoResetPage: resetTable, autoResetPage: false,
autoResetExpanded: resetTable, autoResetExpanded: false,
autoResetGroupBy: resetTable, autoResetGroupBy: false,
autoResetSelectedRows: resetTable, autoResetSelectedRows: false,
autoResetSortBy: resetTable, autoResetSortBy: false,
autoResetFilters: resetTable, autoResetFilters: false,
autoResetRowState: resetTable, autoResetRowState: false,
}, },
useSortBy, useSortBy,
useRowSelect, useRowSelect,
......
...@@ -124,7 +124,7 @@ const UtxosTable = ({ controls, pool, mixs, account, utxos, tableKey }) => { ...@@ -124,7 +124,7 @@ const UtxosTable = ({ controls, pool, mixs, account, utxos, tableKey }) => {
Header: 'Status', Header: 'Status',
accessor: o => o.status, accessor: o => o.status,
Cell: o => !isReadOnly(o.row.original) && Cell: o => !isReadOnly(o.row.original) &&
<span className='text-primary'>{utils.statusLabel(o.row.original)}</span> <span>{utils.statusLabel(o.row.original, true)}</span>
}); });
} }
columns.push({ columns.push({
...@@ -153,12 +153,13 @@ const UtxosTable = ({ controls, pool, mixs, account, utxos, tableKey }) => { ...@@ -153,12 +153,13 @@ const UtxosTable = ({ controls, pool, mixs, account, utxos, tableKey }) => {
const utxosReadOnly = utxos.filter(utxo => isReadOnly(utxo)) const utxosReadOnly = utxos.filter(utxo => isReadOnly(utxo))
const amountUtxosReadOnly = utxosReadOnly.map(utxo => utxo.value).reduce((total,current) => total+current, 0) const amountUtxosReadOnly = utxosReadOnly.map(utxo => utxo.value).reduce((total,current) => total+current, 0)
const key = tableKey+utils.computeUtxoDataKey(visibleUtxos);
return ( return (
<div> <div>
<div> <div>
<TableGeneric <TableGeneric
key={key}
className='table-utxos' className='table-utxos'
tableKey={tableKey}
columns={columns} columns={columns}
data={visibleUtxos} data={visibleUtxos}
sortBy={[{ id: 'lastActivityElapsed', desc: true }]} sortBy={[{ id: 'lastActivityElapsed', desc: true }]}
......
import cliService from './cliService'; import cliService from './cliService';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import * as Icons from '@fortawesome/free-solid-svg-icons'; import * as Icons from '@fortawesome/free-solid-svg-icons';
import crypto from 'crypto';
import * as React from 'react'; import * as React from 'react';
import { shell } from 'electron'; import { shell } from 'electron';
import moment from 'moment'; import moment from 'moment';
...@@ -120,61 +121,53 @@ class Utils { ...@@ -120,61 +121,53 @@ class Utils {
return 'https://oxt.me/address/'+utxo.address return 'https://oxt.me/address/'+utxo.address
} }
statusIcon(utxo) { utxoStatus(utxo) {
switch (utxo.status) {
if (utxo.status === UTXO_STATUS.MIX_STARTED) { case UTXO_STATUS.MIX_STARTED:
return <FontAwesomeIcon icon={Icons.faPlay} size='xs' color='green' title='MIXING'/> return ['MIXING', <FontAwesomeIcon icon={Icons.faPlay} size='xs' color='green' title='MIXING'/>, true]
} case UTXO_STATUS.TX0:
if (utxo.status === UTXO_STATUS.TX0) { return ['TX', <FontAwesomeIcon icon={Icons.faPlay} size='xs' color='green' title='TX0'/>, true]
return <FontAwesomeIcon icon={Icons.faPlay} size='xs' color='green' title='TX0'/> case UTXO_STATUS.TX0_SUCCESS:
} return ['TX0:SUCCESS', <FontAwesomeIcon icon={Icons.faPlay} size='xs' color='green' title='TX0 SUCCESS'/>, true]
if (utxo.status === UTXO_STATUS.TX0_FAILED) { case UTXO_STATUS.TX0_FAILED:
return <FontAwesomeIcon icon={Icons.faSquare} size='xs' color='red' title='TX0 FAILED'/> return ['TX0:ERROR', <FontAwesomeIcon icon={Icons.faSquare} size='xs' color='red' title='TX0 FAILED'/>, true]
} case UTXO_STATUS.MIX_FAILED:
if (utxo.status === UTXO_STATUS.MIX_FAILED) { return ['MIX:FAILED', <FontAwesomeIcon icon={Icons.faSquare} size='xs' color='red' title='MIX FAILED'/>, true]
return <FontAwesomeIcon icon={Icons.faSquare} size='xs' color='red' title='MIX FAILED'/> case UTXO_STATUS.MIX_SUCCESS:
return ['MIXED', <FontAwesomeIcon icon={Icons.faCheck} size='xs' color='green' title='MIXED'/>, false]
case UTXO_STATUS.STOP:
return ['STOPPED', <FontAwesomeIcon icon={Icons.faSquare} size='xs' color='red' title='TX0 FAILED'/>, false]
} }
if (utxo.account === WHIRLPOOL_ACCOUNTS.POSTMIX) { if (utxo.account === WHIRLPOOL_ACCOUNTS.POSTMIX) {
return <FontAwesomeIcon icon={Icons.faCheck} size='xs' color='green' title='MIXED'/> return ['MIXED', <FontAwesomeIcon icon={Icons.faCheck} size='xs' color='green' title='MIXED'/>, false]
}
const statusIcon = this.utxoStatusIcon(utxo)
switch (utxo.status) {
case UTXO_STATUS.READY:
return ['READY', statusIcon, false]
case UTXO_STATUS.MIX_QUEUE:
return ['QUEUE', statusIcon, false]
} }
console.error('Unknown utxoStatus', utxo)
return ['?', statusIcon, false]
}
utxoStatusIcon(utxo) {
switch(utxo.mixableStatus) { switch(utxo.mixableStatus) {
case MIXABLE_STATUS.MIXABLE: case MIXABLE_STATUS.MIXABLE:
return <FontAwesomeIcon icon={Icons.faCircle} size='xs' color='green' title='Ready to mix'/> return <FontAwesomeIcon icon={Icons.faCircle} size='xs' color='green' title='Ready to mix'/>
case MIXABLE_STATUS.HASH_MIXING: case MIXABLE_STATUS.HASH_MIXING:
return <FontAwesomeIcon icon={Icons.faEllipsisH} size='xs' color='orange' title='Another utxo from same hash is currently mixing'/> return <FontAwesomeIcon icon={Icons.faEllipsisH} size='xs' color='orange' title='Another utxo from same hash is currently mixing'/>
case MIXABLE_STATUS.NO_POOL:
return <span></span>
case MIXABLE_STATUS.UNCONFIRMED: case MIXABLE_STATUS.UNCONFIRMED:
return <FontAwesomeIcon icon={Icons.faClock} size='xs' title='Unconfirmed' className='text-muted'/> return <FontAwesomeIcon icon={Icons.faClock} size='xs' title='Unconfirmed' className='text-muted'/>
// case MIXABLE_STATUS.NO_POOL:
} }
return undefined return undefined
} }
statusLabel(utxo) { statusLabel(utxo, showEmphase) {
const icon = this.statusIcon(utxo) const [text, icon, emphase] = this.utxoStatus(utxo)
const text = this.statusLabelText(utxo) return <span>{icon?icon:''} <span className={(showEmphase?(emphase?'text-primary':'text-muted'):undefined)}>{text?text:''}</span></span>
return <span>{icon?icon:''} {text?text:''}</span>
}
statusLabelText(utxo) {
if (utxo.account === WHIRLPOOL_ACCOUNTS.POSTMIX) {
return 'MIXED'
}
if (utxo.mixableStatus === MIXABLE_STATUS.NO_POOL) {
return undefined
}
switch(utxo.status) {
case UTXO_STATUS.READY: return 'READY'
case UTXO_STATUS.STOP: return 'STOPPED'
case UTXO_STATUS.TX0: return 'TX0'
case UTXO_STATUS.TX0_SUCCESS: return 'TX0:SUCCESS'
case UTXO_STATUS.TX0_FAILED: return 'TX0:ERROR'
case UTXO_STATUS.MIX_QUEUE: return 'QUEUE'
case UTXO_STATUS.MIX_STARTED: return 'MIXING'
case UTXO_STATUS.MIX_FAILED: return 'MIX:FAILED'
default: return '?'
}
} }
utxoMessage(utxo) { utxoMessage(utxo) {
...@@ -263,6 +256,16 @@ class Utils { ...@@ -263,6 +256,16 @@ class Utils {
spinner() { spinner() {
return <FontAwesomeIcon icon={Icons.faSpinner} spin size='xs' /> return <FontAwesomeIcon icon={Icons.faSpinner} spin size='xs' />
} }
computeUtxoDataKey(utxos) {
const utxoIds = utxos.map(utxo => utxo.hash + ':' + utxo.index)
const dataKey = this.md5(utxoIds.join(';'))
return dataKey
}
md5(str) {
return crypto.createHash('md5').update(str).digest('hex');
}
} }
const utils = new Utils() const utils = new Utils()
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment