This commit is contained in:
Sebastian 2022-11-18 11:29:24 -03:00
parent 6dc4fda73a
commit d8088e30da
No known key found for this signature in database
GPG Key ID: BE4FF68352439FC1
3 changed files with 138 additions and 98 deletions

View File

@ -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) {

View File

@ -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,

View File

@ -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>
// );
} }
/** /**
* *