diff --git a/src/app/@api/space.api.ts b/src/app/@api/space.api.ts index e44f662..ec5ab34 100644 --- a/src/app/@api/space.api.ts +++ b/src/app/@api/space.api.ts @@ -61,6 +61,17 @@ export class SpaceApi extends BaseApi { public getMembersWithoutData = (spaceId: string, lastValue?: string) => this.spaceMemberRepo.getAll(spaceId, lastValue); + public getAllMembersWithoutData = async (spaceId: string) => { + const members: SpaceMember[] = []; + let actMembers: SpaceMember[] = []; + do { + const last = members[members.length - 1]?.uid; + actMembers = await this.getMembersWithoutData(spaceId, last); + members.push(...actMembers); + } while (members.length === QUERY_MAX_LENGTH); + return members; + }; + public listenMembers = (spaceId: string, lastValue?: string) => this.spaceMemberRepo.getAllLive(spaceId, lastValue).pipe(switchMap(this.getMembers)); diff --git a/src/app/@api/token.api.ts b/src/app/@api/token.api.ts index f0b31de..3dd5b05 100644 --- a/src/app/@api/token.api.ts +++ b/src/app/@api/token.api.ts @@ -2,6 +2,7 @@ import { HttpClient } from '@angular/common/http'; import { Injectable } from '@angular/core'; import { PublicCollections, + QUERY_MAX_LENGTH, Token, TokenDistribution, Transaction, @@ -73,12 +74,22 @@ export class TokenApi extends BaseApi { return this.tokenDistributionRepo.getByIdLive(tokenId.toLowerCase(), memberId.toLowerCase()); } - public getDistributions(tokenId?: string): Observable { + public getDistributionsLive = (tokenId?: string, lastValue?: string) => + tokenId ? this.tokenDistributionRepo.getAllLive(tokenId.toLowerCase(), lastValue) : of([]); + + public getAllDistributions = async (tokenId?: string) => { if (!tokenId) { - return of(undefined); + return []; } - return this.tokenDistributionRepo.getAllLive(tokenId.toLowerCase()); - } + const distributions: TokenDistribution[] = []; + let actDistributions: TokenDistribution[] = []; + do { + const last = distributions[distributions.length - 1]?.uid; + actDistributions = await this.tokenDistributionRepo.getAll(tokenId.toLowerCase(), last); + distributions.push(...actDistributions); + } while (actDistributions.length === QUERY_MAX_LENGTH); + return distributions; + }; public stats(tokenId: string) { if (!tokenId) { diff --git a/src/app/components/token/components/token-info/token-info-description.component.ts b/src/app/components/token/components/token-info/token-info-description.component.ts index 84d627a..b038b96 100644 --- a/src/app/components/token/components/token-info/token-info-description.component.ts +++ b/src/app/components/token/components/token-info/token-info-description.component.ts @@ -7,7 +7,7 @@ import { download } from '@core/utils/tools.utils'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; import { DataService } from '@pages/token/services/data.service'; import { HelperService } from '@pages/token/services/helper.service'; -import { Token } from '@build-5/interfaces'; +import { QUERY_MAX_LENGTH, Token, TokenDistribution } from '@build-5/interfaces'; import Papa from 'papaparse'; import { debounceTime } from 'rxjs'; @@ -46,46 +46,43 @@ export class TokenInfoDescriptionComponent { return DescriptionItemType; } - public downloadCurrentDistribution(): void { - this.tokenApi - .getDistributions(this.token?.uid) - .pipe(debounceTime(2500), untilDestroyed(this)) - .subscribe((distributions) => { - const fields = [ - '', - 'ethAddress', - 'tokenOwned', - 'unclaimedTokens', - 'tokenClaimed', - 'lockedForSale', - 'sold', - 'totalBought', - 'refundedAmount', - 'totalPaid', - 'totalDeposit', - ]; - const csv = Papa.unparse({ - fields, - data: - distributions?.map((d) => [ - d.uid, - d.tokenOwned, - d.totalUnclaimedAirdrop || 0, - d.tokenClaimed, - d.lockedForSale, - d.sold, - d.totalBought, - d.refundedAmount, - d.totalPaid, - d.totalDeposit, - ]) || [], - }); + public async downloadCurrentDistribution(): Promise { + const distributions = await this.tokenApi.getAllDistributions(this.token?.uid); + const fields = [ + '', + 'ethAddress', + 'tokenOwned', + 'unclaimedTokens', + 'tokenClaimed', + 'lockedForSale', + 'sold', + 'totalBought', + 'refundedAmount', + 'totalPaid', + 'totalDeposit', + ]; - download( - `data:text/csv;charset=utf-8${csv}`, - `soonaverse_${this.token?.symbol}_distribution.csv`, - ); - this.cd.markForCheck(); - }); + const csv = Papa.unparse({ + fields, + data: + distributions?.map((d) => [ + d.uid, + d.tokenOwned, + d.totalUnclaimedAirdrop || 0, + d.tokenClaimed, + d.lockedForSale, + d.sold, + d.totalBought, + d.refundedAmount, + d.totalPaid, + d.totalDeposit, + ]) || [], + }); + + download( + `data:text/csv;charset=utf-8${csv}`, + `soonaverse_${this.token?.symbol}_distribution.csv`, + ); + this.cd.markForCheck(); } } diff --git a/src/app/pages/space/pages/space/space-about/space-about.component.ts b/src/app/pages/space/pages/space/space-about/space-about.component.ts index 3fc1745..28c8e3f 100644 --- a/src/app/pages/space/pages/space/space-about/space-about.component.ts +++ b/src/app/pages/space/pages/space/space-about/space-about.component.ts @@ -135,24 +135,16 @@ export class SpaceAboutComponent implements OnInit, OnDestroy { } this.exportingMembers = true; - const data: string[][] = []; - let members: SpaceMember[] = []; - do { - const last = data[data.length - 1]?.[0]; - members = await this.spaceApi.getMembersWithoutData(space.uid, last); - data.push(...members.map((m) => [m.uid])); - if (members.length < QUERY_MAX_LENGTH) { - break; - } - } while (members.length); + const members = await this.spaceApi.getAllMembersWithoutData(space.uid); - this.exportingMembers = false; const fields = ['', 'address']; - const csv = Papa.unparse({ fields, data }); + const csv = Papa.unparse({ fields, data: members.map((m) => [m.uid]) }); const filteredSpaceName = space?.name?.toLowerCase().replace(/[^a-zA-Z0-9-_]/g, ''); download(`data:text/csv;charset=utf-8${csv}`, `soonaverse_${filteredSpaceName}_members.csv`); this.cd.markForCheck(); + + this.exportingMembers = false; } public isSoonSpace(): Observable { diff --git a/src/app/pages/space/pages/space/space.page.ts b/src/app/pages/space/pages/space/space.page.ts index 48738d1..e5fe445 100644 --- a/src/app/pages/space/pages/space/space.page.ts +++ b/src/app/pages/space/pages/space/space.page.ts @@ -24,10 +24,9 @@ import { SOON_SPACE_TEST, Space, StakeType, - TokenDistribution, } from '@build-5/interfaces'; import Papa from 'papaparse'; -import { BehaviorSubject, combineLatest, debounceTime, map, Observable, skip } from 'rxjs'; +import { BehaviorSubject, combineLatest, map, Observable, skip } from 'rxjs'; import { SpaceApi } from './../../../../@api/space.api'; import { NavigationService } from './../../../../@core/services/navigation/navigation.service'; import { NotificationService } from './../../../../@core/services/notification/notification.service'; @@ -147,46 +146,39 @@ export class SpacePage implements OnInit, OnDestroy { ); } - public exportCurrentStakers(token: string): void { - // In progress. + public async exportCurrentStakers(token: string): Promise { if (this.exportingCurrentStakers) { return; } this.exportingCurrentStakers = true; - this.tokenApi - .getDistributions(token) - .pipe(debounceTime(2500), untilDestroyed(this)) - .subscribe((transactions: TokenDistribution[] | undefined) => { - if (!transactions) { - return; - } + const distributions = await this.tokenApi.getAllDistributions(token); - this.exportingCurrentStakers = false; - const fields = [ - '', - 'memberId', - 'tokenStakedDynamic', - 'tokenStakedStatic', - 'stakedValueDynamic', - 'stakedValueStatic', - 'totalStakeRewards', - ]; - const csv = Papa.unparse({ - fields, - data: transactions.map((t) => [ - t.uid, - t.stakes?.[StakeType.DYNAMIC]?.amount || 0, - t.stakes?.[StakeType.STATIC]?.amount || 0, - t.stakes?.[StakeType.DYNAMIC]?.value || 0, - t.stakes?.[StakeType.STATIC]?.value || 0, - t.stakeRewards || 0, - ]), - }); + const fields = [ + '', + 'memberId', + 'tokenStakedDynamic', + 'tokenStakedStatic', + 'stakedValueDynamic', + 'stakedValueStatic', + 'totalStakeRewards', + ]; + const csv = Papa.unparse({ + fields, + data: distributions.map((t) => [ + t.uid, + t.stakes?.[StakeType.DYNAMIC]?.amount || 0, + t.stakes?.[StakeType.STATIC]?.amount || 0, + t.stakes?.[StakeType.DYNAMIC]?.value || 0, + t.stakes?.[StakeType.STATIC]?.value || 0, + t.stakeRewards || 0, + ]), + }); - download(`data:text/csv;charset=utf-8${csv}`, `soonaverse_${token}_stakers.csv`); - this.cd.markForCheck(); - }); + download(`data:text/csv;charset=utf-8${csv}`, `soonaverse_${token}_stakers.csv`); + this.cd.markForCheck(); + + this.exportingCurrentStakers = false; } public get bannerUrl$(): Observable { diff --git a/src/app/pages/token/pages/token/token.page.ts b/src/app/pages/token/pages/token/token.page.ts index 52facd6..32ba089 100644 --- a/src/app/pages/token/pages/token/token.page.ts +++ b/src/app/pages/token/pages/token/token.page.ts @@ -106,7 +106,7 @@ export class TokenPage implements OnInit, OnDestroy { ); this.subscriptions$.push( this.tokenApi - .getDistributions(t.uid) + .getDistributionsLive(t.uid) .pipe(debounceTime(2500), untilDestroyed(this)) .subscribe(this.data.distributions$), );