fix #7394
This commit is contained in:
parent
6dc4fda73a
commit
d8088e30da
@ -93,93 +93,96 @@ export function createPairTimeline(
|
|||||||
left: FeeDescription[],
|
left: FeeDescription[],
|
||||||
right: FeeDescription[],
|
right: FeeDescription[],
|
||||||
): FeeDescriptionPair[] {
|
): FeeDescriptionPair[] {
|
||||||
|
//FIXME: we need to create a copy of the array because
|
||||||
|
//this algorithm is using splice, remove splice and
|
||||||
|
//remove this array duplication
|
||||||
|
left = [...left]
|
||||||
|
right = [...right]
|
||||||
|
|
||||||
//both list empty, discarded
|
//both list empty, discarded
|
||||||
if (left.length === 0 && right.length === 0) return [];
|
if (left.length === 0 && right.length === 0) return [];
|
||||||
|
|
||||||
const pairList: FeeDescriptionPair[] = [];
|
const pairList: FeeDescriptionPair[] = [];
|
||||||
|
|
||||||
let li = 0;
|
let li = 0; //left list index
|
||||||
let ri = 0;
|
let ri = 0; //right list index
|
||||||
|
|
||||||
while (li < left.length && ri < right.length) {
|
while (li < left.length && ri < right.length) {
|
||||||
const currentGroup =
|
const currentGroup = Number.parseFloat(left[li].group) < Number.parseFloat(right[ri].group) ? left[li].group : right[ri].group;
|
||||||
left[li].group < right[ri].group ? left[li].group : right[ri].group;
|
const lgs = li; //left group start index
|
||||||
|
const rgs = ri; //right group start index
|
||||||
|
|
||||||
let ll = 0; //left length (until next value)
|
let lgl = 0; //left group length (until next value)
|
||||||
while (li + ll < left.length && left[li + ll].group === currentGroup) {
|
while (li + lgl < left.length && left[li + lgl].group === currentGroup) {
|
||||||
ll++;
|
lgl++;
|
||||||
}
|
}
|
||||||
let rl = 0; //right length (until next value)
|
let rgl = 0; //right group length (until next value)
|
||||||
while (ri + rl < right.length && right[ri + rl].group === currentGroup) {
|
while (ri + rgl < right.length && right[ri + rgl].group === currentGroup) {
|
||||||
rl++;
|
rgl++;
|
||||||
}
|
}
|
||||||
const leftIsEmpty = ll === 0;
|
const leftGroupIsEmpty = lgl === 0;
|
||||||
const rightIsEmpty = rl === 0;
|
const rightGroupIsEmpty = rgl === 0;
|
||||||
//check which start after, add gap so both list starts at the same time
|
//check which start after, add gap so both list starts at the same time
|
||||||
// one list may be empty
|
// one list may be empty
|
||||||
const leftStarts: AbsoluteTime = leftIsEmpty
|
const leftStartTime: AbsoluteTime = leftGroupIsEmpty
|
||||||
? { t_ms: "never" }
|
? { t_ms: "never" }
|
||||||
: left[li].from;
|
: left[li].from;
|
||||||
const rightStarts: AbsoluteTime = rightIsEmpty
|
const rightStartTime: AbsoluteTime = rightGroupIsEmpty
|
||||||
? { t_ms: "never" }
|
? { t_ms: "never" }
|
||||||
: right[ri].from;
|
: right[ri].from;
|
||||||
|
|
||||||
//first time cut is the smallest time
|
//first time cut is the smallest time
|
||||||
let timeCut: AbsoluteTime = leftStarts;
|
let timeCut: AbsoluteTime = leftStartTime;
|
||||||
|
|
||||||
if (AbsoluteTime.cmp(leftStarts, rightStarts) < 0) {
|
if (AbsoluteTime.cmp(leftStartTime, rightStartTime) < 0) {
|
||||||
const ends = rightIsEmpty ? left[li + ll - 1].until : right[0].from;
|
const ends = rightGroupIsEmpty ? left[li + lgl - 1].until : right[0].from;
|
||||||
|
|
||||||
right.splice(ri, 0, {
|
right.splice(ri, 0, {
|
||||||
from: leftStarts,
|
from: leftStartTime,
|
||||||
until: ends,
|
until: ends,
|
||||||
group: left[li].group,
|
group: left[li].group,
|
||||||
});
|
});
|
||||||
rl++;
|
rgl++;
|
||||||
|
|
||||||
timeCut = leftStarts;
|
timeCut = leftStartTime;
|
||||||
}
|
}
|
||||||
if (AbsoluteTime.cmp(leftStarts, rightStarts) > 0) {
|
if (AbsoluteTime.cmp(leftStartTime, rightStartTime) > 0) {
|
||||||
const ends = leftIsEmpty ? right[ri + rl - 1].until : left[0].from;
|
const ends = leftGroupIsEmpty ? right[ri + rgl - 1].until : left[0].from;
|
||||||
|
|
||||||
left.splice(li, 0, {
|
left.splice(li, 0, {
|
||||||
from: rightStarts,
|
from: rightStartTime,
|
||||||
until: ends,
|
until: ends,
|
||||||
group: right[ri].group,
|
group: right[ri].group,
|
||||||
});
|
});
|
||||||
ll++;
|
lgl++;
|
||||||
|
|
||||||
timeCut = rightStarts;
|
timeCut = rightStartTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
//check which ends sooner, add gap so both list ends at the same time
|
//check which ends sooner, add gap so both list ends at the same time
|
||||||
// here both list are non empty
|
// here both list are non empty
|
||||||
const leftEnds: AbsoluteTime = left[li + ll - 1].until;
|
const leftEndTime: AbsoluteTime = left[li + lgl - 1].until;
|
||||||
const rightEnds: AbsoluteTime = right[ri + rl - 1].until;
|
const rightEndTime: AbsoluteTime = right[ri + rgl - 1].until;
|
||||||
|
|
||||||
if (AbsoluteTime.cmp(leftEnds, rightEnds) > 0) {
|
if (AbsoluteTime.cmp(leftEndTime, rightEndTime) > 0) {
|
||||||
right.splice(ri + rl, 0, {
|
right.splice(ri + rgl, 0, {
|
||||||
from: rightEnds,
|
from: rightEndTime,
|
||||||
until: leftEnds,
|
until: leftEndTime,
|
||||||
group: left[0].group,
|
group: left[0].group,
|
||||||
});
|
});
|
||||||
rl++;
|
rgl++;
|
||||||
}
|
}
|
||||||
if (AbsoluteTime.cmp(leftEnds, rightEnds) < 0) {
|
if (AbsoluteTime.cmp(leftEndTime, rightEndTime) < 0) {
|
||||||
left.splice(li + ll, 0, {
|
left.splice(li + lgl, 0, {
|
||||||
from: leftEnds,
|
from: leftEndTime,
|
||||||
until: rightEnds,
|
until: rightEndTime,
|
||||||
group: right[0].group,
|
group: right[0].group,
|
||||||
});
|
});
|
||||||
ll++;
|
lgl++;
|
||||||
}
|
}
|
||||||
|
|
||||||
//now both lists are non empty and (starts,ends) at the same time
|
//now both lists are non empty and (starts,ends) at the same time
|
||||||
while (
|
while (li < (lgs + lgl) && ri < (rgs + rgl)) {
|
||||||
li < left.length &&
|
|
||||||
ri < right.length &&
|
|
||||||
left[li].group === right[ri].group
|
|
||||||
) {
|
|
||||||
if (
|
if (
|
||||||
AbsoluteTime.cmp(left[li].from, timeCut) !== 0 &&
|
AbsoluteTime.cmp(left[li].from, timeCut) !== 0 &&
|
||||||
AbsoluteTime.cmp(right[ri].from, timeCut) !== 0
|
AbsoluteTime.cmp(right[ri].from, timeCut) !== 0
|
||||||
@ -215,22 +218,22 @@ export function createPairTimeline(
|
|||||||
}
|
}
|
||||||
pairList[pairList.length - 1].until = timeCut;
|
pairList[pairList.length - 1].until = timeCut;
|
||||||
|
|
||||||
if (
|
// if (
|
||||||
li < left.length &&
|
// (li < left.length && left[li].group !== currentGroup) ||
|
||||||
left[li].group !== pairList[pairList.length - 1].group
|
// (ri < right.length && right[ri].group !== currentGroup)
|
||||||
) {
|
// ) {
|
||||||
//value changed, should break
|
// //value changed, should break
|
||||||
//this if will catch when both (left and right) change at the same time
|
// //this if will catch when both (left and right) change at the same time
|
||||||
//if just one side changed it will catch in the while condition
|
// //if just one side changed it will catch in the while condition
|
||||||
break;
|
// break;
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//one of the list left or right can still have elements
|
//one of the list left or right can still have elements
|
||||||
if (li < left.length) {
|
if (li < left.length) {
|
||||||
let timeCut =
|
let timeCut =
|
||||||
pairList.length > 0 &&
|
pairList.length > 0 &&
|
||||||
pairList[pairList.length - 1].group === left[li].group
|
pairList[pairList.length - 1].group === left[li].group
|
||||||
? pairList[pairList.length - 1].until
|
? pairList[pairList.length - 1].until
|
||||||
: left[li].from;
|
: left[li].from;
|
||||||
while (li < left.length) {
|
while (li < left.length) {
|
||||||
@ -248,7 +251,7 @@ export function createPairTimeline(
|
|||||||
if (ri < right.length) {
|
if (ri < right.length) {
|
||||||
let timeCut =
|
let timeCut =
|
||||||
pairList.length > 0 &&
|
pairList.length > 0 &&
|
||||||
pairList[pairList.length - 1].group === right[ri].group
|
pairList[pairList.length - 1].group === right[ri].group
|
||||||
? pairList[pairList.length - 1].until
|
? pairList[pairList.length - 1].until
|
||||||
: right[ri].from;
|
: right[ri].from;
|
||||||
while (ri < right.length) {
|
while (ri < right.length) {
|
||||||
|
@ -38,30 +38,34 @@ export function useComponentState(
|
|||||||
}
|
}
|
||||||
const [value, setValue] = useState(String(initialValue));
|
const [value, setValue] = useState(String(initialValue));
|
||||||
|
|
||||||
|
const selectedIdx = parseInt(value, 10);
|
||||||
|
const selectedExchange =
|
||||||
|
exchanges.length == 0 ? undefined : exchanges[selectedIdx];
|
||||||
|
|
||||||
|
const comparingExchanges = selectedIdx !== initialValue;
|
||||||
|
|
||||||
|
const initialExchange =
|
||||||
|
comparingExchanges ? exchanges[initialValue] : undefined;
|
||||||
|
|
||||||
const hook = useAsyncAsHook(async () => {
|
const hook = useAsyncAsHook(async () => {
|
||||||
const selectedIdx = parseInt(value, 10);
|
|
||||||
const selectedExchange =
|
|
||||||
exchanges.length == 0 ? undefined : exchanges[selectedIdx];
|
|
||||||
const selected = !selectedExchange
|
const selected = !selectedExchange
|
||||||
? undefined
|
? undefined
|
||||||
: await api.wallet.call(WalletApiOperation.GetExchangeDetailedInfo, {
|
: await api.wallet.call(WalletApiOperation.GetExchangeDetailedInfo, {
|
||||||
exchangeBaseUrl: selectedExchange.exchangeBaseUrl,
|
exchangeBaseUrl: selectedExchange.exchangeBaseUrl,
|
||||||
});
|
});
|
||||||
|
|
||||||
const initialExchange =
|
|
||||||
selectedIdx === initialValue ? undefined : exchanges[initialValue];
|
|
||||||
const original = !initialExchange
|
const original = !initialExchange
|
||||||
? undefined
|
? undefined
|
||||||
: await api.wallet.call(WalletApiOperation.GetExchangeDetailedInfo, {
|
: await api.wallet.call(WalletApiOperation.GetExchangeDetailedInfo, {
|
||||||
exchangeBaseUrl: initialExchange.exchangeBaseUrl,
|
exchangeBaseUrl: initialExchange.exchangeBaseUrl,
|
||||||
});
|
});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
exchanges,
|
exchanges,
|
||||||
selected: selected?.exchange,
|
selected: selected?.exchange,
|
||||||
original: original?.exchange,
|
original: original?.exchange,
|
||||||
};
|
};
|
||||||
}, [value]);
|
}, [selectedExchange, initialExchange]);
|
||||||
|
|
||||||
const [showingTos, setShowingTos] = useState<string | undefined>(undefined);
|
const [showingTos, setShowingTos] = useState<string | undefined>(undefined);
|
||||||
const [showingPrivacy, setShowingPrivacy] = useState<string | undefined>(
|
const [showingPrivacy, setShowingPrivacy] = useState<string | undefined>(
|
||||||
@ -83,8 +87,7 @@ export function useComponentState(
|
|||||||
|
|
||||||
const { selected, original } = hook.response;
|
const { selected, original } = hook.response;
|
||||||
|
|
||||||
if (!selected) {
|
if (selectedExchange === undefined || !selected) {
|
||||||
//!selected <=> exchanges.length === 0
|
|
||||||
return {
|
return {
|
||||||
status: "no-exchange",
|
status: "no-exchange",
|
||||||
error: undefined,
|
error: undefined,
|
||||||
@ -118,7 +121,7 @@ export function useComponentState(
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!original) {
|
if (!comparingExchanges || !original) {
|
||||||
// !original <=> selected == original
|
// !original <=> selected == original
|
||||||
return {
|
return {
|
||||||
status: "ready",
|
status: "ready",
|
||||||
@ -147,6 +150,7 @@ export function useComponentState(
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//this may be expensive, useMemo
|
||||||
const pairTimeline: DenomOperationMap<FeeDescription[]> = {
|
const pairTimeline: DenomOperationMap<FeeDescription[]> = {
|
||||||
deposit: createPairTimeline(
|
deposit: createPairTimeline(
|
||||||
selected.denomFees.deposit,
|
selected.denomFees.deposit,
|
||||||
|
@ -262,7 +262,10 @@ export function ComparingView({
|
|||||||
<i18n.Translate>Denomination</i18n.Translate>
|
<i18n.Translate>Denomination</i18n.Translate>
|
||||||
</th>
|
</th>
|
||||||
<th class="fee">
|
<th class="fee">
|
||||||
<i18n.Translate>Fee</i18n.Translate>
|
<i18n.Translate>Current</i18n.Translate>
|
||||||
|
</th>
|
||||||
|
<th class="fee">
|
||||||
|
<i18n.Translate>Selected</i18n.Translate>
|
||||||
</th>
|
</th>
|
||||||
<th>
|
<th>
|
||||||
<i18n.Translate>Until</i18n.Translate>
|
<i18n.Translate>Until</i18n.Translate>
|
||||||
@ -270,7 +273,10 @@ export function ComparingView({
|
|||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
<RenderFeePairByValue list={pairTimeline.deposit} />
|
<RenderFeePairByValue
|
||||||
|
list={pairTimeline.deposit}
|
||||||
|
sorting={(a, b) => Number(a) - Number(b)}
|
||||||
|
/>
|
||||||
</tbody>
|
</tbody>
|
||||||
</FeeDescriptionTable>
|
</FeeDescriptionTable>
|
||||||
<p>
|
<p>
|
||||||
@ -292,7 +298,10 @@ export function ComparingView({
|
|||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
<RenderFeePairByValue list={pairTimeline.withdraw} />
|
<RenderFeePairByValue
|
||||||
|
list={pairTimeline.withdraw}
|
||||||
|
sorting={(a, b) => Number(a) - Number(b)}
|
||||||
|
/>
|
||||||
</tbody>
|
</tbody>
|
||||||
</FeeDescriptionTable>
|
</FeeDescriptionTable>
|
||||||
<p>
|
<p>
|
||||||
@ -314,7 +323,10 @@ export function ComparingView({
|
|||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
<RenderFeePairByValue list={pairTimeline.refund} />
|
<RenderFeePairByValue
|
||||||
|
list={pairTimeline.refund}
|
||||||
|
sorting={(a, b) => Number(a) - Number(b)}
|
||||||
|
/>
|
||||||
</tbody>
|
</tbody>
|
||||||
</FeeDescriptionTable>{" "}
|
</FeeDescriptionTable>{" "}
|
||||||
<p>
|
<p>
|
||||||
@ -336,7 +348,10 @@ export function ComparingView({
|
|||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
<RenderFeePairByValue list={pairTimeline.refresh} />
|
<RenderFeePairByValue
|
||||||
|
list={pairTimeline.refresh}
|
||||||
|
sorting={(a, b) => Number(a) - Number(b)}
|
||||||
|
/>
|
||||||
</tbody>
|
</tbody>
|
||||||
</FeeDescriptionTable>{" "}
|
</FeeDescriptionTable>{" "}
|
||||||
</section>
|
</section>
|
||||||
@ -689,7 +704,7 @@ function FeePairRowsGroup({ infos }: { infos: FeeDescriptionPair[] }): VNode {
|
|||||||
<td class="icon">
|
<td class="icon">
|
||||||
{hasMoreInfo && main ? (
|
{hasMoreInfo && main ? (
|
||||||
<SvgIcon
|
<SvgIcon
|
||||||
title="Select this contact"
|
title="Expand"
|
||||||
dangerouslySetInnerHTML={{ __html: arrowDown }}
|
dangerouslySetInnerHTML={{ __html: arrowDown }}
|
||||||
color="currentColor"
|
color="currentColor"
|
||||||
transform={expanded ? "" : "rotate(-90deg)"}
|
transform={expanded ? "" : "rotate(-90deg)"}
|
||||||
@ -708,7 +723,7 @@ function FeePairRowsGroup({ infos }: { infos: FeeDescriptionPair[] }): VNode {
|
|||||||
<td class="fee"> --- </td>
|
<td class="fee"> --- </td>
|
||||||
)}
|
)}
|
||||||
<td class="expiration">
|
<td class="expiration">
|
||||||
<Time timestamp={info.until} format="dd-MMM-yyyy" />
|
<Time timestamp={info.until} format="dd-MMM-yyyy HH:mm:ss" />
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
);
|
);
|
||||||
@ -722,35 +737,53 @@ function FeePairRowsGroup({ infos }: { infos: FeeDescriptionPair[] }): VNode {
|
|||||||
* @param param0
|
* @param param0
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
function RenderFeePairByValue({ list }: { list: FeeDescriptionPair[] }): VNode {
|
function RenderFeePairByValue({
|
||||||
return (
|
list,
|
||||||
<Fragment>
|
sorting,
|
||||||
{
|
}: {
|
||||||
list.reduce(
|
list: FeeDescriptionPair[];
|
||||||
(prev, info, idx) => {
|
sorting?: (a: string, b: string) => number;
|
||||||
const next = idx >= list.length - 1 ? undefined : list[idx + 1];
|
}): VNode {
|
||||||
|
const grouped = list.reduce((prev, cur) => {
|
||||||
|
if (!prev[cur.group]) {
|
||||||
|
prev[cur.group] = [];
|
||||||
|
}
|
||||||
|
prev[cur.group].push(cur);
|
||||||
|
return prev;
|
||||||
|
}, {} as Record<string, FeeDescriptionPair[]>);
|
||||||
|
const p = Object.keys(grouped)
|
||||||
|
.sort(sorting)
|
||||||
|
.map((i, idx) => <FeePairRowsGroup key={idx} infos={grouped[i]} />);
|
||||||
|
return <Fragment>{p}</Fragment>;
|
||||||
|
|
||||||
const nextIsMoreInfo =
|
// return (
|
||||||
next !== undefined && next.group === info.group;
|
// <Fragment>
|
||||||
|
// {
|
||||||
|
// list.reduce(
|
||||||
|
// (prev, info, idx) => {
|
||||||
|
// const next = idx >= list.length - 1 ? undefined : list[idx + 1];
|
||||||
|
|
||||||
prev.rows.push(info);
|
// const nextIsMoreInfo =
|
||||||
|
// next !== undefined && next.group === info.group;
|
||||||
|
|
||||||
if (nextIsMoreInfo) {
|
// prev.rows.push(info);
|
||||||
return prev;
|
|
||||||
}
|
|
||||||
|
|
||||||
// prev.rows = [];
|
// if (nextIsMoreInfo) {
|
||||||
prev.views.push(<FeePairRowsGroup infos={prev.rows} />);
|
// return prev;
|
||||||
return prev;
|
// }
|
||||||
},
|
|
||||||
{ rows: [], views: [] } as {
|
// // prev.rows = [];
|
||||||
rows: FeeDescriptionPair[];
|
// prev.views.push(<FeePairRowsGroup infos={prev.rows} />);
|
||||||
views: h.JSX.Element[];
|
// return prev;
|
||||||
},
|
// },
|
||||||
).views
|
// { rows: [], views: [] } as {
|
||||||
}
|
// rows: FeeDescriptionPair[];
|
||||||
</Fragment>
|
// views: h.JSX.Element[];
|
||||||
);
|
// },
|
||||||
|
// ).views
|
||||||
|
// }
|
||||||
|
// </Fragment>
|
||||||
|
// );
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
Loading…
Reference in New Issue
Block a user