diff --git a/src/app/@api/nft.api.ts b/src/app/@api/nft.api.ts index 5ce2dcb..a228a40 100644 --- a/src/app/@api/nft.api.ts +++ b/src/app/@api/nft.api.ts @@ -67,8 +67,9 @@ export class NftApi extends BaseApi { return this.listen(nftId); } - public transferNft = (req: Build5Request): Observable<{ [key: string]: number } | undefined> => - this.request(WEN_FUNC.nftTransfer, req); + public transferNft = ( + req: Build5Request, + ): Observable<{ [key: string]: number } | undefined> => this.request(WEN_FUNC.nftTransfer, req); public successfullOrders( nftId: string, diff --git a/src/app/@core/services/build5-error-lookup/build5-error-lookup.service.ts b/src/app/@core/services/build5-error-lookup/build5-error-lookup.service.ts index b0f4611..0827f3b 100644 --- a/src/app/@core/services/build5-error-lookup/build5-error-lookup.service.ts +++ b/src/app/@core/services/build5-error-lookup/build5-error-lookup.service.ts @@ -1,16 +1,20 @@ import { Injectable } from '@angular/core'; import { WenError } from '@build-5/interfaces'; +import { AuthService } from '@components/auth/services/auth.service'; @Injectable({ - providedIn: 'root' + providedIn: 'root', }) export class Build5ErrorLookupService { + constructor( + public auth: AuthService, + ) { - constructor() { } + } public getErrorMessage(errorCode: number): string { // Convert WenError object to an array and find the entry by error code - const errorEntry = Object.values(WenError).find(entry => entry.code === errorCode); + const errorEntry = Object.values(WenError).find((entry) => entry.code === errorCode); return errorEntry ? errorEntry.key : 'Unknown error'; } } diff --git a/src/app/@core/services/nft-selection/nft-selection.service.ts b/src/app/@core/services/nft-selection/nft-selection.service.ts index fe2a560..ae7eff3 100644 --- a/src/app/@core/services/nft-selection/nft-selection.service.ts +++ b/src/app/@core/services/nft-selection/nft-selection.service.ts @@ -2,7 +2,7 @@ import { Injectable } from '@angular/core'; import { BehaviorSubject, Subject } from 'rxjs'; @Injectable({ - providedIn: 'root' + providedIn: 'root', }) export class NftSelectionService { private selectedNftIdsSubject = new BehaviorSubject([]); @@ -18,7 +18,9 @@ export class NftSelectionService { } public deselectNft(nftId: string) { - const updatedSelectedNftIds = this.selectedNftIdsSubject.getValue().filter(id => id !== nftId); + const updatedSelectedNftIds = this.selectedNftIdsSubject + .getValue() + .filter((id) => id !== nftId); this.selectedNftIdsSubject.next(updatedSelectedNftIds); } diff --git a/src/app/@shell/ui/footer/footer.component.ts b/src/app/@shell/ui/footer/footer.component.ts index f4f799c..54fe8dd 100644 --- a/src/app/@shell/ui/footer/footer.component.ts +++ b/src/app/@shell/ui/footer/footer.component.ts @@ -1,4 +1,5 @@ import { ChangeDetectionStrategy, Component } from '@angular/core'; +import { AuthService } from '@components/auth/services/auth.service'; @Component({ selector: 'wen-footer', @@ -8,5 +9,9 @@ import { ChangeDetectionStrategy, Component } from '@angular/core'; }) export class FooterComponent { // No need to inject NftSelectionService or maintain selectedCount$ - constructor() { } + constructor( + public auth: AuthService, + ) { + + } } diff --git a/src/app/@shell/ui/footer/footer.module.ts b/src/app/@shell/ui/footer/footer.module.ts index aee079f..72e507e 100644 --- a/src/app/@shell/ui/footer/footer.module.ts +++ b/src/app/@shell/ui/footer/footer.module.ts @@ -5,10 +5,7 @@ import { NftSelectionToolbarModule } from '@components/nft/components/nft-select @NgModule({ declarations: [FooterComponent], - imports: [ - CommonModule, - NftSelectionToolbarModule, - ], + imports: [CommonModule, NftSelectionToolbarModule], exports: [FooterComponent], }) export class FooterModule {} diff --git a/src/app/components/nft/components/nft-card/nft-card.component.html b/src/app/components/nft/components/nft-card/nft-card.component.html index fb26351..a5a2c4c 100644 --- a/src/app/components/nft/components/nft-card/nft-card.component.html +++ b/src/app/components/nft/components/nft-card/nft-card.component.html @@ -53,19 +53,45 @@ {{ getBadgeProperties().label }} -
-
-
-
- +
+
+
- +
diff --git a/src/app/components/nft/components/nft-card/nft-card.component.ts b/src/app/components/nft/components/nft-card/nft-card.component.ts index a61940f..101cdb6 100644 --- a/src/app/components/nft/components/nft-card/nft-card.component.ts +++ b/src/app/components/nft/components/nft-card/nft-card.component.ts @@ -1,4 +1,14 @@ -import { ChangeDetectionStrategy, ChangeDetectorRef, Component, EventEmitter, Input, OnDestroy, OnInit, Output, SimpleChanges } from '@angular/core'; +import { + ChangeDetectionStrategy, + ChangeDetectorRef, + Component, + EventEmitter, + Input, + OnDestroy, + OnInit, + Output, + SimpleChanges, +} from '@angular/core'; import { Router } from '@angular/router'; import { FileApi } from '@api/file.api'; import { MemberApi } from '@api/member.api'; @@ -22,8 +32,7 @@ import { NftAccess, } from '@build-5/interfaces'; import { BehaviorSubject, Subscription, combineLatest, map, startWith, take } from 'rxjs'; -import { NftSelectionService } from '@core/services/nft-selection/nft-selection.service' - +import { NftSelectionService } from '@core/services/nft-selection/nft-selection.service'; @UntilDestroy() @Component({ @@ -70,15 +79,12 @@ export class NftCardComponent implements OnInit, OnDestroy { @Input() collection?: Collection | null; - //@Input() nftSelectable: boolean = false; - public nftSelectable: boolean = false; - //public showCheckbox: boolean = false; + public nftSelectable = false; @Output() selectionChange = new EventEmitter(); - public nftSelected: boolean = false; + public nftSelected = false; private nftSelectionSubscription$: Subscription = new Subscription(); public mediaType: 'video' | 'image' | undefined; - //public isCheckoutOpen = false; public isBidOpen = false; public path = ROUTER_UTILS.config.nft.root; public owner$: BehaviorSubject = new BehaviorSubject( @@ -103,26 +109,22 @@ export class NftCardComponent implements OnInit, OnDestroy { ngOnInit(): void { this.nftSelectionSubscription$.add( - this.nftSelectionService.selectedNftIds$ - .subscribe(selectedIds => { - this.nftSelected = selectedIds.includes(this.nft?.uid || ''); - this.cd.markForCheck(); - }) + this.nftSelectionService.selectedNftIds$.subscribe((selectedIds) => { + this.nftSelected = selectedIds.includes(this.nft?.uid || ''); + this.cd.markForCheck(); + }), ); - const nftSelectableSub = combineLatest([ - this.owner$, - this.auth.member$.pipe(startWith(null)) - ]) - .pipe( - map(([owner, member]) => { - return owner !== null && member !== null && owner?.uid === member?.uid; - }) - ) - .subscribe(isOwner => { - this.nftSelectable = isOwner && this.nft?.locked === false; - this.cd.markForCheck(); // Trigger change detection - }); + const nftSelectableSub = combineLatest([this.owner$, this.auth.member$.pipe(startWith(null))]) + .pipe( + map(([owner, member]) => { + return owner !== null && member !== null && owner?.uid === member?.uid; + }), + ) + .subscribe((isOwner) => { + this.nftSelectable = isOwner && this.nft?.locked === false; + this.cd.markForCheck(); // Trigger change detection + }); this.nftSelectionSubscription$.add(nftSelectableSub); } @@ -221,20 +223,19 @@ export class NftCardComponent implements OnInit, OnDestroy { public toggleNftSelection(isChecked: boolean, event?: Event): void { if (event) { - event.stopPropagation(); + event.stopPropagation(); } this.nftSelected = isChecked; const action = isChecked ? 'select' : 'deselect'; if (action === 'select') { - this.nftSelectionService.selectNft(this.nft?.uid || ''); + this.nftSelectionService.selectNft(this.nft?.uid || ''); } else { - this.nftSelectionService.deselectNft(this.nft?.uid || ''); + this.nftSelectionService.deselectNft(this.nft?.uid || ''); } this.cd.markForCheck(); -} - + } ngOnDestroy() { if (this.nftSelectionSubscription$) { diff --git a/src/app/components/nft/components/nft-selection-toolbar/nft-selection-toolbar.component.html b/src/app/components/nft/components/nft-selection-toolbar/nft-selection-toolbar.component.html index 1eebd53..efbad03 100644 --- a/src/app/components/nft/components/nft-selection-toolbar/nft-selection-toolbar.component.html +++ b/src/app/components/nft/components/nft-selection-toolbar/nft-selection-toolbar.component.html @@ -1,7 +1,11 @@ -
+
- {{selectedCount}} item(s) selected + {{ selectedCount }} item(s) selected
diff --git a/src/app/components/nft/components/nft-selection-toolbar/nft-selection-toolbar.component.less b/src/app/components/nft/components/nft-selection-toolbar/nft-selection-toolbar.component.less index c2d69b8..7e13e90 100644 --- a/src/app/components/nft/components/nft-selection-toolbar/nft-selection-toolbar.component.less +++ b/src/app/components/nft/components/nft-selection-toolbar/nft-selection-toolbar.component.less @@ -22,7 +22,7 @@ user-select: none; } -.checkbox-custom input[type="checkbox"] { +.checkbox-custom input[type='checkbox'] { visibility: hidden; /* Hide the default checkbox */ position: absolute; } @@ -36,17 +36,17 @@ background-color: #eee; /* Checkbox background */ } -.checkbox-custom input[type="checkbox"]:checked ~ .checkmark { - background-color: #2196F3; /* Checked state */ +.checkbox-custom input[type='checkbox']:checked ~ .checkmark { + background-color: #2196f3; /* Checked state */ } .checkbox-custom .checkmark:after { - content: ""; + content: ''; position: absolute; display: none; } -.checkbox-custom input[type="checkbox"]:checked ~ .checkmark:after { +.checkbox-custom input[type='checkbox']:checked ~ .checkmark:after { display: block; } diff --git a/src/app/components/nft/components/nft-selection-toolbar/nft-selection-toolbar.component.ts b/src/app/components/nft/components/nft-selection-toolbar/nft-selection-toolbar.component.ts index 8ebdf2b..f21dcfc 100644 --- a/src/app/components/nft/components/nft-selection-toolbar/nft-selection-toolbar.component.ts +++ b/src/app/components/nft/components/nft-selection-toolbar/nft-selection-toolbar.component.ts @@ -4,7 +4,7 @@ import { trigger, state, style, transition, animate } from '@angular/animations' import { Observable } from 'rxjs'; import { map } from 'rxjs/operators'; import { NzModalRef, NzModalService } from 'ng-zorro-antd/modal'; -import { TransferModalComponent } from '@components/nft/components/nft-transfer/nft-transfer.component' +import { TransferModalComponent } from '@components/nft/components/nft-transfer/nft-transfer.component'; @Component({ selector: 'wen-nft-selection-toolbar', @@ -14,11 +14,9 @@ import { TransferModalComponent } from '@components/nft/components/nft-transfer/ trigger('slideFromBottom', [ transition(':enter', [ style({ transform: 'translateY(100%)' }), - animate('300ms ease-out', style({ transform: 'translateY(0)' })) + animate('300ms ease-out', style({ transform: 'translateY(0)' })), ]), - transition(':leave', [ - animate('300ms ease-in', style({ transform: 'translateY(100%)' })) - ]) + transition(':leave', [animate('300ms ease-in', style({ transform: 'translateY(100%)' }))]), ]), ], changeDetection: ChangeDetectionStrategy.OnPush, @@ -33,9 +31,7 @@ export class NftSelectionToolbarComponent implements OnInit { ngOnInit(): void { // Observable for the count of selected NFTs remains the same - this.selectedCount$ = this.nftSelectionService.selectedNftIds$.pipe( - map(ids => ids.length) - ); + this.selectedCount$ = this.nftSelectionService.selectedNftIds$.pipe(map((ids) => ids.length)); } public clearSelection() { @@ -49,19 +45,15 @@ export class NftSelectionToolbarComponent implements OnInit { nzClassName: 'nft-transfer-modal', nzFooter: null, nzWidth: '75%', - nzComponentParams: { - - }, - nzOnOk: () => new Promise(resolve => setTimeout(resolve, 1000)), + nzComponentParams: {}, + nzOnOk: () => new Promise((resolve) => setTimeout(resolve, 1000)), nzOnCancel: () => console.log('Cancel transfer'), }); - modal.afterClose.subscribe(result => { + modal.afterClose.subscribe((result) => { const componentInstance = modal.getContentComponent(); componentInstance.onModalClose(); this.nftSelectionService.notifyModalClosed(); }); } - - } diff --git a/src/app/components/nft/components/nft-selection-toolbar/nft-selection-toolbar.module.ts b/src/app/components/nft/components/nft-selection-toolbar/nft-selection-toolbar.module.ts index 1a61c88..8f00905 100644 --- a/src/app/components/nft/components/nft-selection-toolbar/nft-selection-toolbar.module.ts +++ b/src/app/components/nft/components/nft-selection-toolbar/nft-selection-toolbar.module.ts @@ -3,16 +3,11 @@ import { CommonModule } from '@angular/common'; import { NftSelectionToolbarComponent } from './nft-selection-toolbar.component'; import { NzButtonModule } from 'ng-zorro-antd/button'; import { NzModalModule } from 'ng-zorro-antd/modal'; -import { NftTransferModule } from '@components/nft/components/nft-transfer/nft-transfer.module' +import { NftTransferModule } from '@components/nft/components/nft-transfer/nft-transfer.module'; @NgModule({ declarations: [NftSelectionToolbarComponent], - imports: [ - CommonModule, - NzButtonModule, - NzModalModule, - NftTransferModule - ], - exports: [NftSelectionToolbarComponent] + imports: [CommonModule, NzButtonModule, NzModalModule, NftTransferModule], + exports: [NftSelectionToolbarComponent], }) export class NftSelectionToolbarModule {} diff --git a/src/app/components/nft/components/nft-transfer/nft-transfer.component.html b/src/app/components/nft/components/nft-transfer/nft-transfer.component.html index 2d7855c..57d4060 100644 --- a/src/app/components/nft/components/nft-transfer/nft-transfer.component.html +++ b/src/app/components/nft/components/nft-transfer/nft-transfer.component.html @@ -9,29 +9,49 @@ Withdraw Status - + - + - {{ nft.name }} + {{ nft.name }} - {{ nft.mintingData?.network }} + {{ + nft.mintingData?.network + }} - + - + - {{ nft.statusMessage }} + {{ nft.statusMessage }} -
+
@@ -53,7 +74,8 @@ class="target-access-option" (click)="targetAccessOption$.next(targetAccess.MEMBERS)" [ngClass]="{ - 'target-access-option__selected': (targetAccessOption$ | async) === targetAccess.MEMBERS + 'target-access-option__selected': + (targetAccessOption$ | async) === targetAccess.MEMBERS }" i18n > @@ -71,7 +93,7 @@ name="recipientAddress" placeholder="Recipient Wallet Address" required - > + /> diff --git a/src/app/components/nft/components/nft-transfer/nft-transfer.component.ts b/src/app/components/nft/components/nft-transfer/nft-transfer.component.ts index 351d79c..4946c9a 100644 --- a/src/app/components/nft/components/nft-transfer/nft-transfer.component.ts +++ b/src/app/components/nft/components/nft-transfer/nft-transfer.component.ts @@ -1,8 +1,29 @@ import { ChangeDetectionStrategy, Component, OnInit, ChangeDetectorRef } from '@angular/core'; import { NzModalRef } from 'ng-zorro-antd/modal'; import { NftSelectionService } from '@core/services/nft-selection/nft-selection.service'; -import { Nft, NftTransferRequest, Transaction, Timestamp, COL, Member, NftAccess, WenError, RETRY_UNCOFIRMED_PAYMENT_DELAY } from '@build-5/interfaces'; -import { BehaviorSubject, Subscription, catchError, forkJoin, from, map, of, switchMap, take, tap } from 'rxjs'; +import { + Nft, + NftTransferRequest, + Transaction, + Timestamp, + COL, + Member, + NftAccess, + WenError, + RETRY_UNCOFIRMED_PAYMENT_DELAY, +} from '@build-5/interfaces'; +import { + BehaviorSubject, + Subscription, + catchError, + forkJoin, + from, + map, + of, + switchMap, + take, + tap, +} from 'rxjs'; import { NftApi } from '@api/nft.api'; import { OrderApi } from '@api/order.api'; import { AuthService } from '@components/auth/services/auth.service'; @@ -40,7 +61,7 @@ interface HistoryItem { }) export class TransferModalComponent implements OnInit { public selectedNfts: TransNft[] = []; - public recipientAddress: string = ''; + public recipientAddress = ''; private nftSelectionSubscription$: Subscription = new Subscription(); public selectedNetwork: string | null = null; private transSubscription$?: Subscription; @@ -81,32 +102,37 @@ export class TransferModalComponent implements OnInit { this.nftSelectionSubscription$.add( this.nftSelectionService.selectedNftIds$ .pipe( - switchMap(ids => { + switchMap((ids) => { if (ids.length === 0) { return of([]); } - return forkJoin(ids.map(id => this.nftApi.getNftById(id).pipe( - take(1), - catchError(error => { - console.error(`Error fetching NFT with ID ${id}:`, error); - return of(null); - }) - ))); + return forkJoin( + ids.map((id) => + this.nftApi.getNftById(id).pipe( + take(1), + catchError((error) => { + console.error(`Error fetching NFT with ID ${id}:`, error); + return of(null); + }), + ), + ), + ); }), - map(nfts => nfts.filter((nft): nft is Nft => nft !== null && nft !== undefined) - .map(nft => ({ - ...nft, - transfer: false, - withdraw: false, - disabled: false, - })) - ) + map((nfts) => + nfts + .filter((nft): nft is Nft => nft !== null && nft !== undefined) + .map((nft) => ({ + ...nft, + transfer: false, + withdraw: false, + disabled: false, + })), + ), ) - .subscribe(nfts => { + .subscribe((nfts) => { this.selectedNfts = this.sortNfts(nfts); this.cd.markForCheck(); - }) - + }), ); this.targetAccessOption$.pipe(untilDestroyed(this)).subscribe((targetAccessOption) => { @@ -129,7 +155,6 @@ export class TransferModalComponent implements OnInit { value: member.uid, }; }), - ); }); } @@ -147,7 +172,7 @@ export class TransferModalComponent implements OnInit { public updateNetworkSelection(selectedNft: any): void { if (selectedNft.transfer) { this.selectedNetwork = selectedNft.mintingData?.network; - } else if (this.selectedNfts.every(nft => !nft.transfer)) { + } else if (this.selectedNfts.every((nft) => !nft.transfer)) { this.selectedNetwork = null; } } @@ -157,31 +182,38 @@ export class TransferModalComponent implements OnInit { } public getSubmitButtonTooltip(): string { - const addressTrue = (this.selectedAccessControl.value === 0 && !!this.recipientAddress) || (this.selectedAccessControl.value === 1 && !!this.transferMemberControl.value); + const addressTrue = + (this.selectedAccessControl.value === 0 && !!this.recipientAddress) || + (this.selectedAccessControl.value === 1 && !!this.transferMemberControl.value); if (!addressTrue) { return 'Input address or choose member to allow transfer of NFTs'; } - if (this.selectedNfts.every(nft => !nft.transfer)) { + if (this.selectedNfts.every((nft) => !nft.transfer)) { return 'Select which NFT(s) to transfer'; } return ''; } public canSubmit(): boolean { - const addressTrue = (this.selectedAccessControl.value === 0 && !!this.recipientAddress) || (this.selectedAccessControl.value === 1 && !!this.transferMemberControl.value); - return addressTrue && this.selectedNfts.some(nft => nft.transfer); + const addressTrue = + (this.selectedAccessControl.value === 0 && !!this.recipientAddress) || + (this.selectedAccessControl.value === 1 && !!this.transferMemberControl.value); + return addressTrue && this.selectedNfts.some((nft) => nft.transfer); } public async onSubmit(): Promise { - const sendToAddress = (this.selectedAccessControl.value === 0) ? this.recipientAddress : this.transferMemberControl.value; + const sendToAddress = + this.selectedAccessControl.value === 0 + ? this.recipientAddress + : this.transferMemberControl.value; const request: NftTransferRequest = { transfers: this.selectedNfts - .filter(nft => nft.transfer) - .map(nft => ({ + .filter((nft) => nft.transfer) + .map((nft) => ({ nft: nft.uid, target: sendToAddress, - withdraw: nft.withdraw || undefined - })) + withdraw: nft.withdraw || undefined, + })), }; const params = request; @@ -191,7 +223,7 @@ export class TransferModalComponent implements OnInit { .subscribe((val: any) => { if (val && typeof val === 'object') { Object.entries(val).forEach(([nftId, responseCode]) => { - const nftIndex = this.selectedNfts.findIndex(nft => nft.uid === nftId); + const nftIndex = this.selectedNfts.findIndex((nft) => nft.uid === nftId); if (nftIndex !== -1) { if (responseCode === 200) { this.selectedNfts[nftIndex].transfer = false; @@ -241,11 +273,13 @@ export class TransferModalComponent implements OnInit { } onModalClose(): void { - const idsOfTransferredNfts = this.selectedNfts.filter(nft => nft.disabled).map(nft => nft.uid); + const idsOfTransferredNfts = this.selectedNfts + .filter((nft) => nft.disabled) + .map((nft) => nft.uid); if (idsOfTransferredNfts.length > 0) { - this.selectedNfts = this.selectedNfts.filter(nft => !nft.disabled); + this.selectedNfts = this.selectedNfts.filter((nft) => !nft.disabled); - idsOfTransferredNfts.forEach(nftId => { + idsOfTransferredNfts.forEach((nftId) => { this.nftSelectionService.deselectNft(nftId); }); @@ -254,16 +288,14 @@ export class TransferModalComponent implements OnInit { const expectedPath = `/member/${memberId}/nfts`; const currentPath = this.router.url; if (currentPath === expectedPath) { - this.router.navigateByUrl('/', { skipLocationChange: true }).then(() => { - window.location.href = `/member/${memberId}/nfts`; + window.location.href = `/member/${memberId}/nfts`; }); } } } } - private sortNfts(nfts: TransNft[]): TransNft[] { return nfts.sort((a, b) => { const networkA = a.mintingData?.network || ''; diff --git a/src/app/components/nft/components/nft-transfer/nft-transfer.module.ts b/src/app/components/nft/components/nft-transfer/nft-transfer.module.ts index e41cf75..48284e5 100644 --- a/src/app/components/nft/components/nft-transfer/nft-transfer.module.ts +++ b/src/app/components/nft/components/nft-transfer/nft-transfer.module.ts @@ -14,9 +14,7 @@ import { NzRadioModule } from 'ng-zorro-antd/radio'; import { NzSelectModule } from 'ng-zorro-antd/select'; @NgModule({ - declarations: [ - TransferModalComponent - ], + declarations: [TransferModalComponent], imports: [ CommonModule, FormsModule, @@ -32,8 +30,6 @@ import { NzSelectModule } from 'ng-zorro-antd/select'; NzRadioModule, NzSelectModule, ], - exports: [ - TransferModalComponent - ] + exports: [TransferModalComponent], }) -export class NftTransferModule { } +export class NftTransferModule {} diff --git a/src/app/pages/member/pages/nfts/nfts.page.ts b/src/app/pages/member/pages/nfts/nfts.page.ts index 95eb434..aab14d2 100644 --- a/src/app/pages/member/pages/nfts/nfts.page.ts +++ b/src/app/pages/member/pages/nfts/nfts.page.ts @@ -73,7 +73,6 @@ export class NFTsPage implements OnInit { setInterval(() => this.cd.markForCheck(), 200); } }); - }); } @@ -96,7 +95,7 @@ export class NFTsPage implements OnInit { if (event.selected) { this.selectedNfts.push(event.nft); } else { - this.selectedNfts = this.selectedNfts.filter(nft => nft.id !== event.nft.id); + this.selectedNfts = this.selectedNfts.filter((nft) => nft.id !== event.nft.id); } } }