some fixes
This commit is contained in:
@@ -19,6 +19,7 @@ import { observer } from 'mobx-react-lite';
|
|||||||
import Delegates from './pages/services/Delegates';
|
import Delegates from './pages/services/Delegates';
|
||||||
import VPNServers from './pages/services/VPNServers';
|
import VPNServers from './pages/services/VPNServers';
|
||||||
import VPNPrepare from './pages/services/VPNPrepare';
|
import VPNPrepare from './pages/services/VPNPrepare';
|
||||||
|
import { NotificationContainer } from './components/NotificationContainer';
|
||||||
|
|
||||||
const App = observer(() => {
|
const App = observer(() => {
|
||||||
const location = useLocation();
|
const location = useLocation();
|
||||||
@@ -39,6 +40,7 @@ const App = observer(() => {
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{store.loading && <LoadingOverlay />}
|
{store.loading && <LoadingOverlay />}
|
||||||
|
<NotificationContainer />
|
||||||
<Routes>
|
<Routes>
|
||||||
<Route exact path="/" element={<Onboarding1 />} />
|
<Route exact path="/" element={<Onboarding1 />} />
|
||||||
<Route path="/digitalId/profile-id" element={<ProfileId />} />
|
<Route path="/digitalId/profile-id" element={<ProfileId />} />
|
||||||
|
|||||||
@@ -89,9 +89,9 @@ function DropdownTransaction({ align, value, onChange }) {
|
|||||||
<li>
|
<li>
|
||||||
<span
|
<span
|
||||||
className="font-medium text-sm text-slate-600 hover:text-slate-800 flex items-center py-1 px-3 cursor-pointer"
|
className="font-medium text-sm text-slate-600 hover:text-slate-800 flex items-center py-1 px-3 cursor-pointer"
|
||||||
onClick={() => changeValue('Unvoiting')}
|
onClick={() => changeValue('Unlocking')}
|
||||||
>
|
>
|
||||||
Unvoiting
|
Unlocking
|
||||||
</span>
|
</span>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|||||||
14
src/components/NotificationContainer.jsx
Normal file
14
src/components/NotificationContainer.jsx
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { observer } from 'mobx-react-lite';
|
||||||
|
import { Toast } from './Toast2';
|
||||||
|
import { store } from '../store/store';
|
||||||
|
|
||||||
|
export const NotificationContainer = observer(() => (
|
||||||
|
<div className="absolute z-50 top-2 right-2 gap-2">
|
||||||
|
{store.notifications.map((e) => (
|
||||||
|
<Toast type={e.type} key={e.id} id={e.id}>
|
||||||
|
{e.message}
|
||||||
|
</Toast>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
));
|
||||||
90
src/components/Toast2.jsx
Normal file
90
src/components/Toast2.jsx
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
import React, { useEffect } from 'react';
|
||||||
|
import { store } from '../store/store';
|
||||||
|
import { observer } from 'mobx-react-lite';
|
||||||
|
|
||||||
|
export const Toast = observer(({ children, className, type, id }) => {
|
||||||
|
const typeIcon = (type) => {
|
||||||
|
switch (type) {
|
||||||
|
case 'warning':
|
||||||
|
return (
|
||||||
|
<svg
|
||||||
|
className="w-4 h-4 shrink-0 fill-current opacity-80 mt-[3px] mr-3"
|
||||||
|
viewBox="0 0 16 16"
|
||||||
|
>
|
||||||
|
<path d="M8 0C3.6 0 0 3.6 0 8s3.6 8 8 8 8-3.6 8-8-3.6-8-8-8zm0 12c-.6 0-1-.4-1-1s.4-1 1-1 1 .4 1 1-.4 1-1 1zm1-3H7V4h2v5z" />
|
||||||
|
</svg>
|
||||||
|
);
|
||||||
|
case 'error':
|
||||||
|
return (
|
||||||
|
<svg
|
||||||
|
className="w-4 h-4 shrink-0 fill-current opacity-80 mt-[3px] mr-3"
|
||||||
|
viewBox="0 0 16 16"
|
||||||
|
>
|
||||||
|
<path d="M8 0C3.6 0 0 3.6 0 8s3.6 8 8 8 8-3.6 8-8-3.6-8-8-8zm3.5 10.1l-1.4 1.4L8 9.4l-2.1 2.1-1.4-1.4L6.6 8 4.5 5.9l1.4-1.4L8 6.6l2.1-2.1 1.4 1.4L9.4 8l2.1 2.1z" />
|
||||||
|
</svg>
|
||||||
|
);
|
||||||
|
case 'success':
|
||||||
|
return (
|
||||||
|
<svg
|
||||||
|
className="w-4 h-4 shrink-0 fill-current opacity-80 mt-[3px] mr-3"
|
||||||
|
viewBox="0 0 16 16"
|
||||||
|
>
|
||||||
|
<path d="M8 0C3.6 0 0 3.6 0 8s3.6 8 8 8 8-3.6 8-8-3.6-8-8-8zM7 11.4L3.6 8 5 6.6l2 2 4-4L12.4 6 7 11.4z" />
|
||||||
|
</svg>
|
||||||
|
);
|
||||||
|
default:
|
||||||
|
return (
|
||||||
|
<svg
|
||||||
|
className="w-4 h-4 shrink-0 fill-current opacity-80 mt-[3px] mr-3"
|
||||||
|
viewBox="0 0 16 16"
|
||||||
|
>
|
||||||
|
<path d="M8 0C3.6 0 0 3.6 0 8s3.6 8 8 8 8-3.6 8-8-3.6-8-8-8zm1 12H7V7h2v5zM8 6c-.6 0-1-.4-1-1s.4-1 1-1 1 .4 1 1-.4 1-1 1z" />
|
||||||
|
</svg>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const typeColor = (type) => {
|
||||||
|
switch (type) {
|
||||||
|
case 'warning':
|
||||||
|
return 'bg-amber-100 border-amber-200 text-amber-600';
|
||||||
|
case 'error':
|
||||||
|
return 'bg-rose-100 border-rose-200 text-rose-600';
|
||||||
|
case 'success':
|
||||||
|
return 'bg-emerald-100 border-emerald-200 text-emerald-600';
|
||||||
|
default:
|
||||||
|
return 'bg-indigo-100 border-indigo-200 text-indigo-500';
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const timerId = setTimeout(() => store.removeNotification(id), 3000);
|
||||||
|
return () => clearTimeout(timerId);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={className}>
|
||||||
|
<div
|
||||||
|
className={`inline-flex min-w-80 px-4 py-2 rounded-sm text-sm border ${typeColor(
|
||||||
|
type
|
||||||
|
)}`}
|
||||||
|
>
|
||||||
|
<div className="flex w-full justify-between items-start">
|
||||||
|
<div className="flex">
|
||||||
|
{typeIcon(type)}
|
||||||
|
<div>{children}</div>
|
||||||
|
</div>
|
||||||
|
<button
|
||||||
|
className="opacity-70 hover:opacity-80 ml-3 mt-[3px]"
|
||||||
|
onClick={() => store.removeNotification(id)}
|
||||||
|
>
|
||||||
|
<div className="sr-only">Close</div>
|
||||||
|
<svg className="w-4 h-4 fill-current">
|
||||||
|
<path d="M7.95 6.536l4.242-4.243a1 1 0 111.415 1.414L9.364 7.95l4.243 4.242a1 1 0 11-1.415 1.415L7.95 9.364l-4.243 4.243a1 1 0 01-1.414-1.415L6.536 7.95 2.293 3.707a1 1 0 011.414-1.414L7.95 6.536z" />
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
});
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
import React, { useEffect, useState } from 'react';
|
import React, { useEffect, useMemo, useState } from 'react';
|
||||||
|
|
||||||
import Sidebar from '../../partials/Sidebar';
|
import Sidebar from '../../partials/Sidebar';
|
||||||
import Header from '../../partials/Header';
|
import Header from '../../partials/Header';
|
||||||
@@ -10,7 +10,7 @@ import TransactionPanel from '../../partials/finance/TransactionPanel';
|
|||||||
import { Filters } from '../../components/Filters';
|
import { Filters } from '../../components/Filters';
|
||||||
|
|
||||||
const filters = {
|
const filters = {
|
||||||
'View All': '',
|
'View All': 'all',
|
||||||
Voted: 'Unvote',
|
Voted: 'Unvote',
|
||||||
Pending: 'Pending',
|
Pending: 'Pending',
|
||||||
};
|
};
|
||||||
@@ -22,17 +22,24 @@ const Delegates = observer(() => {
|
|||||||
|
|
||||||
const [lockedFor, setLockedFor] = useState('Voiting');
|
const [lockedFor, setLockedFor] = useState('Voiting');
|
||||||
|
|
||||||
const lockedLabel = Object.values(
|
const delegates = useMemo(() => {
|
||||||
lockedFor === 'Voiting' ? store.processedVotes : store.accountLockedVotes
|
if (filters[currentFilter] === 'all') return store.delegates;
|
||||||
|
return store.delegates.filter((e) => e.status === filters[currentFilter]);
|
||||||
|
}, [store.delegates, currentFilter]);
|
||||||
|
|
||||||
|
const lockedLabel = (
|
||||||
|
lockedFor === 'Voiting'
|
||||||
|
? Object.values(store.accountSentVotes)
|
||||||
|
: Object.values(store.accountLockedVotesCanReturn)
|
||||||
|
.flat()
|
||||||
|
.map((e) => e.amount)
|
||||||
)
|
)
|
||||||
.reduce((sum, e) => sum + e, 0n)
|
.reduce((sum, e) => sum + e, 0n)
|
||||||
.toString();
|
.toString();
|
||||||
|
|
||||||
const [fetchOffset, setFetchOffset] = useState(0);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
store.fetchDelegates(fetchOffset);
|
store.fetchDelegates(0);
|
||||||
}, [fetchOffset]);
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex h-screen overflow-hidden">
|
<div className="flex h-screen overflow-hidden">
|
||||||
@@ -72,20 +79,21 @@ const Delegates = observer(() => {
|
|||||||
|
|
||||||
{/* Table */}
|
{/* Table */}
|
||||||
<TransactionsTable
|
<TransactionsTable
|
||||||
data={store.delegates}
|
data={delegates}
|
||||||
|
lockedFor={lockedFor}
|
||||||
rowClick={(delegate) => setCurrentDelegate(delegate)}
|
rowClick={(delegate) => setCurrentDelegate(delegate)}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
{/* Pagination */}
|
{/*/!* Pagination *!/*/}
|
||||||
<div className="mt-8">
|
{/*<div className="mt-8">*/}
|
||||||
<PaginationClassic
|
{/* <PaginationClassic*/}
|
||||||
count={store.delegatesMeta.count}
|
{/* count={store.delegatesMeta.count}*/}
|
||||||
limit={store.delegatesMeta.limit}
|
{/* limit={store.delegatesMeta.limit}*/}
|
||||||
offset={store.delegatesMeta.offset}
|
{/* offset={store.delegatesMeta.offset}*/}
|
||||||
onNextPage={() => setFetchOffset((prev) => prev + 10)}
|
{/* onNextPage={() => setFetchOffset((prev) => prev + 10)}*/}
|
||||||
onPrevPage={() => setFetchOffset((prev) => prev - 10)}
|
{/* onPrevPage={() => setFetchOffset((prev) => prev - 10)}*/}
|
||||||
/>
|
{/* />*/}
|
||||||
</div>
|
{/*</div>*/}
|
||||||
|
|
||||||
<TransactionPanel
|
<TransactionPanel
|
||||||
transactionPanelOpen={!!currentDelegate}
|
transactionPanelOpen={!!currentDelegate}
|
||||||
|
|||||||
@@ -26,6 +26,8 @@ const VPNPrepare = observer(() => {
|
|||||||
if (store.canVPN) navigate('/services/vpn/servers');
|
if (store.canVPN) navigate('/services/vpn/servers');
|
||||||
}, [store.canVPN]);
|
}, [store.canVPN]);
|
||||||
|
|
||||||
|
if (store.loading && !store.canVPN) return null;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex h-screen overflow-hidden">
|
<div className="flex h-screen overflow-hidden">
|
||||||
{/* Sidebar */}
|
{/* Sidebar */}
|
||||||
|
|||||||
@@ -95,7 +95,7 @@ PersistentKeepalive = 25
|
|||||||
<label
|
<label
|
||||||
className="relative block cursor-pointer text-left w-full"
|
className="relative block cursor-pointer text-left w-full"
|
||||||
onClick={() => setSelectedServer(i)}
|
onClick={() => setSelectedServer(i)}
|
||||||
key={e.publicKey}
|
key={e.serverPublickKey}
|
||||||
>
|
>
|
||||||
<input
|
<input
|
||||||
type="radio"
|
type="radio"
|
||||||
@@ -107,7 +107,7 @@ PersistentKeepalive = 25
|
|||||||
<div className="p-4 rounded border border-slate-200 hover:border-slate-300 shadow-sm duration-150 ease-in-out">
|
<div className="p-4 rounded border border-slate-200 hover:border-slate-300 shadow-sm duration-150 ease-in-out">
|
||||||
<div className="grid grid-cols-12 items-center gap-x-2">
|
<div className="grid grid-cols-12 items-center gap-x-2">
|
||||||
{/* Card */}
|
{/* Card */}
|
||||||
<div className="col-span-6 order-1 sm:order-none sm:col-span-3 flex items-center space-x-4 lg:sidebar-expanded:col-span-6 xl:sidebar-expanded:col-span-3">
|
<div className="col-span-6 order-1 sm:order-none flex items-center space-x-4 ">
|
||||||
<ReactCountryFlag
|
<ReactCountryFlag
|
||||||
countryCode={e.country}
|
countryCode={e.country}
|
||||||
svg
|
svg
|
||||||
@@ -121,13 +121,13 @@ PersistentKeepalive = 25
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{/* Card limits */}
|
{/* Card limits */}
|
||||||
<div className="col-span-6 order-1 sm:order-none sm:col-span-4 text-right sm:text-center lg:sidebar-expanded:col-span-6 xl:sidebar-expanded:col-span-6">
|
<div className="col-span-3 order-1 sm:order-none text-right sm:text-center">
|
||||||
<div className="text-sm">
|
<div className="text-sm">
|
||||||
{e.transferSum} / 50.00 GB
|
{e.transferSum} / 50.00 GB
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{/* Card status */}
|
{/* Card status */}
|
||||||
<div className="col-span-6 order-2 sm:order-none sm:col-span-2 text-right lg:sidebar-expanded:hidden xl:sidebar-expanded:block">
|
<div className="col-span-3 order-2 sm:order-none text-right">
|
||||||
{e?.state ? (
|
{e?.state ? (
|
||||||
<div className="text-xs inline-flex font-medium bg-emerald-100 text-emerald-600 rounded-full text-center px-2.5 py-1">
|
<div className="text-xs inline-flex font-medium bg-emerald-100 text-emerald-600 rounded-full text-center px-2.5 py-1">
|
||||||
Active
|
Active
|
||||||
@@ -150,7 +150,7 @@ PersistentKeepalive = 25
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Sidebar */}
|
{/* Sidebar */}
|
||||||
{servers?.length > 0 && (
|
{servers?.length > 0 && servers?.[selectedServer]?.state && (
|
||||||
<div>
|
<div>
|
||||||
<div className="lg:sticky lg:top-16 bg-slate-50 lg:overflow-x-hidden lg:overflow-y-auto no-scrollbar lg:shrink-0 border-t lg:border-t-0 lg:border-l border-slate-200 lg:w-[390px] lg:h-[calc(100vh-64px)]">
|
<div className="lg:sticky lg:top-16 bg-slate-50 lg:overflow-x-hidden lg:overflow-y-auto no-scrollbar lg:shrink-0 border-t lg:border-t-0 lg:border-l border-slate-200 lg:w-[390px] lg:h-[calc(100vh-64px)]">
|
||||||
<div className="py-8 px-4 lg:px-8 h-full">
|
<div className="py-8 px-4 lg:px-8 h-full">
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import TransactionItem from './TransactionsTableItem';
|
|||||||
import Image01 from '../../images/transactions-image-01.svg';
|
import Image01 from '../../images/transactions-image-01.svg';
|
||||||
import { observer } from 'mobx-react-lite';
|
import { observer } from 'mobx-react-lite';
|
||||||
|
|
||||||
const TransactionsTable = observer(({ data, rowClick }) => {
|
const TransactionsTable = observer(({ data, rowClick, lockedFor }) => {
|
||||||
return (
|
return (
|
||||||
<div className="bg-white">
|
<div className="bg-white">
|
||||||
<div>
|
<div>
|
||||||
@@ -30,7 +30,9 @@ const TransactionsTable = observer(({ data, rowClick }) => {
|
|||||||
<div className="font-semibold text-center"></div>
|
<div className="font-semibold text-center"></div>
|
||||||
</th>
|
</th>
|
||||||
<th className="px-4 first:pl-5 last:pr-5 py-3 whitespace-nowrap">
|
<th className="px-4 first:pl-5 last:pr-5 py-3 whitespace-nowrap">
|
||||||
<div className="font-semibold text-center">Sent Votes</div>
|
<div className="font-semibold text-center">
|
||||||
|
{lockedFor === 'Voiting' ? 'Sent Votes' : 'Blocked votes'}
|
||||||
|
</div>
|
||||||
</th>
|
</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
@@ -42,14 +44,25 @@ const TransactionsTable = observer(({ data, rowClick }) => {
|
|||||||
key={delegate.address}
|
key={delegate.address}
|
||||||
id={delegate.address}
|
id={delegate.address}
|
||||||
image={Image01}
|
image={Image01}
|
||||||
balance={delegate.token.balance}
|
balance={delegate?.token?.balance}
|
||||||
name={delegate.dpos.delegate.username || delegate.address}
|
name={delegate.dpos?.delegate?.username || delegate.address}
|
||||||
total={delegate.dpos.delegate.totalVotesReceived}
|
total={delegate.dpos?.delegate?.totalVotesReceived || ''}
|
||||||
hasSevice={false}
|
hasSevice={
|
||||||
|
delegate.dpos?.delegate?.username === 'delegate_0'
|
||||||
|
}
|
||||||
date={delegate.date}
|
date={delegate.date}
|
||||||
|
displayReturn={lockedFor === 'Unlocking'}
|
||||||
status={delegate.status}
|
status={delegate.status}
|
||||||
amount={store.accountSentVotes[delegate.address] || 0}
|
amount={
|
||||||
handleClick={() => rowClick(delegate)}
|
(lockedFor === 'Voiting'
|
||||||
|
? store.accountSentVotes[delegate.address]
|
||||||
|
: store.accountLockedVotesCanReturnSum[
|
||||||
|
delegate.address
|
||||||
|
]) || ''
|
||||||
|
}
|
||||||
|
handleClick={() =>
|
||||||
|
lockedFor === 'Voiting' && rowClick(delegate)
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
|
|||||||
@@ -43,14 +43,6 @@ const TransactionsTableItem = observer((props) => {
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="font-medium text-slate-800">{props.name}</div>
|
<div className="font-medium text-slate-800">{props.name}</div>
|
||||||
{store.accountLockedVotesCanReturn[props.id] && (
|
|
||||||
<span
|
|
||||||
className="truncate font-medium text-indigo-500 group-hover:text-indigo-600 ml-2"
|
|
||||||
onClick={clickReturn}
|
|
||||||
>
|
|
||||||
Return votes
|
|
||||||
</span>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td className="px-2 first:pl-5 last:pr-5 py-3 whitespace-nowrap">
|
<td className="px-2 first:pl-5 last:pr-5 py-3 whitespace-nowrap">
|
||||||
@@ -72,21 +64,36 @@ const TransactionsTableItem = observer((props) => {
|
|||||||
<div className="text-center">{props.balance}/idn</div>
|
<div className="text-center">{props.balance}/idn</div>
|
||||||
</td>
|
</td>
|
||||||
<td className="px-2 first:pl-5 last:pr-5 py-3 whitespace-nowrap">
|
<td className="px-2 first:pl-5 last:pr-5 py-3 whitespace-nowrap">
|
||||||
<div className="text-center">{props.total}/idn</div>
|
<div className="text-center">
|
||||||
|
{props.total}
|
||||||
|
{props.total && '/idn'}
|
||||||
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td className="px-2 first:pl-5 last:pr-5 py-3 whitespace-nowrap">
|
<td className="px-2 first:pl-5 last:pr-5 py-3 whitespace-nowrap">
|
||||||
<div className="text-center">
|
<div className="text-center">
|
||||||
|
{props.displayReturn ? (
|
||||||
|
store.accountLockedVotesCanReturn[props.id] && (
|
||||||
|
<span
|
||||||
|
className="truncate font-medium text-indigo-500 group-hover:text-indigo-600 ml-2"
|
||||||
|
onClick={clickReturn}
|
||||||
|
>
|
||||||
|
Return votes
|
||||||
|
</span>
|
||||||
|
)
|
||||||
|
) : (
|
||||||
<div
|
<div
|
||||||
className={`text-xs inline-flex font-medium rounded-full justify-center px-2.5 py-1 ${statusColor()}`}
|
className={`text-xs inline-flex font-medium rounded-full justify-center px-2.5 py-1 ${statusColor()}`}
|
||||||
style={{ minWidth: '84px' }}
|
style={{ minWidth: '84px' }}
|
||||||
>
|
>
|
||||||
{props.status}
|
{props.status}
|
||||||
</div>
|
</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td className="px-2 first:pl-5 last:pr-5 py-3 whitespace-nowrap w-px">
|
<td className="px-2 first:pl-5 last:pr-5 py-3 whitespace-nowrap w-px">
|
||||||
<div className={`text-center font-medium ${amountColor()}`}>
|
<div className={`text-center font-medium ${amountColor()}`}>
|
||||||
{props.amount.toString()}/idn
|
{props.amount.toString()}
|
||||||
|
{props.amount && '/idn'}
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|||||||
@@ -64,7 +64,12 @@ function request(method, url, headers = {}, token, body) {
|
|||||||
requestOptions.headers.Authorization = null;
|
requestOptions.headers.Authorization = null;
|
||||||
}
|
}
|
||||||
setTimeout(() => controller.abort(), 15000);
|
setTimeout(() => controller.abort(), 15000);
|
||||||
return fetch(prepareUrl(url), requestOptions);
|
return fetch(prepareUrl(url), requestOptions).then((res) => {
|
||||||
|
if (res.status > 400) {
|
||||||
|
store.addNotification(new Date().getTime(), 'error', res.statusText);
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function get(url, headers, attempts = 3) {
|
function get(url, headers, attempts = 3) {
|
||||||
|
|||||||
@@ -13,7 +13,6 @@ import { statusMap } from '../shared/statusMap';
|
|||||||
import { generateSvgAvatar } from '../images/GenerateOnboardingSvg/GenerateSvg';
|
import { generateSvgAvatar } from '../images/GenerateOnboardingSvg/GenerateSvg';
|
||||||
import { decryptedData } from '../utils/decryptedData';
|
import { decryptedData } from '../utils/decryptedData';
|
||||||
import {
|
import {
|
||||||
bytesToMbytes,
|
|
||||||
encryptAccountData,
|
encryptAccountData,
|
||||||
encryptSharedData,
|
encryptSharedData,
|
||||||
formatBytes,
|
formatBytes,
|
||||||
@@ -55,6 +54,8 @@ class Store {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
_notifications = [];
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
makeAutoObservable(this, {});
|
makeAutoObservable(this, {});
|
||||||
|
|
||||||
@@ -93,7 +94,7 @@ class Store {
|
|||||||
.then((r) => this.fetchVPNServersSuccess(r));
|
.then((r) => this.fetchVPNServersSuccess(r));
|
||||||
}
|
}
|
||||||
|
|
||||||
fetchDelegates(offset = 0, limit = 10) {
|
fetchDelegates(offset = 0, limit = 100) {
|
||||||
fetchWrapper
|
fetchWrapper
|
||||||
.getAuth(`delegates?limit=${limit}&offset=${offset}`)
|
.getAuth(`delegates?limit=${limit}&offset=${offset}`)
|
||||||
.then((r) => this.fetchDelegatesSuccess(r));
|
.then((r) => this.fetchDelegatesSuccess(r));
|
||||||
@@ -253,10 +254,9 @@ class Store {
|
|||||||
this.passPhrase
|
this.passPhrase
|
||||||
);
|
);
|
||||||
|
|
||||||
const { amount, unvoteHeight } =
|
const unlockObjects = this.accountLockedVotesCanReturn[delegateAddress];
|
||||||
this.accountLockedVotesCanReturn[delegateAddress];
|
|
||||||
|
|
||||||
const signedTx = builder.unlock(delegateAddress, amount, unvoteHeight);
|
const signedTx = builder.unlock(delegateAddress, unlockObjects);
|
||||||
|
|
||||||
if (signedTx) {
|
if (signedTx) {
|
||||||
fetchWrapper
|
fetchWrapper
|
||||||
@@ -507,15 +507,27 @@ class Store {
|
|||||||
.reduce(
|
.reduce(
|
||||||
(acc, e) => ({
|
(acc, e) => ({
|
||||||
...acc,
|
...acc,
|
||||||
[e.delegateAddress]: {
|
[e.delegateAddress]: [
|
||||||
|
{
|
||||||
|
...acc[e.delegateAddress],
|
||||||
amount: BigInt(e.amount || 0) / 100000000n,
|
amount: BigInt(e.amount || 0) / 100000000n,
|
||||||
unvoteHeight: e.unvoteHeight,
|
unvoteHeight: e.unvoteHeight,
|
||||||
},
|
},
|
||||||
|
],
|
||||||
}),
|
}),
|
||||||
{}
|
{}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get accountLockedVotesCanReturnSum() {
|
||||||
|
return Object.fromEntries(
|
||||||
|
Object.entries(this.accountLockedVotesCanReturn).map(([key, val]) => [
|
||||||
|
key,
|
||||||
|
val.reduce((sum, e) => sum + e.amount, 0n),
|
||||||
|
])
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
get accountFeaturesMap() {
|
get accountFeaturesMap() {
|
||||||
return this.accountFeatures.reduce(
|
return this.accountFeatures.reduce(
|
||||||
(acc, item) => ({
|
(acc, item) => ({
|
||||||
@@ -644,7 +656,7 @@ class Store {
|
|||||||
...delegate.dpos.delegate,
|
...delegate.dpos.delegate,
|
||||||
totalVotesReceived: Number(
|
totalVotesReceived: Number(
|
||||||
BigInt(delegate.dpos.delegate.totalVotesReceived) / 100000000n
|
BigInt(delegate.dpos.delegate.totalVotesReceived) / 100000000n
|
||||||
).toString(),
|
),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
@@ -653,6 +665,22 @@ class Store {
|
|||||||
get delegatesMeta() {
|
get delegatesMeta() {
|
||||||
return this._delegates.meta;
|
return this._delegates.meta;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get notifications() {
|
||||||
|
return this._notifications;
|
||||||
|
}
|
||||||
|
|
||||||
|
addNotification(id, type, message) {
|
||||||
|
this._notifications.push({
|
||||||
|
id,
|
||||||
|
type,
|
||||||
|
message,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
removeNotification(id) {
|
||||||
|
this._notifications = this._notifications.filter((e) => e.id !== id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const store = new Store();
|
export const store = new Store();
|
||||||
|
|||||||
@@ -197,7 +197,7 @@ export const generateTransaction = (
|
|||||||
delegateAddress,
|
delegateAddress,
|
||||||
amount
|
amount
|
||||||
),
|
),
|
||||||
unlock: (delegateAddress, amount, unvoteHeight) =>
|
unlock: (delegateAddress, unlockObjects) =>
|
||||||
generateUnlockTransaction(
|
generateUnlockTransaction(
|
||||||
nonce,
|
nonce,
|
||||||
senderPublicKey,
|
senderPublicKey,
|
||||||
@@ -205,8 +205,7 @@ export const generateTransaction = (
|
|||||||
passPhrase,
|
passPhrase,
|
||||||
fee,
|
fee,
|
||||||
delegateAddress,
|
delegateAddress,
|
||||||
amount,
|
unlockObjects
|
||||||
unvoteHeight
|
|
||||||
),
|
),
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
@@ -379,8 +378,7 @@ const generateUnlockTransaction = (
|
|||||||
passPhrase = '',
|
passPhrase = '',
|
||||||
fee = BigInt(500000),
|
fee = BigInt(500000),
|
||||||
delegateAddress = '',
|
delegateAddress = '',
|
||||||
amount = 0n,
|
unlockObjects = []
|
||||||
unvoteHeight = 0
|
|
||||||
) => {
|
) => {
|
||||||
const tx = {
|
const tx = {
|
||||||
moduleID: 5,
|
moduleID: 5,
|
||||||
@@ -389,13 +387,11 @@ const generateUnlockTransaction = (
|
|||||||
senderPublicKey: Buffer.from(senderPublicKey, 'hex'),
|
senderPublicKey: Buffer.from(senderPublicKey, 'hex'),
|
||||||
fee,
|
fee,
|
||||||
asset: {
|
asset: {
|
||||||
unlockObjects: [
|
unlockObjects: unlockObjects.map((e) => ({
|
||||||
{
|
|
||||||
delegateAddress: Buffer.from(delegateAddress, 'hex'),
|
delegateAddress: Buffer.from(delegateAddress, 'hex'),
|
||||||
amount: amount * 100000000n,
|
amount: e.amount * 100000000n,
|
||||||
unvoteHeight,
|
unvoteHeight: e.unvoteHeight,
|
||||||
},
|
})),
|
||||||
],
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user