From 298129967e8c11748dee835a03022c2dc1963317 Mon Sep 17 00:00:00 2001 From: Juan M Date: Wed, 22 May 2024 01:26:59 -0300 Subject: [PATCH 1/3] Refactor events owners --- src/components/EventsOwners.js | 215 +++++++++++++++++++-------------- src/pages/Events.js | 37 ++++-- src/styles/events-owners.css | 11 +- 3 files changed, 151 insertions(+), 112 deletions(-) diff --git a/src/components/EventsOwners.js b/src/components/EventsOwners.js index c1d679e..f6ef520 100644 --- a/src/components/EventsOwners.js +++ b/src/components/EventsOwners.js @@ -3,10 +3,8 @@ import { useMemo, useState } from 'react' import { chunks } from 'utils/array' import { DropProps } from 'models/drop' import { - filterInCommon, getAddressInCommonAddresses, getAddressInCommonEventIds, - sortInCommonEntries, } from 'models/in-common' import ButtonLink from 'components/ButtonLink' import Card from 'components/Card' @@ -44,10 +42,9 @@ function inverseOwnersSortedEntries(owners) { * @param {PropTypes.InferProps} props */ function EventsOwners({ - children, - owners, - inCommon: initialInCommon = {}, - events = {}, + eventsOwners, + inCommon, + events, all = false, }) { /** @@ -55,122 +52,155 @@ function EventsOwners({ */ const [showAll, setShowAll] = useState(all) - let ownersEntries = useMemo( - () => inverseOwnersSortedEntries(owners), - [owners] + let ownersEvents = useMemo( + () => inverseOwnersSortedEntries(eventsOwners), + [eventsOwners] ) - const ownersEventIds = Object.keys(owners).map( - (rawEventId) => parseInt(rawEventId) + const eventIds = useMemo( + () => Object.keys(eventsOwners).map( + (rawEventId) => parseInt(rawEventId) + ), + [eventsOwners] ) - const eventsTotal = ownersEventIds.length - const ownersTotal = ownersEntries.length + const ownersTotal = ownersEvents.length + const eventsTotal = eventIds.length - /** - * @type {string[]} - */ - const inCommonAddresses = useMemo( + const inCommonOwnersTotal = useMemo( () => { const inCommonAddresses = [] - for (const [ownerAddress, ownerEventIds] of ownersEntries) { + for (const [ownerAddress, ownerEventIds] of ownersEvents) { if (ownerEventIds.length === eventsTotal) { inCommonAddresses.push(ownerAddress) } } - return inCommonAddresses + return inCommonAddresses.length }, - [ownersEntries, eventsTotal] + [ownersEvents, eventsTotal] ) - const inCommonOwnersTotal = inCommonAddresses.length - if (ownersTotal > inCommonOwnersTotal && !showAll && !all) { - ownersEntries = ownersEntries.slice(0, inCommonOwnersTotal) + ownersEvents = ownersEvents.slice(0, inCommonOwnersTotal) } - const ownersEntriesChunks = chunks(ownersEntries, 10) - - const inCommonEntries = useMemo( - () => initialInCommon == null ? [] : sortInCommonEntries( - Object - .entries(filterInCommon(initialInCommon)) - .map(([rawEventId, addresses]) => [parseInt(rawEventId), addresses]) - ), - [initialInCommon] - ) - - const inCommon = Object.fromEntries(inCommonEntries) + const ownersEventsChunks = chunks(ownersEvents, 10) return (
- {(all || showAll) &&

{ownersTotal} collector{ownersTotal === 1 ? '' : 's'}

} - {!all && !showAll &&

{inCommonOwnersTotal} collector{inCommonOwnersTotal === 1 ? '' : 's'} in common

} - {children} -
- {ownersEntriesChunks.map( - (ownersEntriesChunk, chunkIndex) => ( -
    - {ownersEntriesChunk.map( - ([address, eventIds]) => { - const inCommonEventIds = getAddressInCommonEventIds( - inCommon, - address - ) - const inCommonAddresses = getAddressInCommonAddresses( - inCommon, - inCommonEventIds, - address - ) - return ( -
  • - -
  • - ) - } - )} - {chunkIndex + 1 === ownersEntriesChunks.length && ownersTotal > inCommonOwnersTotal && !all && ( -
  • -
    - setShowAll((prevShowAll) => !prevShowAll)}> - {showAll ? (inCommonOwnersTotal === 0 ? 'hide all' : `show ${inCommonOwnersTotal}${all ? '' : ' in common'}`) : `show all ${ownersTotal}`} - -
    + {(all || showAll) && ( +

    {ownersTotal} collector{ownersTotal === 1 ? '' : 's'}

    + )} + {!all && !showAll && ( +

    + {inCommonOwnersTotal}{' '} + collector{inCommonOwnersTotal === 1 ? '' : 's'}{' '} + in common +

    + )} +
    + {ownersEventsChunks.map((ownersEventsChunk, chunkIndex) => ( +
      + {ownersEventsChunk.map(([owner, ownerEventIds]) => { + const inCommonEventIds = getAddressInCommonEventIds( + inCommon, + owner + ) + const inCommonAddresses = getAddressInCommonAddresses( + inCommon, + inCommonEventIds, + owner + ) + return ( +
    • +
    • - )} -
    - ) - )} + ) + })} + {( + chunkIndex + 1 === ownersEventsChunks.length && + ownersTotal > inCommonOwnersTotal && + !all + ) && ( +
  • +
    + setShowAll((prevShowAll) => !prevShowAll)} + > + { + showAll + ? ( + inCommonOwnersTotal === 0 + ? 'hide all' + : `show ${inCommonOwnersTotal}` + + `${all ? '' : ' in common'}` + ) + : `show all ${ownersTotal}` + } + +
    +
  • + )} +
+ ))}
- {inCommonOwnersTotal === 0 && ownersEntries.length === 0 && ( + {inCommonOwnersTotal === 0 && ownersEvents.length === 0 && (
- setShowAll((prevShowAll) => !prevShowAll)}> - {showAll ? (inCommonOwnersTotal === 0 ? 'hide all' : `show ${inCommonOwnersTotal}${all ? '' : ' in common'}`) : `show all ${ownersTotal}`} + setShowAll((prevShowAll) => !prevShowAll)} + > + { + showAll + ? ( + inCommonOwnersTotal === 0 + ? 'hide all' + : `show ${inCommonOwnersTotal}` + + `${all ? '' : ' in common'}` + ) + : `show all ${ownersTotal}` + }
)} - {ownersEntries.length > 0 && ( + {ownersEvents.length > 0 && ( address)} - title={`Generates CSV file with collectors in common between drop${Object.keys(events).length === 1 ? '' : 's'} #${Object.keys(events).join(', #')}`} + filename={ + `collectors-` + + `drop${eventsTotal === 1 ? '' : 's'}-` + + `${eventIds.join('+')}` + } + name={ + eventsTotal === 1 + ? events[eventIds[0]].name + : undefined + } + addresses={ownersEvents.map(([address]) => address)} + title={ + `Generates CSV file with collectors in common ` + + `between drop${eventsTotal === 1 ? '' : 's'} ` + + `#${eventIds.join(', #')}` + } /> ownerAddress)} - eventIds={ownersEventIds} + title={ + `Expands${showAll ? ' all' : ''} ` + + `collectors${showAll ? '' : ' in common'} between ` + + `drop${eventsTotal === 1 ? '' : 's'} ` + + `#${eventIds.join(', #')}` + } + addresses={ownersEvents.map(([ownerAddress]) => ownerAddress)} + eventIds={eventIds} /> )} @@ -180,8 +210,7 @@ function EventsOwners({ } EventsOwners.propTypes = { - children: PropTypes.node, - owners: PropTypes.objectOf( + eventsOwners: PropTypes.objectOf( PropTypes.arrayOf( PropTypes.string.isRequired ).isRequired @@ -190,7 +219,7 @@ EventsOwners.propTypes = { PropTypes.arrayOf( PropTypes.string.isRequired ).isRequired - ), + ).isRequired, events: PropTypes.objectOf( PropTypes.shape(DropProps).isRequired ).isRequired, diff --git a/src/pages/Events.js b/src/pages/Events.js index 5c64138..48687ab 100644 --- a/src/pages/Events.js +++ b/src/pages/Events.js @@ -1107,22 +1107,33 @@ function Events() { /** * @type {Record} */ - let inCommon = {} - if (status === STATUS_LOADING_COMPLETE) { - inCommon = mergeAllInCommon( - Object.values(eventData).map( - (oneEventData) => oneEventData?.inCommon ?? {} - ), - all - ) - } + const inCommon = useMemo( + () => { + if (status !== STATUS_LOADING_COMPLETE) { + return {} + } + return mergeAllInCommon( + Object.values(eventData).map( + (oneEventData) => oneEventData?.inCommon ?? {} + ), + all + ) + }, + [eventData, status, all] + ) /** * @type {Record} */ - const allEvents = Object.values(eventData).reduce( - (allEvents, data) => ({ ...allEvents, ...data.events }), - {} + const allEvents = useMemo( + () => Object.values(eventData).reduce( + (allEvents, data) => ({ + ...allEvents, + ...data.events, + }), + {} + ), + [eventData] ) const refreshCache = () => { @@ -1407,7 +1418,7 @@ function Events() { )} Date: Wed, 22 May 2024 01:31:16 -0300 Subject: [PATCH 2/3] Owners total --- src/components/EventsOwners.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/EventsOwners.js b/src/components/EventsOwners.js index f6ef520..2166f4d 100644 --- a/src/components/EventsOwners.js +++ b/src/components/EventsOwners.js @@ -153,7 +153,7 @@ function EventsOwners({ ))}
- {inCommonOwnersTotal === 0 && ownersEvents.length === 0 && ( + {inCommonOwnersTotal === 0 && ownersTotal === 0 && (
setShowAll((prevShowAll) => !prevShowAll)} @@ -171,7 +171,7 @@ function EventsOwners({
)} - {ownersEvents.length > 0 && ( + {ownersTotal > 0 && ( Date: Wed, 22 May 2024 01:31:34 -0300 Subject: [PATCH 3/3] Address owners CSS --- src/components/AddressOwner.js | 4 ++-- src/styles/{owner.css => address-owner.css} | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) rename src/styles/{owner.css => address-owner.css} (90%) diff --git a/src/components/AddressOwner.js b/src/components/AddressOwner.js index 88eaad0..544f090 100644 --- a/src/components/AddressOwner.js +++ b/src/components/AddressOwner.js @@ -5,7 +5,7 @@ import { DropProps } from 'models/drop' import TokenImage from 'components/TokenImage' import LinkToScan from 'components/LinkToScan' import ButtonAddressProfile from 'components/ButtonAddressProfile' -import 'styles/owner.css' +import 'styles/address-owner.css' /** * @param {PropTypes.InferProps} props @@ -30,7 +30,7 @@ function AddressOwner({ ) return ( -
+
{settings && settings.openProfiles ? ( diff --git a/src/styles/owner.css b/src/styles/address-owner.css similarity index 90% rename from src/styles/owner.css rename to src/styles/address-owner.css index 8d39d49..ad3e26b 100644 --- a/src/styles/owner.css +++ b/src/styles/address-owner.css @@ -1,21 +1,21 @@ -.owner { +.address-owner { display: flex; gap: .5rem; justify-content: space-between; } -.owner .owner-name { +.address-owner .owner-name { flex-grow: 1; width: 25.8rem; } -.owner-event-empty { +.address-owner .owner-event-empty { display: inline-block; width: 18px; height: 18px; } -.owner-scan { +.address-owner .owner-scan { width: 16px; height: 16px; background: @@ -32,7 +32,7 @@ cursor: pointer; } -.owner-scan:hover { +.address-owner .owner-scan:hover { background: linear-gradient(to right, #7d73e2 2px, transparent 2px) 0 0, linear-gradient(to right, #7d73e2 2px, transparent 2px) 0 100%,