Skip to content

Commit 4630fb9

Browse files
authored
Merge pull request #2965 from numbersprotocol/feature-v230725-showing-order-information-in-the-transaction
Feature v230725 showing order information in the transaction
2 parents 4bc0546 + 8c49316 commit 4630fb9

12 files changed

+325
-205
lines changed

src/app/features/home/activities/activities.page.html

+1-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
[text]="t('userGuide.viewNetworkActionsHistory')"
2323
>
2424
<ion-label>
25-
{{ t('networkActions') }}
25+
{{ t('orders') }}
2626
</ion-label>
2727
</ion-segment-button>
2828
</ion-segment>

src/app/features/home/activities/activities.page.scss

+8
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,11 @@ mat-toolbar {
33
padding-right: 40px;
44
}
55
}
6+
7+
ion-segment {
8+
display: flex;
9+
10+
ion-segment-button {
11+
flex: 1;
12+
}
13+
}
Original file line numberDiff line numberDiff line change
@@ -1,118 +1,16 @@
1-
<mat-toolbar *transloco="let t">
2-
<app-capture-back-button></app-capture-back-button>
3-
<span>{{ t('networkActionOrderDetails') }}</span>
4-
</mat-toolbar>
1+
<ng-container *ngIf="isOffline$ | ngrxPush; else onlineTemplate">
2+
<mat-toolbar *transloco="let t">
3+
<app-capture-back-button></app-capture-back-button>
4+
<span>{{ t('networkActionOrderDetails') }}</span>
5+
</mat-toolbar>
6+
</ng-container>
57

6-
<ion-content *ngrxLet="order$ as order">
7-
<div *transloco="let t">
8-
<h4 class="datetime">
9-
{{ order['Created Date'] | date: 'short' }}
10-
</h4>
11-
<ion-card>
12-
<ion-grid>
13-
<ion-row>
14-
<img
15-
decoding="async"
16-
loading="lazy"
17-
[src]="
18-
(order.assetThumbnailUrl$ | ngrxPush) ||
19-
'/assets/images/image-placeholder.png'
20-
"
21-
/>
22-
</ion-row>
23-
24-
<ion-row>
25-
<ion-col size="12">
26-
<h4 id="network-action-name">{{ order.network_app_name_text }}</h4>
27-
</ion-col>
28-
</ion-row>
29-
<ion-row id="order-id-row" class="detail-info-rows">
30-
<ion-col size="3.5">
31-
<ion-label>{{ t('order') + ' ID' }}:</ion-label>
32-
</ion-col>
33-
<ion-col class="wrap-text" align="end">
34-
<ion-label>{{ order.order_id_text }} </ion-label>
35-
</ion-col>
36-
<ion-col size="1" align="end">
37-
<ion-icon
38-
size="small"
39-
name="copy-outline"
40-
(click)="copyToClipboard(order.order_id_text)"
41-
></ion-icon>
42-
</ion-col>
43-
</ion-row>
44-
45-
<ion-row class="detail-info-rows">
46-
<ion-col size="3.5">
47-
<ion-label>{{ t('resultUrl') }}:</ion-label>
48-
</ion-col>
49-
<ion-col class="wrap-text" align="end">
50-
<ion-label
51-
*ngIf="order.result_url_text !== undefined"
52-
(click)="openResultUrl(order.result_url_text)"
53-
>
54-
<a> {{ order.result_url_text }} </a>
55-
</ion-label>
56-
57-
<ion-label
58-
*ngIf="order.result_url_text === undefined"
59-
(click)="openResultUrl(resultUrlFromAssetId(order.asset_id_text))"
60-
>
61-
<a> {{ resultUrlFromAssetId(order.asset_id_text) }} </a>
62-
</ion-label>
63-
</ion-col>
64-
<ion-col size="1"> </ion-col>
65-
</ion-row>
66-
67-
<ion-row class="detail-info-rows">
68-
<ion-col size="3.5">
69-
<ion-label>{{ t('payment.price') }}:</ion-label>
70-
</ion-col>
71-
<ion-col align="end">
72-
<ion-label
73-
>{{ order.price_number | number: '1.4-4' }}
74-
{{ order.cost_token_ticker_text || 'NUM' }}</ion-label
75-
>
76-
</ion-col>
77-
<ion-col size="1"></ion-col>
78-
</ion-row>
79-
<ion-row class="detail-info-rows">
80-
<ion-col size="3.5">
81-
<ion-label>{{ t('payment.fee') }}:</ion-label>
82-
</ion-col>
83-
<ion-col align="end">
84-
<ion-label
85-
>{{ order.gas_fee_number | number: '1.4-4' }}
86-
{{ order.cost_token_ticker_text || 'NUM' }}</ion-label
87-
>
88-
</ion-col>
89-
<ion-col size="1"></ion-col>
90-
</ion-row>
91-
<ion-row class="detail-info-rows">
92-
<ion-col size="3.5">
93-
<ion-label>{{ t('payment.totalCost') }}:</ion-label>
94-
</ion-col>
95-
<ion-col align="end">
96-
<ion-label
97-
>{{ order.total_cost_number | number: '1.4-4' }}
98-
{{ order.cost_token_ticker_text || 'NUM' }}</ion-label
99-
>
100-
</ion-col>
101-
<ion-col size="1"></ion-col>
102-
</ion-row>
103-
104-
<ion-row>
105-
<ion-col id="status-col">
106-
<button
107-
[class]="order.status_text"
108-
mat-stroked-button
109-
disableRipple
110-
>
111-
{{ t('networkActionOrderState.' + order.status_text) }}
112-
</button>
113-
</ion-col>
114-
</ion-row>
115-
</ion-grid>
116-
</ion-card>
117-
</div>
118-
</ion-content>
8+
<ng-template #onlineTemplate>
9+
<ng-container *ngIf="iframeUrl$ | ngrxPush as iframeUrl">
10+
<iframe [src]="iframeUrl | safeResourceUrl"> </iframe>
11+
</ng-container>
12+
<ion-spinner
13+
*ngIf="(iframeLoaded$ | async) !== true"
14+
name="lines-sharp"
15+
></ion-spinner>
16+
</ng-template>

src/app/features/home/activities/network-action-order-details/network-action-order-details.page.scss

+26
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,35 @@
11
mat-toolbar {
22
span {
33
padding-right: 40px;
4+
font-style: normal;
5+
font-weight: 500;
6+
font-size: 16px;
7+
line-height: 21px;
8+
text-align: center;
9+
color: white;
410
}
511
}
612

13+
.no-network-text {
14+
font-size: 18px;
15+
margin: auto;
16+
}
17+
18+
iframe {
19+
background-color: black;
20+
width: 100vw;
21+
height: 100vh;
22+
border: 0;
23+
}
24+
25+
ion-spinner {
26+
position: absolute;
27+
left: 50%;
28+
top: 50%;
29+
transform: translate(-50%, -50%);
30+
scale: 1.5;
31+
}
32+
733
ion-content {
834
.datetime {
935
width: 90vw;

src/app/features/home/activities/network-action-order-details/network-action-order-details.page.ts

+94-9
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,24 @@ import { Component } from '@angular/core';
22
import { MatSnackBar } from '@angular/material/snack-bar';
33
import { ActivatedRoute } from '@angular/router';
44
import { Plugins } from '@capacitor/core';
5+
import { NavController } from '@ionic/angular';
56
import { TranslocoService } from '@ngneat/transloco';
6-
import { UntilDestroy } from '@ngneat/until-destroy';
7-
import { combineLatest } from 'rxjs';
8-
import { catchError, first, map } from 'rxjs/operators';
7+
import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy';
8+
import { BehaviorSubject, combineLatest, fromEvent } from 'rxjs';
9+
import {
10+
catchError,
11+
concatMap,
12+
first,
13+
map,
14+
switchMap,
15+
tap,
16+
} from 'rxjs/operators';
917
import { OrderHistoryService } from '../../../../shared/actions/service/order-history.service';
18+
import { BUBBLE_IFRAME_URL } from '../../../../shared/dia-backend/secret';
19+
import { DiaBackendStoreService } from '../../../../shared/dia-backend/store/dia-backend-store.service';
1020
import { ErrorService } from '../../../../shared/error/error.service';
21+
import { BubbleToIonicPostMessage } from '../../../../shared/iframe/iframe';
22+
import { NetworkService } from '../../../../shared/network/network.service';
1123
import { isNonNullable } from '../../../../utils/rx-operators/rx-operators';
1224
import { getAssetProfileForNSE } from '../../../../utils/url';
1325

@@ -19,26 +31,99 @@ const { Browser, Clipboard } = Plugins;
1931
styleUrls: ['./network-action-order-details.page.scss'],
2032
})
2133
export class NetworkActionOrderDetailsPage {
34+
readonly orderId$ = this.route.paramMap.pipe(
35+
map(params => params.get('order_id')),
36+
isNonNullable()
37+
);
38+
readonly assetId$ = this.orderId$.pipe(
39+
switchMap(orderId => this.storeService.retrieveNetworkAppOrder$(orderId)),
40+
map(order => {
41+
if ('nid' in order.action_args) return order.action_args.nid as string;
42+
if ('cid' in order.action_args) return order.action_args.cid as string;
43+
return undefined;
44+
})
45+
);
2246
readonly order$ = combineLatest([
2347
this.orderHistoryService.networkActionOrders$,
24-
this.route.paramMap.pipe(
25-
map(params => params.get('order_id')),
26-
isNonNullable()
27-
),
48+
this.orderId$,
2849
]).pipe(
2950
first(),
3051
map(([orders, orderId]) => orders.find(o => o.order_id_text === orderId)),
3152
isNonNullable(),
3253
catchError((err: unknown) => this.errorService.toastError$(err))
3354
);
55+
readonly isOffline$ = this.networkService.connected$.pipe(
56+
map(connected => connected === false)
57+
);
58+
59+
readonly iframeUrl$ = combineLatest([this.orderId$, this.assetId$]).pipe(
60+
map(([orderId, assetId]) => {
61+
const queryParams = new URLSearchParams();
62+
63+
queryParams.append('order_id', orderId);
64+
65+
/**
66+
* Some network action orders might not have releated asset id (aka nid, cid).
67+
* For example:
68+
* - "Creator Gallery"
69+
* - "One-NUM-price"
70+
* - "CustodialWalletWithdraw"
71+
* - etc
72+
*/
73+
if (assetId) queryParams.append('asset_id', assetId);
74+
75+
return `${BUBBLE_IFRAME_URL}/version-test/order_details?${queryParams}`;
76+
})
77+
);
78+
79+
readonly iframeLoaded$ = new BehaviorSubject(false);
3480

3581
constructor(
3682
private readonly route: ActivatedRoute,
3783
private readonly orderHistoryService: OrderHistoryService,
84+
private readonly storeService: DiaBackendStoreService,
3885
private readonly errorService: ErrorService,
3986
private readonly snackBar: MatSnackBar,
40-
private readonly translocoService: TranslocoService
41-
) {}
87+
private readonly translocoService: TranslocoService,
88+
private readonly networkService: NetworkService,
89+
private readonly navController: NavController
90+
) {
91+
this.processIframeEvents();
92+
}
93+
94+
private processIframeEvents() {
95+
fromEvent(window, 'message')
96+
.pipe(
97+
tap(event => {
98+
const postMessageEvent = event as MessageEvent;
99+
const data = postMessageEvent.data as BubbleToIonicPostMessage;
100+
switch (data) {
101+
case BubbleToIonicPostMessage.IFRAME_ON_LOAD:
102+
this.iframeLoaded$.next(true);
103+
break;
104+
case BubbleToIonicPostMessage.IFRAME_BACK_BUTTON_CLICKED:
105+
this.navController.back();
106+
break;
107+
case BubbleToIonicPostMessage.IFRAME_COPY_TO_CLIPBOARD_ORDER_ID:
108+
this.copyToClipboardOrderId();
109+
break;
110+
default:
111+
break;
112+
}
113+
}),
114+
untilDestroyed(this)
115+
)
116+
.subscribe();
117+
}
118+
119+
private copyToClipboardOrderId() {
120+
this.order$
121+
.pipe(
122+
first(),
123+
concatMap(({ order_id_text }) => this.copyToClipboard(order_id_text))
124+
)
125+
.subscribe();
126+
}
42127

43128
// eslint-disable-next-line class-methods-use-this
44129
openResultUrl(url: string) {

0 commit comments

Comments
 (0)