From 1d8542157c399dd2bcee7d85ed30fbd70ba32c0d Mon Sep 17 00:00:00 2001 From: takYoon Date: Wed, 17 Aug 2022 23:44:12 +0700 Subject: [PATCH 01/28] testing config for abcpay and swap --- src/app/app-routing.module.ts | 18 ++++- src/app/app.component.ts | 32 ++++----- src/app/app.module.ts | 13 +++- src/app/pages/pages.ts | 2 + src/app/pages/swap/swap.component.html | 3 + src/app/pages/swap/swap.component.scss | 0 src/app/pages/swap/swap.component.spec.ts | 24 +++++++ src/app/pages/swap/swap.component.ts | 14 ++++ src/app/providers/feature-flags.service.ts | 42 ++++++++++++ src/app/providers/feature-gaurd.service.ts | 77 ++++++++++++++++++++++ 10 files changed, 205 insertions(+), 20 deletions(-) create mode 100644 src/app/pages/swap/swap.component.html create mode 100644 src/app/pages/swap/swap.component.scss create mode 100644 src/app/pages/swap/swap.component.spec.ts create mode 100644 src/app/pages/swap/swap.component.ts create mode 100644 src/app/providers/feature-flags.service.ts create mode 100644 src/app/providers/feature-gaurd.service.ts diff --git a/src/app/app-routing.module.ts b/src/app/app-routing.module.ts index 3c59eba6922..187f11105cb 100644 --- a/src/app/app-routing.module.ts +++ b/src/app/app-routing.module.ts @@ -67,15 +67,21 @@ import { SettingsPage } from './pages/settings/settings'; import { SearchContactPage } from './pages/search/search-contact/search-contact.component'; import { SelectFlowPage } from './pages/onboarding/select-flow/select-flow'; import { ChartViewPage } from './pages/chart-view/chart-view'; +import { FeatureGuard } from './providers/feature-gaurd.service'; +import { SwapPage } from './pages/swap/swap.component'; const routes: Routes = [ { path: '', - loadChildren: () => import('./tabs/tabs.module').then(m => m.TabsPageModule) + loadChildren: () => import('./tabs/tabs.module').then(m => m.TabsPageModule), }, { path: 'select-flow', - component: SelectFlowPage + component: SelectFlowPage, + canLoad: [FeatureGuard], + data: { + feature: 'abcpay' + } }, { path: 'feature-education', @@ -346,6 +352,14 @@ const routes: Routes = [ { path: 'chart-view', component: ChartViewPage + }, + { + path: 'swap', + component: SwapPage, + canActivate: [FeatureGuard], + data: { + feature: 'swap' + } } ]; diff --git a/src/app/app.component.ts b/src/app/app.component.ts index 297d99a7265..8bb88f5e8bf 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -91,14 +91,14 @@ export class CopayApp { private imageLoaderConfig: ImageLoaderConfigService, private navasd: NavController ) { - this.imageLoaderConfig.setFileNameCachedWithExtension(true); - this.imageLoaderConfig.useImageTag(true); - this.imageLoaderConfig.enableSpinner(false); - this.initializeApp(); - this.platformProvider.isCordova ? this.routerHidden = true : this.routerHidden = false; - if (!this.platformProvider.isCordova) { - this.renderer.addClass(document.body, 'bg-desktop'); - } + // this.imageLoaderConfig.setFileNameCachedWithExtension(true); + // this.imageLoaderConfig.useImageTag(true); + // this.imageLoaderConfig.enableSpinner(false); + // this.initializeApp(); + // this.platformProvider.isCordova ? this.routerHidden = true : this.routerHidden = false; + // if (!this.platformProvider.isCordova) { + // this.renderer.addClass(document.body, 'bg-desktop'); + // } } ngOnDestroy() { @@ -111,15 +111,15 @@ export class CopayApp { } initializeApp() { - this.platform - .ready() - .then(async readySource => { + // this.platform + // .ready() + // .then(async readySource => { - this.onPlatformReady(readySource); - }) - .catch(e => { - this.logger.error('Platform is not ready.', e); - }); + // this.onPlatformReady(readySource); + // }) + // .catch(e => { + // this.logger.error('Platform is not ready.', e); + // }); } private onPlatformReady(readySource): void { diff --git a/src/app/app.module.ts b/src/app/app.module.ts index fa2eb0cccb5..38e96aecab6 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -1,5 +1,5 @@ import { HttpClientModule } from '@angular/common/http'; -import { CUSTOM_ELEMENTS_SCHEMA, ErrorHandler, NgModule } from '@angular/core'; +import { APP_INITIALIZER, CUSTOM_ELEMENTS_SCHEMA, ErrorHandler, NgModule } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; import { RouteReuseStrategy } from '@angular/router'; import { ServiceWorkerModule } from '@angular/service-worker'; @@ -48,6 +48,7 @@ import { MatIconModule } from '@angular/material/icon'; import { A11yModule } from '@angular/cdk/a11y'; import { ClickOutsideModule } from 'ng-click-outside'; import { CountdownModule } from 'ngx-countdown'; +import { FeatureFlagsService } from './providers/feature-flags.service'; export function translateParserFactory() { return new InterpolatedTranslateParser(); @@ -63,7 +64,8 @@ export class MyMissingTranslationHandler implements MissingTranslationHandler { return this.parser.interpolate(params.key, params.interpolateParams); } } - +const featureFactory = (featureFlagsService: FeatureFlagsService) => () => + featureFlagsService.loadConfig(); @NgModule({ declarations: [ /* Pipes */ @@ -131,6 +133,12 @@ export class MyMissingTranslationHandler implements MissingTranslationHandler { ServiceWorkerModule.register('ngsw-worker.js', { enabled: env.name === 'production' }) ], providers: [ + { + provide: APP_INITIALIZER, + useFactory: featureFactory, + deps: [FeatureFlagsService], + multi: true + }, { provide: RouteReuseStrategy, useClass: IonicRouteStrategy @@ -139,6 +147,7 @@ export class MyMissingTranslationHandler implements MissingTranslationHandler { provide: ErrorHandler, useClass: CustomErrorHandler }, + FormatCurrencyPipe, NavParams, FormBuilder, diff --git a/src/app/pages/pages.ts b/src/app/pages/pages.ts index 004c99eb2b0..0f56b09a5ff 100644 --- a/src/app/pages/pages.ts +++ b/src/app/pages/pages.ts @@ -110,6 +110,7 @@ import { TokenInforPage } from './token-info/token-info'; import { AccountsPage } from './accounts/accounts'; import { SearchContactPage } from './search/search-contact/search-contact.component'; import { SelectFlowPage } from './onboarding/select-flow/select-flow'; +import { SwapPage } from './swap/swap.component'; export const PAGES = [ AddPage, @@ -203,6 +204,7 @@ export const PAGES = [ CoinSelectorPage, DisclaimerModal, SlideToAcceptPage, + SwapPage, LocalThemePage, NavigationPage, NewFeaturePage, diff --git a/src/app/pages/swap/swap.component.html b/src/app/pages/swap/swap.component.html new file mode 100644 index 00000000000..db824802d4e --- /dev/null +++ b/src/app/pages/swap/swap.component.html @@ -0,0 +1,3 @@ +

+ swap works! +

diff --git a/src/app/pages/swap/swap.component.scss b/src/app/pages/swap/swap.component.scss new file mode 100644 index 00000000000..e69de29bb2d diff --git a/src/app/pages/swap/swap.component.spec.ts b/src/app/pages/swap/swap.component.spec.ts new file mode 100644 index 00000000000..80502b146ce --- /dev/null +++ b/src/app/pages/swap/swap.component.spec.ts @@ -0,0 +1,24 @@ +import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; +import { IonicModule } from '@ionic/angular'; + +import { SwapComponent } from './swap.component'; + +describe('SwapComponent', () => { + let component: SwapComponent; + let fixture: ComponentFixture; + + beforeEach(waitForAsync(() => { + TestBed.configureTestingModule({ + declarations: [ SwapComponent ], + imports: [IonicModule.forRoot()] + }).compileComponents(); + + fixture = TestBed.createComponent(SwapComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + })); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/pages/swap/swap.component.ts b/src/app/pages/swap/swap.component.ts new file mode 100644 index 00000000000..b406b71a267 --- /dev/null +++ b/src/app/pages/swap/swap.component.ts @@ -0,0 +1,14 @@ +import { Component, OnInit } from '@angular/core'; + +@Component({ + selector: 'app-swap', + templateUrl: './swap.component.html', + styleUrls: ['./swap.component.scss'], +}) +export class SwapPage implements OnInit { + + constructor() { } + + ngOnInit() {} + +} diff --git a/src/app/providers/feature-flags.service.ts b/src/app/providers/feature-flags.service.ts new file mode 100644 index 00000000000..d69e5d25e9b --- /dev/null +++ b/src/app/providers/feature-flags.service.ts @@ -0,0 +1,42 @@ +import { HttpClient } from "@angular/common/http"; +import { Injectable } from "@angular/core"; +import { get, has } from "lodash"; +import { of } from "rxjs"; +import { tap } from "rxjs/operators"; + +export interface FeatureConfig { + abcpay: boolean, + swap: boolean +} + +@Injectable({ + providedIn: "root" + }) + export class FeatureFlagsService { + config: FeatureConfig = null; + configUrl = ``; // <-- URL for getting the config + + constructor(private http: HttpClient) {} + + /** + * We convert it to promise so that this function can + * be called by the APP_INITIALIZER + */ + loadConfig() : Promise { + // return this.http + // .get(this.configUrl) + // .pipe(tap(data => (this.config = data))) + // .toPromise(); + return Promise.resolve({ + abcpay: true, + swap: false + } as FeatureConfig); + } + + isFeatureEnabled(key: string) { + if (this.config && has(this.config, key)) { + return get(this.config, key, false); + } + return false; + } + } \ No newline at end of file diff --git a/src/app/providers/feature-gaurd.service.ts b/src/app/providers/feature-gaurd.service.ts new file mode 100644 index 00000000000..f3db7758e6a --- /dev/null +++ b/src/app/providers/feature-gaurd.service.ts @@ -0,0 +1,77 @@ +import { Injectable } from '@angular/core'; +import { ActivatedRouteSnapshot, CanActivate, CanDeactivate, CanLoad, Route, Router, RouterStateSnapshot, UrlSegment, UrlTree } from '@angular/router'; +import { Observable } from 'rxjs'; +import { FeatureFlagsService } from './feature-flags.service'; + +@Injectable({ + providedIn: 'root', +}) +export class FeatureGuard implements CanActivate, CanLoad { + constructor( + private featureFlagsService: FeatureFlagsService, + private router: Router + ) {} + canLoad(route: Route, segments: UrlSegment[]): boolean | UrlTree | Observable | Promise { + const { + data: { feature }, // <-- Get the module name from route data + } = route; + if (feature) { + const isEnabled = this.featureFlagsService.isFeatureEnabled(feature); + if (isEnabled) { + return true; + } + } + this.router.navigate(['/swap']); + return false; } + canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean | UrlTree | Observable | Promise { + const { + data: { feature }, // <-- Get the module name from route data + } = route; + if (feature) { + const isEnabled = this.featureFlagsService.isFeatureEnabled(feature); + if (isEnabled) { + return true; + } + } + this.router.navigate(['/swap']); + return false; + } +// canActivate( +// route: Route, +// segments: UrlSegment[] +// ): +// boolean { +// const { +// data: { feature }, // <-- Get the module name from route data +// } = route; +// if (feature) { +// const isEnabled = this.featureFlagsService.isFeatureEnabled(feature); +// if (isEnabled) { +// return true; +// } +// } +// this.router.navigate(['/swap']); +// return false; +// } + + CanDeactivate( + route: Route, + segments: UrlSegment[] + ): + | Observable + | Promise + | boolean + | UrlTree { + const { + data: { feature }, // <-- Get the module name from route data + } = route; + if (feature) { + const isEnabled = this.featureFlagsService.isFeatureEnabled(feature); + if (isEnabled) { + return true; + } + } + this.router.navigate(['/swap']); + return false; + } +} \ No newline at end of file From fe2a421ab0b54d1d8f2cd8758cdfa2058dd6a76e Mon Sep 17 00:00:00 2001 From: takYoon Date: Tue, 23 Aug 2022 09:29:15 +0700 Subject: [PATCH 02/28] update feature flag --- src/app/app-routing.module.ts | 353 ++++++++++++++++++++- src/app/app.module.ts | 9 + src/app/providers/feature-flags.service.ts | 25 +- src/app/providers/feature-gaurd.service.ts | 7 +- 4 files changed, 375 insertions(+), 19 deletions(-) diff --git a/src/app/app-routing.module.ts b/src/app/app-routing.module.ts index 187f11105cb..6bf7b842443 100644 --- a/src/app/app-routing.module.ts +++ b/src/app/app-routing.module.ts @@ -78,280 +78,613 @@ const routes: Routes = [ { path: 'select-flow', component: SelectFlowPage, - canLoad: [FeatureGuard], + canActivate: [FeatureGuard], data: { feature: 'abcpay' } }, { path: 'feature-education', - component: FeatureEducationPage + component: FeatureEducationPage, + canActivate: [FeatureGuard], + + data: { + feature: 'abcpay' + } }, { path: 'about', component: AboutPage, + canActivate: [FeatureGuard], + + data: { + feature: 'abcpay' + } }, { path: 'accounts-page', - component: AccountsPage + component: AccountsPage, + canActivate: [FeatureGuard], + + data: { + feature: 'abcpay' + } }, { path: 'token-details', - component: TokenDetailsPage + component: TokenDetailsPage, + canActivate: [FeatureGuard], + + data: { + feature: 'abcpay' + } }, { path: 'token-info', - component: TokenInforPage + component: TokenInforPage, + canActivate: [FeatureGuard], + + data: { + feature: 'abcpay' + } }, { path: 'confirm-token', - component: ConfirmTokenPage + component: ConfirmTokenPage, + canActivate: [FeatureGuard], + + data: { + feature: 'abcpay' + } }, { path: 'alt-curency', component: AltCurrencyPage, + canActivate: [FeatureGuard], + + data: { + feature: 'abcpay' + } }, { path: 'language', component: LanguagePage, + canActivate: [FeatureGuard], + + data: { + feature: 'abcpay' + } }, { path: 'advanced', component: AdvancedPage, + canActivate: [FeatureGuard], + + data: { + feature: 'abcpay' + } }, { path: 'local-theme', component: LocalThemePage, + canActivate: [FeatureGuard], + + data: { + feature: 'abcpay' + } }, { path: 'navigation', component: NavigationPage, + canActivate: [FeatureGuard], + + data: { + feature: 'abcpay' + } }, { path: 'addressbook', component: AddressbookPage, + canActivate: [FeatureGuard], + + data: { + feature: 'abcpay' + } }, { path: 'fee-policy', component: FeePolicyPage, + canActivate: [FeatureGuard], + + data: { + feature: 'abcpay' + } }, { path: 'notifications', component: NotificationsPage, + canActivate: [FeatureGuard], + + data: { + feature: 'abcpay' + } }, { path: 'wallet-settings', component: WalletSettingsPage, + canActivate: [FeatureGuard], + + data: { + feature: 'abcpay' + } }, { path: 'share', component: SharePage, + canActivate: [FeatureGuard], + + data: { + feature: 'abcpay' + } }, { path: 'lock', component: LockPage, + canActivate: [FeatureGuard], + + data: { + feature: 'abcpay' + } }, { path: 'key-settings', component: KeySettingsPage, + canActivate: [FeatureGuard], + + data: { + feature: 'abcpay' + } }, { path: 'add', component: AddPage, + canActivate: [FeatureGuard], + + data: { + feature: 'abcpay' + } }, { path: 'wallet-recover', component: WalletRecoverPage, + canActivate: [FeatureGuard], + + data: { + feature: 'abcpay' + } }, { path: 'address-book-add', component: AddressbookAddPage, + canActivate: [FeatureGuard], + + data: { + feature: 'abcpay' + } }, { path: 'address-book-view', component: AddressbookViewPage, + canActivate: [FeatureGuard], + + data: { + feature: 'abcpay' + } }, { path: 'scan', component: ScanPage, + canActivate: [FeatureGuard], + + data: { + feature: 'abcpay' + } }, { path: 'price', component: PricePage, + canActivate: [FeatureGuard], + + data: { + feature: 'abcpay' + } }, { path: 'session-log', component: SessionLogPage, + canActivate: [FeatureGuard], + + data: { + feature: 'abcpay' + } }, { path: 'send-feedback', component: SendFeedbackPage, + canActivate: [FeatureGuard], + + data: { + feature: 'abcpay' + } }, { path: 'share', component: SharePage, + canActivate: [FeatureGuard], + + data: { + feature: 'abcpay' + } }, { path: 'select-currency', component: SelectCurrencyPage, + canActivate: [FeatureGuard], + + data: { + feature: 'abcpay' + } }, { path: 'join-wallet', component: JoinWalletPage, + canActivate: [FeatureGuard], + + data: { + feature: 'abcpay' + } }, { path: 'create-wallet', component: CreateWalletPage, + canActivate: [FeatureGuard], + + data: { + feature: 'abcpay' + } }, { path: 'import-wallet', component: ImportWalletPage, + canActivate: [FeatureGuard], + + data: { + feature: 'abcpay' + } }, { path: 'recovery-key', component: RecoveryKeyPage, + canActivate: [FeatureGuard], + + data: { + feature: 'abcpay' + } }, { path: 'wallet-details', component: WalletDetailsPage, + canActivate: [FeatureGuard], + + data: { + feature: 'abcpay' + } }, { path: 'send-page', component: SendPage, + canActivate: [FeatureGuard], + + data: { + feature: 'abcpay' + } }, { path: 'add-wallet', component: AddWalletPage, + canActivate: [FeatureGuard], + + data: { + feature: 'abcpay' + } }, { path: 'amount', component: AmountPage, + canActivate: [FeatureGuard], + + data: { + feature: 'abcpay' + } }, { path: 'wallet-name', component: WalletNamePage, + canActivate: [FeatureGuard], + + data: { + feature: 'abcpay' + } }, { path: 'wallet-information', component: WalletInformationPage, + canActivate: [FeatureGuard], + + data: { + feature: 'abcpay' + } }, { path: 'wallet-addresses', component: WalletAddressesPage, + canActivate: [FeatureGuard], + + data: { + feature: 'abcpay' + } }, { path: 'wallet-export', component: WalletExportPage, + canActivate: [FeatureGuard], + + data: { + feature: 'abcpay' + } }, { path: 'wallet-service-url', component: WalletServiceUrlPage, + canActivate: [FeatureGuard], + + data: { + feature: 'abcpay' + } }, { path: 'wallet-transaction-history', component: WalletTransactionHistoryPage, + canActivate: [FeatureGuard], + + data: { + feature: 'abcpay' + } }, { path: 'wallet-duplicate', component: WalletDuplicatePage, + canActivate: [FeatureGuard], + + data: { + feature: 'abcpay' + } }, { path: 'wallet-delete', component: WalletDeletePage, + canActivate: [FeatureGuard], + + data: { + feature: 'abcpay' + } }, { path: 'wallet-mnemonic-recover', component: WalletMnemonicRecoverPage, + canActivate: [FeatureGuard], + + data: { + feature: 'abcpay' + } }, { path: 'backup-key', component: BackupKeyPage, + canActivate: [FeatureGuard], + + data: { + feature: 'abcpay' + } }, { path: 'backup-game', component: BackupGamePage, + canActivate: [FeatureGuard], + + data: { + feature: 'abcpay' + } }, { path: 'clear-encrypt-password', component: ClearEncryptPasswordPage, + canActivate: [FeatureGuard], + + data: { + feature: 'abcpay' + } }, { path: 'key-delete', component: KeyDeletePage, + canActivate: [FeatureGuard], + + data: { + feature: 'abcpay' + } }, { path: 'key-qr-export', component: KeyQrExportPage, + canActivate: [FeatureGuard], + + data: { + feature: 'abcpay' + } }, { path: 'extended-private-key', component: ExtendedPrivateKeyPage, + canActivate: [FeatureGuard], + + data: { + feature: 'abcpay' + } }, { path: 'key-name', component: KeyNamePage, + canActivate: [FeatureGuard], + + data: { + feature: 'abcpay' + } }, { path: 'lock-method', component: LockMethodPage, - canActivate: [RedirectGuard] + canActivate: [RedirectGuard], + data: { + feature: 'abcpay' + } }, { path: 'proposals-notifications', component: ProposalsNotificationsPage, + canActivate: [FeatureGuard], + + data: { + feature: 'abcpay' + } }, { path: 'confirm', component: ConfirmPage, + canActivate: [FeatureGuard], + + data: { + feature: 'abcpay' + } }, { path: 'multi-send', component: MultiSendPage, + canActivate: [FeatureGuard], + + data: { + feature: 'abcpay' + } }, { path: 'select-inputs', component: SelectInputsPage, + canActivate: [FeatureGuard], + + data: { + feature: 'abcpay' + } }, { path: 'send-select-inputs', component: SelectInputsSendPage, + canActivate: [FeatureGuard], + + data: { + feature: 'abcpay' + } }, { path: 'transfer-to-modal', component: TransferToModalPage, + canActivate: [FeatureGuard], + + data: { + feature: 'abcpay' + } }, { path: 'custom-amount', component: CustomAmountPage, + canActivate: [FeatureGuard], + + data: { + feature: 'abcpay' + } }, { path: 'add-funds', component: AddFundsPage, + canActivate: [FeatureGuard], + + data: { + feature: 'abcpay' + } }, { path: 'copayers', component: CopayersPage, + canActivate: [FeatureGuard], + + data: { + feature: 'abcpay' + } }, { path: 'paper-wallet', component: PaperWalletPage, + canActivate: [FeatureGuard], + + data: { + feature: 'abcpay' + } }, { path: 'address-book-add', component: AddressbookAddPage, + canActivate: [FeatureGuard], + + data: { + feature: 'abcpay' + } }, { path: 'setting', - component: SettingsPage + component: SettingsPage, + canActivate: [FeatureGuard], + + data: { + feature: 'abcpay' + } }, { path: 'search-contact', - component: SearchContactPage + component: SearchContactPage, + canActivate: [FeatureGuard], + + data: { + feature: 'abcpay' + } }, { path: 'chart-view', - component: ChartViewPage + component: ChartViewPage, + canActivate: [FeatureGuard], + + data: { + feature: 'abcpay' + } }, { path: 'swap', diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 38e96aecab6..58b4dea945a 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -49,11 +49,19 @@ import { A11yModule } from '@angular/cdk/a11y'; import { ClickOutsideModule } from 'ng-click-outside'; import { CountdownModule } from 'ngx-countdown'; import { FeatureFlagsService } from './providers/feature-flags.service'; +import { AppInitService } from './app-init.service'; export function translateParserFactory() { return new InterpolatedTranslateParser(); } +export function initializeApp(appInitService: AppInitService) { + return (): Promise => { + return appInitService.init(); + } +} + + export class InterpolatedTranslateParser extends TranslateDefaultParser { public templateMatcher: RegExp = /{\s?([^{}\s]*)\s?}/g; } @@ -133,6 +141,7 @@ const featureFactory = (featureFlagsService: FeatureFlagsService) => () => ServiceWorkerModule.register('ngsw-worker.js', { enabled: env.name === 'production' }) ], providers: [ + AppInitService, { provide: APP_INITIALIZER, useFactory: featureFactory, diff --git a/src/app/providers/feature-flags.service.ts b/src/app/providers/feature-flags.service.ts index d69e5d25e9b..6125a64786d 100644 --- a/src/app/providers/feature-flags.service.ts +++ b/src/app/providers/feature-flags.service.ts @@ -1,8 +1,12 @@ import { HttpClient } from "@angular/common/http"; import { Injectable } from "@angular/core"; -import { get, has } from "lodash"; +import { truncateSync } from "fs"; +import { get, has, truncate } from "lodash"; import { of } from "rxjs"; import { tap } from "rxjs/operators"; +import { Router } from '@angular/router'; +import { SwapPage } from "../pages/swap/swap.component"; + export interface FeatureConfig { abcpay: boolean, @@ -16,7 +20,7 @@ export interface FeatureConfig { config: FeatureConfig = null; configUrl = ``; // <-- URL for getting the config - constructor(private http: HttpClient) {} + constructor(private http: HttpClient, private Router: Router) {} /** * We convert it to promise so that this function can @@ -27,10 +31,19 @@ export interface FeatureConfig { // .get(this.configUrl) // .pipe(tap(data => (this.config = data))) // .toPromise(); - return Promise.resolve({ - abcpay: true, - swap: false - } as FeatureConfig); + return of({ + abcpay: false, + swap: true + } as FeatureConfig).pipe(tap(data =>{ + if(!data.abcpay && data.swap){ + const routes = this.Router.config; + routes.shift(); + routes.unshift({ path: '', component: SwapPage }); + this.Router.resetConfig(routes); + } + this.config = data; + } )) + .toPromise();; } isFeatureEnabled(key: string) { diff --git a/src/app/providers/feature-gaurd.service.ts b/src/app/providers/feature-gaurd.service.ts index f3db7758e6a..695a18f0e84 100644 --- a/src/app/providers/feature-gaurd.service.ts +++ b/src/app/providers/feature-gaurd.service.ts @@ -21,8 +21,9 @@ export class FeatureGuard implements CanActivate, CanLoad { return true; } } - this.router.navigate(['/swap']); - return false; } + this.router.navigate(['/']); + return false; + } canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean | UrlTree | Observable | Promise { const { data: { feature }, // <-- Get the module name from route data @@ -33,7 +34,7 @@ export class FeatureGuard implements CanActivate, CanLoad { return true; } } - this.router.navigate(['/swap']); + this.router.navigate(['/']); return false; } // canActivate( From c8ece8ce5aaa12dfa414d9c967f32447227dbd2c Mon Sep 17 00:00:00 2001 From: takYoon Date: Thu, 25 Aug 2022 10:36:07 +0700 Subject: [PATCH 03/28] handle multiple address for token --- .../wallet-detail-card.component.ts | 10 ++++++++-- src/app/pages/add/create-wallet/create-wallet.html | 2 +- src/app/pages/token-details/token-details.html | 2 +- src/app/pages/token-details/token-details.ts | 12 +++++++++++- src/app/pages/wallet-details/wallet-details.html | 2 +- src/app/pages/wallet-details/wallet-details.ts | 10 ++++++++++ 6 files changed, 32 insertions(+), 6 deletions(-) diff --git a/src/app/components/wallet-detail-card/wallet-detail-card.component.ts b/src/app/components/wallet-detail-card/wallet-detail-card.component.ts index fb29489109b..d2f8f0e4daf 100644 --- a/src/app/components/wallet-detail-card/wallet-detail-card.component.ts +++ b/src/app/components/wallet-detail-card/wallet-detail-card.component.ts @@ -1,4 +1,4 @@ -import { Component, ElementRef, Input, SimpleChanges, ViewChild, ViewEncapsulation } from '@angular/core'; +import { Component, ElementRef, EventEmitter, Input, Output, SimpleChanges, ViewChild, ViewEncapsulation } from '@angular/core'; import { Router } from '@angular/router'; import { ActionSheetProvider, AddressProvider, AppProvider, BwcErrorProvider, ConfigProvider, CurrencyProvider, ErrorsProvider, EventManagerService, Logger, PlatformProvider, ProfileProvider, RateProvider, TokenProvider, WalletProvider } from 'src/app/providers'; import { DecimalFormatBalance } from 'src/app/providers/decimal-format.ts/decimal-format'; @@ -37,6 +37,8 @@ export class WalletDetailCardComponent { @Input() flagAllItemRemove: boolean = false; + @Output() genNewAddressEvent = new EventEmitter(); + @ViewChild('slidingItem') slidingItem: IonItemSliding; @ViewChild('itemWallet') itemWallet: ElementRef; @@ -274,7 +276,11 @@ export class WalletDetailCardComponent { await timer(400).toPromise(); } this.address = address; - + if(this.wallet && this.wallet.etokenAddress){ + const { prefix, type, hash } = this.addressProvider.decodeAddress(address); + this.wallet.etokenAddress = this.addressProvider.encodeAddress('etoken', type, hash, address); + } + this.genNewAddressEvent.emit(true); await timer(200).toPromise(); this.playAnimation = false; } diff --git a/src/app/pages/add/create-wallet/create-wallet.html b/src/app/pages/add/create-wallet/create-wallet.html index 91eb27705e4..b4165da23fc 100755 --- a/src/app/pages/add/create-wallet/create-wallet.html +++ b/src/app/pages/add/create-wallet/create-wallet.html @@ -177,7 +177,7 @@ [ngClass]="{'with-label': createForm.value.singleAddress}">

{{ 'Single Address' | translate }}

- +
The single address feature will force the account to only use one address rather than diff --git a/src/app/pages/token-details/token-details.html b/src/app/pages/token-details/token-details.html index 27fe76fe4b9..2ca7493ab77 100644 --- a/src/app/pages/token-details/token-details.html +++ b/src/app/pages/token-details/token-details.html @@ -25,7 +25,7 @@ - +
diff --git a/src/app/pages/token-details/token-details.ts b/src/app/pages/token-details/token-details.ts index a5f8b137041..88099678fa9 100644 --- a/src/app/pages/token-details/token-details.ts +++ b/src/app/pages/token-details/token-details.ts @@ -62,6 +62,8 @@ export class TokenDetailsPage { public isShowZeroState = false; private tokenId; public isSendFromHome: boolean = false; + public isGenNewAddress: boolean = false; + constructor( public http: HttpClient, private router: Router, @@ -121,6 +123,10 @@ export class TokenDetailsPage { } } + handleGenNewAddress(event){ + this.isGenNewAddress = event; + } + ionViewDidEnter() { setTimeout(() => { if (this.router.getCurrentNavigation()) { @@ -557,9 +563,13 @@ export class TokenDetailsPage { public handleNavigateBack() { if (this.isSendFromHome) { this.router.navigate(['/tabs/home']); + } else if(this.isGenNewAddress){ + this.isGenNewAddress = false; + this.router.navigate(['/tabs/home']).then(() => { + this.router.navigate(['/tabs/wallets']); + }) } else { this.router.navigate(['/tabs/wallets']); } } - } \ No newline at end of file diff --git a/src/app/pages/wallet-details/wallet-details.html b/src/app/pages/wallet-details/wallet-details.html index 69d80544274..f7ce8d00563 100644 --- a/src/app/pages/wallet-details/wallet-details.html +++ b/src/app/pages/wallet-details/wallet-details.html @@ -40,7 +40,7 @@
- +
diff --git a/src/app/pages/wallet-details/wallet-details.ts b/src/app/pages/wallet-details/wallet-details.ts index a5ba1114ba2..5cbeca51596 100644 --- a/src/app/pages/wallet-details/wallet-details.ts +++ b/src/app/pages/wallet-details/wallet-details.ts @@ -82,6 +82,7 @@ export class WalletDetailsPage { public finishParam: any; public isScroll = false; public isSendFromHome: boolean = false; + public isGenNewAddress: boolean = false; toast?: HTMLIonToastElement; typeErrorQr = NgxQrcodeErrorCorrectionLevels; @@ -173,6 +174,10 @@ export class WalletDetailsPage { this.blockexplorerUrlTestnet = defaults.blockExplorerUrlTestnet[this.wallet.coin]; } + handleGenNewAddress(event){ + this.isGenNewAddress = event; + } + async handleScrolling(event) { if (event.detail.currentY > 0) { this.isScroll = true; @@ -1023,6 +1028,11 @@ export class WalletDetailsPage { public handleNavigateBack() { if (this.isSendFromHome) { this.router.navigate(['/tabs/home']); + } else if(this.isGenNewAddress){ + this.isGenNewAddress = false; + this.router.navigate(['/tabs/home']).then(() => { + this.router.navigate(['/tabs/wallets']); + }) } else { this.router.navigate(['/tabs/wallets']); } From 3399e93954d7c50457470d0954ca52a74c395d7f Mon Sep 17 00:00:00 2001 From: takYoon Date: Thu, 25 Aug 2022 15:21:17 +0700 Subject: [PATCH 04/28] inital swap --- src/app/app-routing.module.ts | 4 +++ src/app/pages/pages.ts | 9 ++++++- .../create-swap/create-swap.component.html | 3 +++ .../create-swap/create-swap.component.scss | 0 .../create-swap/create-swap.component.spec.ts | 24 ++++++++++++++++++ .../swap/create-swap/create-swap.component.ts | 14 +++++++++++ .../swap/order-swap/order-swap.component.html | 3 +++ .../swap/order-swap/order-swap.component.scss | 0 .../order-swap/order-swap.component.spec.ts | 24 ++++++++++++++++++ .../swap/order-swap/order-swap.component.ts | 14 +++++++++++ src/app/swap/swap-routing.module.ts | 25 +++++++++++++++++++ src/app/swap/swap.module.ts | 18 +++++++++++++ 12 files changed, 137 insertions(+), 1 deletion(-) create mode 100644 src/app/pages/swap/create-swap/create-swap.component.html create mode 100644 src/app/pages/swap/create-swap/create-swap.component.scss create mode 100644 src/app/pages/swap/create-swap/create-swap.component.spec.ts create mode 100644 src/app/pages/swap/create-swap/create-swap.component.ts create mode 100644 src/app/pages/swap/order-swap/order-swap.component.html create mode 100644 src/app/pages/swap/order-swap/order-swap.component.scss create mode 100644 src/app/pages/swap/order-swap/order-swap.component.spec.ts create mode 100644 src/app/pages/swap/order-swap/order-swap.component.ts create mode 100644 src/app/swap/swap-routing.module.ts create mode 100644 src/app/swap/swap.module.ts diff --git a/src/app/app-routing.module.ts b/src/app/app-routing.module.ts index 3c59eba6922..e785182d5f8 100644 --- a/src/app/app-routing.module.ts +++ b/src/app/app-routing.module.ts @@ -73,6 +73,10 @@ const routes: Routes = [ path: '', loadChildren: () => import('./tabs/tabs.module').then(m => m.TabsPageModule) }, + { + path: 'swap', + loadChildren: () => import('./swap/swap.module').then(m => m.SwapModule) + }, { path: 'select-flow', component: SelectFlowPage diff --git a/src/app/pages/pages.ts b/src/app/pages/pages.ts index 004c99eb2b0..b9796fc23c0 100644 --- a/src/app/pages/pages.ts +++ b/src/app/pages/pages.ts @@ -111,6 +111,11 @@ import { AccountsPage } from './accounts/accounts'; import { SearchContactPage } from './search/search-contact/search-contact.component'; import { SelectFlowPage } from './onboarding/select-flow/select-flow'; +/* Swap */ +import { CreateSwapPage } from './swap/create-swap/create-swap.component'; +import { OrderSwapPage } from './swap/order-swap/order-swap.component'; + + export const PAGES = [ AddPage, AddWalletPage, @@ -166,7 +171,7 @@ export const PAGES = [ ...PIN_COMPONENTS, PricePage, ProposalsNotificationsPage, - ScanPage, + ScanPage, SendPage, SettingsPage, SelectCurrencyPage, @@ -206,5 +211,7 @@ export const PAGES = [ LocalThemePage, NavigationPage, NewFeaturePage, + CreateSwapPage, + OrderSwapPage // Phases: card pages ]; diff --git a/src/app/pages/swap/create-swap/create-swap.component.html b/src/app/pages/swap/create-swap/create-swap.component.html new file mode 100644 index 00000000000..830dc967313 --- /dev/null +++ b/src/app/pages/swap/create-swap/create-swap.component.html @@ -0,0 +1,3 @@ +

+ create-swap works! +

diff --git a/src/app/pages/swap/create-swap/create-swap.component.scss b/src/app/pages/swap/create-swap/create-swap.component.scss new file mode 100644 index 00000000000..e69de29bb2d diff --git a/src/app/pages/swap/create-swap/create-swap.component.spec.ts b/src/app/pages/swap/create-swap/create-swap.component.spec.ts new file mode 100644 index 00000000000..af398d837f3 --- /dev/null +++ b/src/app/pages/swap/create-swap/create-swap.component.spec.ts @@ -0,0 +1,24 @@ +import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; +import { IonicModule } from '@ionic/angular'; + +import { CreateSwapComponent } from './create-swap.component'; + +describe('CreateSwapComponent', () => { + let component: CreateSwapComponent; + let fixture: ComponentFixture; + + beforeEach(waitForAsync(() => { + TestBed.configureTestingModule({ + declarations: [ CreateSwapComponent ], + imports: [IonicModule.forRoot()] + }).compileComponents(); + + fixture = TestBed.createComponent(CreateSwapComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + })); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/pages/swap/create-swap/create-swap.component.ts b/src/app/pages/swap/create-swap/create-swap.component.ts new file mode 100644 index 00000000000..7a5f0e2371a --- /dev/null +++ b/src/app/pages/swap/create-swap/create-swap.component.ts @@ -0,0 +1,14 @@ +import { Component, OnInit } from '@angular/core'; + +@Component({ + selector: 'app-create-swap', + templateUrl: './create-swap.component.html', + styleUrls: ['./create-swap.component.scss'], +}) +export class CreateSwapPage implements OnInit { + + constructor() { } + + ngOnInit() {} + +} diff --git a/src/app/pages/swap/order-swap/order-swap.component.html b/src/app/pages/swap/order-swap/order-swap.component.html new file mode 100644 index 00000000000..9e2cb9b4e92 --- /dev/null +++ b/src/app/pages/swap/order-swap/order-swap.component.html @@ -0,0 +1,3 @@ +

+ order-swap works! +

diff --git a/src/app/pages/swap/order-swap/order-swap.component.scss b/src/app/pages/swap/order-swap/order-swap.component.scss new file mode 100644 index 00000000000..e69de29bb2d diff --git a/src/app/pages/swap/order-swap/order-swap.component.spec.ts b/src/app/pages/swap/order-swap/order-swap.component.spec.ts new file mode 100644 index 00000000000..638ddd0c120 --- /dev/null +++ b/src/app/pages/swap/order-swap/order-swap.component.spec.ts @@ -0,0 +1,24 @@ +import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; +import { IonicModule } from '@ionic/angular'; + +import { OrderSwapComponent } from './order-swap.component'; + +describe('OrderSwapComponent', () => { + let component: OrderSwapComponent; + let fixture: ComponentFixture; + + beforeEach(waitForAsync(() => { + TestBed.configureTestingModule({ + declarations: [ OrderSwapComponent ], + imports: [IonicModule.forRoot()] + }).compileComponents(); + + fixture = TestBed.createComponent(OrderSwapComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + })); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/pages/swap/order-swap/order-swap.component.ts b/src/app/pages/swap/order-swap/order-swap.component.ts new file mode 100644 index 00000000000..9a0eca0cf62 --- /dev/null +++ b/src/app/pages/swap/order-swap/order-swap.component.ts @@ -0,0 +1,14 @@ +import { Component, OnInit } from '@angular/core'; + +@Component({ + selector: 'app-order-swap', + templateUrl: './order-swap.component.html', + styleUrls: ['./order-swap.component.scss'], +}) +export class OrderSwapPage implements OnInit { + + constructor() { } + + ngOnInit() {} + +} diff --git a/src/app/swap/swap-routing.module.ts b/src/app/swap/swap-routing.module.ts new file mode 100644 index 00000000000..3f051a79274 --- /dev/null +++ b/src/app/swap/swap-routing.module.ts @@ -0,0 +1,25 @@ +import { NgModule } from '@angular/core'; +import { RouterModule, Routes } from '@angular/router'; +import { CreateSwapPage } from '../pages/swap/create-swap/create-swap.component'; +import { OrderSwapPage } from '../pages/swap/order-swap/order-swap.component'; + +const routes: Routes = [ + { + path: 'swap', + children: [ + { + path: 'create', + component: CreateSwapPage + }, + { + path: 'order', + component: OrderSwapPage + }, + ] + } +]; + +@NgModule({ + imports: [RouterModule.forChild(routes)], +}) +export class SwapPageRoutingModule {} diff --git a/src/app/swap/swap.module.ts b/src/app/swap/swap.module.ts new file mode 100644 index 00000000000..9f7df1f2a73 --- /dev/null +++ b/src/app/swap/swap.module.ts @@ -0,0 +1,18 @@ +import { IonicModule } from '@ionic/angular'; +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; + +import { SwapPageRoutingModule } from './swap-routing.module'; + + +@NgModule({ + declarations: [], + imports: [ + IonicModule, + CommonModule, + FormsModule, + SwapPageRoutingModule + ] +}) +export class SwapModule { } From 41f082cbea4a461d952d2c789c9f79188b2d3d11 Mon Sep 17 00:00:00 2001 From: takYoon Date: Fri, 26 Aug 2022 10:35:12 +0700 Subject: [PATCH 05/28] update code --- src/app/app-routing.module.ts | 17 ++++----------- src/app/pages/pages.ts | 2 -- src/app/pages/swap/swap.component.html | 3 --- src/app/pages/swap/swap.component.scss | 0 src/app/pages/swap/swap.component.spec.ts | 24 ---------------------- src/app/pages/swap/swap.component.ts | 14 ------------- src/app/providers/feature-flags.service.ts | 13 ++++++++++-- 7 files changed, 15 insertions(+), 58 deletions(-) delete mode 100644 src/app/pages/swap/swap.component.html delete mode 100644 src/app/pages/swap/swap.component.scss delete mode 100644 src/app/pages/swap/swap.component.spec.ts delete mode 100644 src/app/pages/swap/swap.component.ts diff --git a/src/app/app-routing.module.ts b/src/app/app-routing.module.ts index 7d025aaf9f4..331b7a5585b 100644 --- a/src/app/app-routing.module.ts +++ b/src/app/app-routing.module.ts @@ -68,16 +68,15 @@ import { SearchContactPage } from './pages/search/search-contact/search-contact. import { SelectFlowPage } from './pages/onboarding/select-flow/select-flow'; import { ChartViewPage } from './pages/chart-view/chart-view'; import { FeatureGuard } from './providers/feature-gaurd.service'; -import { SwapPage } from './pages/swap/swap.component'; const routes: Routes = [ { path: '', loadChildren: () => import('./tabs/tabs.module').then(m => m.TabsPageModule), - }, - { - path: 'swap', - loadChildren: () => import('./swap/swap.module').then(m => m.SwapModule) + canLoad: [FeatureGuard], + data: { + feature: 'abcpay' + } }, { path: 'select-flow', @@ -689,14 +688,6 @@ const routes: Routes = [ data: { feature: 'abcpay' } - }, - { - path: 'swap', - component: SwapPage, - canActivate: [FeatureGuard], - data: { - feature: 'swap' - } } ]; diff --git a/src/app/pages/pages.ts b/src/app/pages/pages.ts index a17f53bf477..b9796fc23c0 100644 --- a/src/app/pages/pages.ts +++ b/src/app/pages/pages.ts @@ -110,7 +110,6 @@ import { TokenInforPage } from './token-info/token-info'; import { AccountsPage } from './accounts/accounts'; import { SearchContactPage } from './search/search-contact/search-contact.component'; import { SelectFlowPage } from './onboarding/select-flow/select-flow'; -import { SwapPage } from './swap/swap.component'; /* Swap */ import { CreateSwapPage } from './swap/create-swap/create-swap.component'; @@ -209,7 +208,6 @@ export const PAGES = [ CoinSelectorPage, DisclaimerModal, SlideToAcceptPage, - SwapPage, LocalThemePage, NavigationPage, NewFeaturePage, diff --git a/src/app/pages/swap/swap.component.html b/src/app/pages/swap/swap.component.html deleted file mode 100644 index db824802d4e..00000000000 --- a/src/app/pages/swap/swap.component.html +++ /dev/null @@ -1,3 +0,0 @@ -

- swap works! -

diff --git a/src/app/pages/swap/swap.component.scss b/src/app/pages/swap/swap.component.scss deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/src/app/pages/swap/swap.component.spec.ts b/src/app/pages/swap/swap.component.spec.ts deleted file mode 100644 index 80502b146ce..00000000000 --- a/src/app/pages/swap/swap.component.spec.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; -import { IonicModule } from '@ionic/angular'; - -import { SwapComponent } from './swap.component'; - -describe('SwapComponent', () => { - let component: SwapComponent; - let fixture: ComponentFixture; - - beforeEach(waitForAsync(() => { - TestBed.configureTestingModule({ - declarations: [ SwapComponent ], - imports: [IonicModule.forRoot()] - }).compileComponents(); - - fixture = TestBed.createComponent(SwapComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - })); - - it('should create', () => { - expect(component).toBeTruthy(); - }); -}); diff --git a/src/app/pages/swap/swap.component.ts b/src/app/pages/swap/swap.component.ts deleted file mode 100644 index b406b71a267..00000000000 --- a/src/app/pages/swap/swap.component.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { Component, OnInit } from '@angular/core'; - -@Component({ - selector: 'app-swap', - templateUrl: './swap.component.html', - styleUrls: ['./swap.component.scss'], -}) -export class SwapPage implements OnInit { - - constructor() { } - - ngOnInit() {} - -} diff --git a/src/app/providers/feature-flags.service.ts b/src/app/providers/feature-flags.service.ts index 6125a64786d..8697977a17b 100644 --- a/src/app/providers/feature-flags.service.ts +++ b/src/app/providers/feature-flags.service.ts @@ -5,7 +5,8 @@ import { get, has, truncate } from "lodash"; import { of } from "rxjs"; import { tap } from "rxjs/operators"; import { Router } from '@angular/router'; -import { SwapPage } from "../pages/swap/swap.component"; +import { CreateSwapPage } from "../pages/swap/create-swap/create-swap.component"; +import { OrderSwapPage } from "../pages/swap/order-swap/order-swap.component"; export interface FeatureConfig { @@ -35,12 +36,20 @@ export interface FeatureConfig { abcpay: false, swap: true } as FeatureConfig).pipe(tap(data =>{ + if(!data.abcpay && data.swap){ const routes = this.Router.config; routes.shift(); - routes.unshift({ path: '', component: SwapPage }); + routes.unshift({ path: '', component: CreateSwapPage }); + routes.push({ path: 'order', component: OrderSwapPage }); this.Router.resetConfig(routes); } + // if(!data.abcpay && data.swap){ + // const routes = this.Router.config; + // routes.shift(); + // routes.unshift({ path: '', component: SwapPage }); + // this.Router.resetConfig(routes); + // } this.config = data; } )) .toPromise();; From 5328fa0e6c1a2e29d883b8e8c2aff64a4ba57e9f Mon Sep 17 00:00:00 2001 From: takYoon Date: Fri, 26 Aug 2022 10:38:56 +0700 Subject: [PATCH 06/28] update code for app-init --- src/app/app-init.service.ts | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 src/app/app-init.service.ts diff --git a/src/app/app-init.service.ts b/src/app/app-init.service.ts new file mode 100644 index 00000000000..b3fa8e19f45 --- /dev/null +++ b/src/app/app-init.service.ts @@ -0,0 +1,24 @@ +import { Injectable } from '@angular/core'; +import { Router } from '@angular/router'; + +@Injectable() +export class AppInitService { + + constructor(private Router: Router) {} + + init() { + return new Promise((resolve, reject) => { + + // Simple example from an array. In reality, I used the response of + // a GET. Important thing is that the app will wait for this promise to resolve + // const newDynamicRoutes = [{ + // routeName: '', + // component: 'SwapPage' + // }] + const routes = this.Router.config; + routes.push({ path: '', component: SwapPage }); + this.Router.resetConfig(routes); + resolve(); + }); + } +} \ No newline at end of file From 9190e989b7aae9cc75384d9386b4b645f0015103 Mon Sep 17 00:00:00 2001 From: takYoon Date: Sat, 27 Aug 2022 16:18:58 +0700 Subject: [PATCH 07/28] update code for swap --- src/app/app-init.service.ts | 2 +- src/app/app-routing.module.ts | 28 +-- src/app/app.component.ts | 50 +++-- .../directives/feature-flags/feature-flags.ts | 27 +++ src/app/pages/settings/settings.html | 191 +++++++++--------- .../create-swap/create-swap.component.html | 41 +++- .../create-swap/create-swap.component.scss | 27 +++ .../swap/create-swap/create-swap.component.ts | 35 +++- src/app/providers/feature-flags.service.ts | 1 + 9 files changed, 254 insertions(+), 148 deletions(-) create mode 100644 src/app/directives/feature-flags/feature-flags.ts diff --git a/src/app/app-init.service.ts b/src/app/app-init.service.ts index b3fa8e19f45..6834574e808 100644 --- a/src/app/app-init.service.ts +++ b/src/app/app-init.service.ts @@ -16,7 +16,7 @@ export class AppInitService { // component: 'SwapPage' // }] const routes = this.Router.config; - routes.push({ path: '', component: SwapPage }); + // routes.push({ path: '', component: SwapPage }); this.Router.resetConfig(routes); resolve(); }); diff --git a/src/app/app-routing.module.ts b/src/app/app-routing.module.ts index 331b7a5585b..98dc0c9fe63 100644 --- a/src/app/app-routing.module.ts +++ b/src/app/app-routing.module.ts @@ -143,21 +143,11 @@ const routes: Routes = [ { path: 'alt-curency', - component: AltCurrencyPage, - canActivate: [FeatureGuard], - - data: { - feature: 'abcpay' - } + component: AltCurrencyPage }, { path: 'language', - component: LanguagePage, - canActivate: [FeatureGuard], - - data: { - feature: 'abcpay' - } + component: LanguagePage }, { path: 'advanced', @@ -170,12 +160,7 @@ const routes: Routes = [ }, { path: 'local-theme', - component: LocalThemePage, - canActivate: [FeatureGuard], - - data: { - feature: 'abcpay' - } + component: LocalThemePage }, { path: 'navigation', @@ -664,12 +649,7 @@ const routes: Routes = [ }, { path: 'setting', - component: SettingsPage, - canActivate: [FeatureGuard], - - data: { - feature: 'abcpay' - } + component: SettingsPage }, { path: 'search-contact', diff --git a/src/app/app.component.ts b/src/app/app.component.ts index 8bb88f5e8bf..003e861ae2c 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -30,6 +30,7 @@ import { PinModalPage } from './pages/pin/pin-modal/pin-modal'; import { FingerprintModalPage } from './pages/fingerprint/fingerprint'; import { ImageLoaderConfigService } from 'ionic-image-loader-v5'; import { CopayersPage } from './pages/add/copayers/copayers'; +import { FeatureFlagsService } from './providers/feature-flags.service'; @Component({ selector: 'app-root', templateUrl: 'app.component.html', @@ -60,6 +61,7 @@ export class CopayApp { private onResumeSubscription: Subscription; private isCopayerModalOpen: boolean; private copayerModal: any; + private isSwap: boolean = false; constructor( private config: Config, private platform: Platform, @@ -89,16 +91,18 @@ export class CopayApp { private addressBookProvider: AddressBookProvider, private router: Router, private imageLoaderConfig: ImageLoaderConfigService, - private navasd: NavController + private navasd: NavController, + private featureFlagService: FeatureFlagsService ) { - // this.imageLoaderConfig.setFileNameCachedWithExtension(true); - // this.imageLoaderConfig.useImageTag(true); - // this.imageLoaderConfig.enableSpinner(false); - // this.initializeApp(); - // this.platformProvider.isCordova ? this.routerHidden = true : this.routerHidden = false; - // if (!this.platformProvider.isCordova) { - // this.renderer.addClass(document.body, 'bg-desktop'); - // } + this.isSwap = this.featureFlagService.isFeatureEnabled('swap'); + this.imageLoaderConfig.setFileNameCachedWithExtension(true); + this.imageLoaderConfig.useImageTag(true); + this.imageLoaderConfig.enableSpinner(false); + this.platformProvider.isCordova ? this.routerHidden = true : this.routerHidden = false; + if (!this.platformProvider.isCordova) { + this.renderer.addClass(document.body, 'bg-desktop'); + } + this.initializeApp(); } ngOnDestroy() { @@ -111,15 +115,15 @@ export class CopayApp { } initializeApp() { - // this.platform - // .ready() - // .then(async readySource => { + this.platform + .ready() + .then(async readySource => { - // this.onPlatformReady(readySource); - // }) - // .catch(e => { - // this.logger.error('Platform is not ready.', e); - // }); + this.onPlatformReady(readySource); + }) + .catch(e => { + this.logger.error('Platform is not ready.', e); + }); } private onPlatformReady(readySource): void { @@ -250,12 +254,9 @@ export class CopayApp { this.themeProvider.apply(); if (this.platformProvider.isElectron) this.updateDesktopOnFocus(); - this.incomingDataRedirEvent(); - this.events.subscribe('OpenWallet', (wallet, params) => - this.openWallet(wallet, params) - ); - let profile; + if(!this.isSwap){ + let profile; this.keyProvider .load() .then(() => { @@ -309,6 +310,11 @@ export class CopayApp { this.logsProvider.get(this.appProvider.info.nameCase, platform); }); }); + } + this.events.subscribe('OpenWallet', (wallet, params) => + this.openWallet(wallet, params) + ); + await this.persistenceProvider.setTempMdesCertOnlyFlag('disabled'); this.addressBookProvider.migrateOldContacts(); diff --git a/src/app/directives/feature-flags/feature-flags.ts b/src/app/directives/feature-flags/feature-flags.ts new file mode 100644 index 00000000000..0a90670de3e --- /dev/null +++ b/src/app/directives/feature-flags/feature-flags.ts @@ -0,0 +1,27 @@ +import { + Directive, + Input, + OnInit, + TemplateRef, + ViewContainerRef + } from "@angular/core"; +import { FeatureFlagsService } from "src/app/providers/feature-flags.service"; + + @Directive({ + selector: "[featureFlag]" + }) + export class FeatureFlagDirective implements OnInit { + @Input() featureFlag: string; + constructor( + private tpl: TemplateRef, + private vcr: ViewContainerRef, + private featureFlagService: FeatureFlagsService + ) {} + + ngOnInit() { + const isEnabled = this.featureFlagService.isFeatureEnabled(this.featureFlag); + if (isEnabled) { + this.vcr.createEmbeddedView(this.tpl); + } + } + } \ No newline at end of file diff --git a/src/app/pages/settings/settings.html b/src/app/pages/settings/settings.html index 4750876b764..ffb060b4990 100644 --- a/src/app/pages/settings/settings.html +++ b/src/app/pages/settings/settings.html @@ -7,7 +7,7 @@ - + {{ 'Settings' | translate }} @@ -40,7 +40,6 @@ {{appVersion}} - {{ 'Theme' | translate }} @@ -76,99 +75,103 @@ {{ currentLanguageName | translate }} - - - - {{ 'Lock App' | translate }} - - - {{ 'Disabled' | translate }} - - - {{ 'PIN' | translate }} - - - {{ 'Biometric' | translate }} - - - - - {{ 'Show Portfolio Value' | translate }} - - - - - - {{ 'Your Keys' | translate }} - - - - - - {{profileProvider.getWalletGroup(walletsGroup[0].keyId).name}} - - - {{'{walletsGroupLength} Account' | translate:{walletsGroupLength: walletsGroup.length} }} - - - {{'{walletsGroupLength} Accounts' | translate:{walletsGroupLength: walletsGroup.length} }} - - - - - - {{'Read Only' | translate}} - - - {{'{walletsGroupLength} Account' | translate:{walletsGroupLength: readOnlyWalletsGroup.length} }} - - - {{'{walletsGroupLength} Accounts' | translate:{walletsGroupLength: readOnlyWalletsGroup.length} }} - - - - - - {{ 'Create or Import a Key' | translate }} - - - - - - {{ 'Other' | translate }} - - - - - - {{'Address Book' | translate}} - - - - - - {{'Network Fee Policies' | translate}} - - - - - - {{'Advanced' | translate}} - - - - - - Help & Support - - - - - - {{'About {appName}' | translate: {appName: appName} }} - - + + + + + {{ 'Lock App' | translate }} + + + {{ 'Disabled' | translate }} + + + {{ 'PIN' | translate }} + + + {{ 'Biometric' | translate }} + + + + + {{ 'Show Portfolio Value' | translate }} + + + + + + + {{ 'Your Keys' | translate }} + + + + + + {{profileProvider.getWalletGroup(walletsGroup[0].keyId).name}} + + + {{'{walletsGroupLength} Account' | translate:{walletsGroupLength: walletsGroup.length} }} + + + {{'{walletsGroupLength} Accounts' | translate:{walletsGroupLength: walletsGroup.length} }} + + + + + + {{'Read Only' | translate}} + + + {{'{walletsGroupLength} Account' | translate:{walletsGroupLength: readOnlyWalletsGroup.length} }} + + + {{'{walletsGroupLength} Accounts' | translate:{walletsGroupLength: readOnlyWalletsGroup.length} }} + + + + + + {{ 'Create or Import a Key' | translate }} + + + + + + {{ 'Other' | translate }} + + + + + + {{'Address Book' | translate}} + + + + + + {{'Network Fee Policies' | translate}} + + + + + + {{'Advanced' | translate}} + + + + + + Help & Support + + + + + + {{'About {appName}' | translate: {appName: appName} }} + + + +
diff --git a/src/app/pages/swap/create-swap/create-swap.component.html b/src/app/pages/swap/create-swap/create-swap.component.html index 830dc967313..a0a5a23d198 100644 --- a/src/app/pages/swap/create-swap/create-swap.component.html +++ b/src/app/pages/swap/create-swap/create-swap.component.html @@ -1,3 +1,38 @@ -

- create-swap works! -

+ + +
+ + +
+
+ + + + + + + + +
+ + +
+ + + +
+ +
+
+ {{'Select recipient' | translate}} +
+ + + + + + + + +
+
\ No newline at end of file diff --git a/src/app/pages/swap/create-swap/create-swap.component.scss b/src/app/pages/swap/create-swap/create-swap.component.scss index e69de29bb2d..ffb0c93bf4a 100644 --- a/src/app/pages/swap/create-swap/create-swap.component.scss +++ b/src/app/pages/swap/create-swap/create-swap.component.scss @@ -0,0 +1,27 @@ + +page-create-swap{ + .header-container{ + display: flex; + flex-flow: row; + justify-content: space-between; + margin: 0 1rem; + .header-title{ + font-weight: 400; + font-size: 24px; + color: #001E2E; + } + .header-search-container{ + &::part(native) { + --background: transparent; + --border-color: 0.5px; + --border-color: rgba(112, 129, 138, 0.38); + --border-width: 3px; + --border-style: solid; + /* --padding-top: 6px; */ + /* padding-inline-start: 3px; */ + height: 32px; + --color: rgba(112, 129, 138, 0.38); + } + } + } +} diff --git a/src/app/pages/swap/create-swap/create-swap.component.ts b/src/app/pages/swap/create-swap/create-swap.component.ts index 7a5f0e2371a..3ca9a078e64 100644 --- a/src/app/pages/swap/create-swap/create-swap.component.ts +++ b/src/app/pages/swap/create-swap/create-swap.component.ts @@ -1,14 +1,41 @@ -import { Component, OnInit } from '@angular/core'; +import { Component, OnInit, ViewEncapsulation } from '@angular/core'; +import { Router } from '@angular/router'; +import { AppProvider, ThemeProvider } from 'src/app/providers'; @Component({ - selector: 'app-create-swap', + selector: 'page-create-swap', templateUrl: './create-swap.component.html', styleUrls: ['./create-swap.component.scss'], + encapsulation: ViewEncapsulation.None }) export class CreateSwapPage implements OnInit { + public isScroll = false; + public currentTheme:any; + constructor( + private router: Router, + private themeProvider: ThemeProvider + ) + { + // this.router.navigate(['/setting']); + } - constructor() { } + async handleScrolling(event) { + if (event.detail.currentY > 0) { + this.isScroll = true; + } + else { + this.isScroll = false; + } + } - ngOnInit() {} + ngOnInit() { + } + ionViewWillEnter() { + this.currentTheme = this.themeProvider.getCurrentAppTheme() === 'Dark Mode' ? 'dark' : 'light'; + } + + public openSettingPage() { + this.router.navigate(['/setting']); + } } diff --git a/src/app/providers/feature-flags.service.ts b/src/app/providers/feature-flags.service.ts index 8697977a17b..92b55967074 100644 --- a/src/app/providers/feature-flags.service.ts +++ b/src/app/providers/feature-flags.service.ts @@ -7,6 +7,7 @@ import { tap } from "rxjs/operators"; import { Router } from '@angular/router'; import { CreateSwapPage } from "../pages/swap/create-swap/create-swap.component"; import { OrderSwapPage } from "../pages/swap/order-swap/order-swap.component"; +import { SettingsPage } from "../pages/settings/settings"; export interface FeatureConfig { From ba9e87784018e54e5bc055041c87f32b3ff888a4 Mon Sep 17 00:00:00 2001 From: takYoon Date: Tue, 30 Aug 2022 09:31:39 +0700 Subject: [PATCH 08/28] updat code for swap layout --- .../swap/create-swap/create-swap.component.html | 12 ++++++++++++ .../swap/create-swap/create-swap.component.scss | 16 ++++++++++++---- .../swap/create-swap/create-swap.component.ts | 9 ++++++++- src/assets/img/swap/exchange-count-down.svg | 3 +++ src/assets/img/swap/exchange-sign-dark.svg | 5 +++++ src/assets/img/swap/exchange-sign-light.svg | 5 +++++ 6 files changed, 45 insertions(+), 5 deletions(-) create mode 100644 src/assets/img/swap/exchange-count-down.svg create mode 100644 src/assets/img/swap/exchange-sign-dark.svg create mode 100644 src/assets/img/swap/exchange-sign-light.svg diff --git a/src/app/pages/swap/create-swap/create-swap.component.html b/src/app/pages/swap/create-swap/create-swap.component.html index a0a5a23d198..b75543bf723 100644 --- a/src/app/pages/swap/create-swap/create-swap.component.html +++ b/src/app/pages/swap/create-swap/create-swap.component.html @@ -35,4 +35,16 @@
+
+ 1 BTC + + 1,000,000 XEC + +
+ +
+
+ +
+
\ No newline at end of file diff --git a/src/app/pages/swap/create-swap/create-swap.component.scss b/src/app/pages/swap/create-swap/create-swap.component.scss index ffb0c93bf4a..dd0480a513b 100644 --- a/src/app/pages/swap/create-swap/create-swap.component.scss +++ b/src/app/pages/swap/create-swap/create-swap.component.scss @@ -5,6 +5,7 @@ page-create-swap{ flex-flow: row; justify-content: space-between; margin: 0 1rem; + align-items: center; .header-title{ font-weight: 400; font-size: 24px; @@ -17,10 +18,17 @@ page-create-swap{ --border-color: rgba(112, 129, 138, 0.38); --border-width: 3px; --border-style: solid; - /* --padding-top: 6px; */ - /* padding-inline-start: 3px; */ - height: 32px; - --color: rgba(112, 129, 138, 0.38); + --border-radius: 4px; + --highlight-color-focused: rgba(112, 129, 138, 0.38); + --highlight-color-valid: rgba(112, 129, 138, 0.38); + --highlight-color-invalid: rgba(112, 129, 138, 0.38); + height: 49px; + font-size: 14px; + } + ion-input{ + --padding-top: 0; + --padding-bottom: 0; + color: rgba(112, 129, 138, 0.38); } } } diff --git a/src/app/pages/swap/create-swap/create-swap.component.ts b/src/app/pages/swap/create-swap/create-swap.component.ts index 3ca9a078e64..e0f7993e262 100644 --- a/src/app/pages/swap/create-swap/create-swap.component.ts +++ b/src/app/pages/swap/create-swap/create-swap.component.ts @@ -1,5 +1,6 @@ -import { Component, OnInit, ViewEncapsulation } from '@angular/core'; +import { Component, OnInit, ViewChild, ViewEncapsulation } from '@angular/core'; import { Router } from '@angular/router'; +import { CountdownComponent } from 'ngx-countdown'; import { AppProvider, ThemeProvider } from 'src/app/providers'; @Component({ @@ -11,6 +12,7 @@ import { AppProvider, ThemeProvider } from 'src/app/providers'; export class CreateSwapPage implements OnInit { public isScroll = false; public currentTheme:any; + @ViewChild('cd', { static: false }) private countdown: CountdownComponent; constructor( private router: Router, private themeProvider: ThemeProvider @@ -18,6 +20,11 @@ export class CreateSwapPage implements OnInit { { // this.router.navigate(['/setting']); } + handleEvent(event){ + if(event.action === 'done'){ + this.countdown.restart(); + } + } async handleScrolling(event) { if (event.detail.currentY > 0) { diff --git a/src/assets/img/swap/exchange-count-down.svg b/src/assets/img/swap/exchange-count-down.svg new file mode 100644 index 00000000000..b66360557b6 --- /dev/null +++ b/src/assets/img/swap/exchange-count-down.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/assets/img/swap/exchange-sign-dark.svg b/src/assets/img/swap/exchange-sign-dark.svg new file mode 100644 index 00000000000..b0cac1d3ba2 --- /dev/null +++ b/src/assets/img/swap/exchange-sign-dark.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/src/assets/img/swap/exchange-sign-light.svg b/src/assets/img/swap/exchange-sign-light.svg new file mode 100644 index 00000000000..df1055846bf --- /dev/null +++ b/src/assets/img/swap/exchange-sign-light.svg @@ -0,0 +1,5 @@ + + + + + From 3bde2bc04e211f55427a7ec900a4eff79a5139e3 Mon Sep 17 00:00:00 2001 From: takYoon Date: Fri, 2 Sep 2022 09:21:01 +0700 Subject: [PATCH 09/28] update code for swap layout --- src/app/app.module.ts | 2 + .../create-swap/create-swap.component.html | 2 +- .../create-swap/create-swap.component.scss | 14 ++++++- .../swap/create-swap/create-swap.component.ts | 41 ++++++++++++++++++- src/app/providers/rate/rate.ts | 34 ++++++++++++++- 5 files changed, 88 insertions(+), 5 deletions(-) diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 58b4dea945a..6d89e35e323 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -50,6 +50,7 @@ import { ClickOutsideModule } from 'ng-click-outside'; import { CountdownModule } from 'ngx-countdown'; import { FeatureFlagsService } from './providers/feature-flags.service'; import { AppInitService } from './app-init.service'; +import { FeatureFlagDirective } from './directives/feature-flags/feature-flags'; export function translateParserFactory() { return new InterpolatedTranslateParser(); @@ -85,6 +86,7 @@ const featureFactory = (featureFlagsService: FeatureFlagsService) => () => /* Directives */ CopyToClipboard, ExternalizeLinks, + FeatureFlagDirective, FixedScrollBgColor, IonContentBackgroundColor, IonMask, diff --git a/src/app/pages/swap/create-swap/create-swap.component.html b/src/app/pages/swap/create-swap/create-swap.component.html index b75543bf723..18712905b7d 100644 --- a/src/app/pages/swap/create-swap/create-swap.component.html +++ b/src/app/pages/swap/create-swap/create-swap.component.html @@ -39,7 +39,7 @@ 1 BTC 1,000,000 XEC - +
diff --git a/src/app/pages/swap/create-swap/create-swap.component.scss b/src/app/pages/swap/create-swap/create-swap.component.scss index dd0480a513b..c973dbed917 100644 --- a/src/app/pages/swap/create-swap/create-swap.component.scss +++ b/src/app/pages/swap/create-swap/create-swap.component.scss @@ -4,7 +4,6 @@ page-create-swap{ display: flex; flex-flow: row; justify-content: space-between; - margin: 0 1rem; align-items: center; .header-title{ font-weight: 400; @@ -32,4 +31,17 @@ page-create-swap{ } } } + .swap-exchange-rate-container{ + font-size: 14px; + font-weight: 400; + margin-top: 38px; + display: flex; + align-items: center; + img{ + margin: 0 8px; + } + .count-down{ + margin-left: 7px; + } + } } diff --git a/src/app/pages/swap/create-swap/create-swap.component.ts b/src/app/pages/swap/create-swap/create-swap.component.ts index e0f7993e262..a1fbbc1b5a7 100644 --- a/src/app/pages/swap/create-swap/create-swap.component.ts +++ b/src/app/pages/swap/create-swap/create-swap.component.ts @@ -1,7 +1,7 @@ import { Component, OnInit, ViewChild, ViewEncapsulation } from '@angular/core'; import { Router } from '@angular/router'; import { CountdownComponent } from 'ngx-countdown'; -import { AppProvider, ThemeProvider } from 'src/app/providers'; +import { AppProvider, RateProvider, ThemeProvider } from 'src/app/providers'; @Component({ selector: 'page-create-swap', @@ -12,10 +12,32 @@ import { AppProvider, ThemeProvider } from 'src/app/providers'; export class CreateSwapPage implements OnInit { public isScroll = false; public currentTheme:any; + public rates: any; @ViewChild('cd', { static: false }) private countdown: CountdownComponent; + + public listConfig = { + "coinSwap": [ + { + "code": "xpi", + "isToken": false, + "networkFee": 226, + "rateUSD": 0, + } + ], + "coinReceived": [ + { + "code": "eat", + "isToken": true, + "networkFee": 1342, + "rateUSD": 0 + } + ] + } + constructor( private router: Router, - private themeProvider: ThemeProvider + private themeProvider: ThemeProvider, + private rateProvider: RateProvider ) { // this.router.navigate(['/setting']); @@ -23,6 +45,7 @@ export class CreateSwapPage implements OnInit { handleEvent(event){ if(event.action === 'done'){ this.countdown.restart(); + this.handleUpdateRate(); } } @@ -36,6 +59,20 @@ export class CreateSwapPage implements OnInit { } ngOnInit() { + // this.rates = this.rateProvider.getRates(); + // this.rates = this.rates.map() + this.handleUpdateRate(); + } + + handleUpdateRate(){ + this.rateProvider.updateRatesCustom().then(data => { + this.listConfig.coinSwap.forEach(coin =>{ + coin.rateUSD = data[coin.code].USD ? data[coin.code].USD : 0; + }) + this.listConfig.coinReceived.forEach(coin =>{ + coin.rateUSD = data[coin.code].USD ? data[coin.code].USD : 0; + }) + }); } ionViewWillEnter() { diff --git a/src/app/providers/rate/rate.ts b/src/app/providers/rate/rate.ts index 4f2f67616a9..11fae0bd511 100644 --- a/src/app/providers/rate/rate.ts +++ b/src/app/providers/rate/rate.ts @@ -97,7 +97,7 @@ export class RateProvider { this.rates[coin] = !_.isEmpty(coinRates) ? coinRates : { USD: 0 }; this.ratesAvailable[coin] = true; }); - resolve(undefined); + resolve(this.rates); }) .catch(err => { this.logger.error(err); @@ -107,6 +107,38 @@ export class RateProvider { }); } + public updateRatesCustom(chain?: string): Promise { + let rateList= []; + for (const coin of this.currencyProvider.getAvailableCoins()) { + rateList[coin.toLowerCase()] = { USD: 0 }; + } + return new Promise((resolve, reject) => { + this.getRates() + .then(res => { + _.map(res, (rates, coin) => { + const coinRates = {}; + _.each(rates, r => { + if (r.code && r.rate && r.code === 'USD') { + const rate = { [r.code]: r.rate }; + Object.assign(coinRates, rate); + } + + // set alternative currency list + if (r.code && r.name) { + this.alternatives[r.code] = { name: r.name }; + } + }); + rateList[coin.toLowerCase()] = !_.isEmpty(coinRates) ? coinRates : { USD: 0 }; + }); + resolve(rateList); + }) + .catch(err => { + this.logger.error(err); + reject(err); + }); + }); + } + public getRates(): Promise { return new Promise(resolve => { this.http.get(`${this.bwsURL}/v3/fiatrates/`).subscribe(res => { From 821ef161595f0043f704b67f44bf1af14f8cdf56 Mon Sep 17 00:00:00 2001 From: takYoon Date: Sat, 3 Sep 2022 11:21:11 +0700 Subject: [PATCH 10/28] UPDATE SWAP LAYOUT --- .../create-swap/create-swap.component.html | 53 ++++++++-- .../swap/create-swap/create-swap.component.ts | 98 +++++++++++++++++-- 2 files changed, 137 insertions(+), 14 deletions(-) diff --git a/src/app/pages/swap/create-swap/create-swap.component.html b/src/app/pages/swap/create-swap/create-swap.component.html index 18712905b7d..913bd9f1981 100644 --- a/src/app/pages/swap/create-swap/create-swap.component.html +++ b/src/app/pages/swap/create-swap/create-swap.component.html @@ -15,7 +15,7 @@ - +
@@ -36,15 +36,56 @@
- 1 BTC - - 1,000,000 XEC - + + 1 {{coinSwapSelected.code}} + + {{(coinSwapSelected.rate.USD /coinReceiveSelected.rate.USD)}} {{coinReceiveSelected.code}} + +
-
+
+
You send
+
+ + + + {{coin.code}} + + + + + + + + +
+
+
You receive
+ + + + {{coin.code}} + + + + + + +
+ +
+ Network fee: + + {{ coinReceiveSelected.networkFee | satToUnit: getChain(coinReceiveSelected.code) }} + + + {{ getFeeToken(coinReceiveSelected.networkFee) }} XEC + +
+
\ No newline at end of file diff --git a/src/app/pages/swap/create-swap/create-swap.component.ts b/src/app/pages/swap/create-swap/create-swap.component.ts index a1fbbc1b5a7..2f3035a07a1 100644 --- a/src/app/pages/swap/create-swap/create-swap.component.ts +++ b/src/app/pages/swap/create-swap/create-swap.component.ts @@ -1,7 +1,10 @@ -import { Component, OnInit, ViewChild, ViewEncapsulation } from '@angular/core'; +import { Component, ElementRef, OnInit, ViewChild, ViewEncapsulation } from '@angular/core'; import { Router } from '@angular/router'; +import _ from 'lodash'; import { CountdownComponent } from 'ngx-countdown'; -import { AppProvider, RateProvider, ThemeProvider } from 'src/app/providers'; +import { Subject, Subscription } from 'rxjs'; +import { debounceTime } from 'rxjs/operators'; +import { Coin, CurrencyProvider, RateProvider, ThemeProvider } from 'src/app/providers'; @Component({ selector: 'page-create-swap', @@ -13,15 +16,31 @@ export class CreateSwapPage implements OnInit { public isScroll = false; public currentTheme:any; public rates: any; + public coinSwapSelected: any; + public coinReceiveSelected: any; + public swapValue = 0; + public receiveValue= 0; + private modelChanged: Subject = new Subject(); + private subscription: Subscription; + debounceTime = 500; + // public config: Config; + public fiatCode: any; @ViewChild('cd', { static: false }) private countdown: CountdownComponent; - + @ViewChild('input-swap') inputSwap:ElementRef; + @ViewChild('input-receive') inputReceive:ElementRef; public listConfig = { "coinSwap": [ { "code": "xpi", "isToken": false, "networkFee": 226, - "rateUSD": 0, + "rate": {}, + }, + { + "code": "btc", + "isToken": false, + "networkFee": 226, + "rate": {}, } ], "coinReceived": [ @@ -29,7 +48,19 @@ export class CreateSwapPage implements OnInit { "code": "eat", "isToken": true, "networkFee": 1342, - "rateUSD": 0 + "rate": {} + }, + { + "code": "xec", + "isToken": false, + "networkFee": 1342, + "rate": {} + }, + { + "code": "xpi", + "isToken": false, + "networkFee": 226, + "rate": {} } ] } @@ -37,11 +68,18 @@ export class CreateSwapPage implements OnInit { constructor( private router: Router, private themeProvider: ThemeProvider, - private rateProvider: RateProvider + private rateProvider: RateProvider, + private currencyProvider: CurrencyProvider ) { // this.router.navigate(['/setting']); } + + public getChain(coin: Coin): string { + // return ''; + return this.currencyProvider.getChain(coin).toLowerCase(); + } + handleEvent(event){ if(event.action === 'done'){ this.countdown.restart(); @@ -58,23 +96,67 @@ export class CreateSwapPage implements OnInit { } } + getFeeToken(networkFee) : number{ + const precision = _.get(this.currencyProvider.getPrecision('xec' as Coin), 'unitToSatoshi', 0); + if(!precision){ + return 0; + } else{ + return networkFee / precision; + } + } + ngOnInit() { // this.rates = this.rateProvider.getRates(); // this.rates = this.rates.map() + // this.currentTheme = this.themeProvider.getCurrentAppTheme() === 'Dark Mode' ? 'dark' : 'light'; this.handleUpdateRate(); + this.coinReceiveSelected = this.listConfig.coinReceived[0]; + this.coinSwapSelected = this.listConfig.coinSwap[0]; + this.subscription = this.modelChanged + .pipe( + debounceTime(this.debounceTime), + ) + .subscribe((isSwap) => { + this.handleInputChange(isSwap); + }); + // this.fiatCode = + // this.config.wallet.settings.alternativeIsoCode || + // 'USD'; + } + + handleInputChange(isSwap?:Boolean){ + if(!!isSwap){ + this.receiveValue = this.swapValue * ( this.coinSwapSelected.rate.USD/ this.coinReceiveSelected.rate.USD); + } else{ + this.swapValue = this.receiveValue * ( this.coinReceiveSelected.rate.USD /this.coinSwapSelected.rate.USD); + } + } + + inputChanged(isSwap:boolean){ + this.modelChanged.next(isSwap); } handleUpdateRate(){ this.rateProvider.updateRatesCustom().then(data => { this.listConfig.coinSwap.forEach(coin =>{ - coin.rateUSD = data[coin.code].USD ? data[coin.code].USD : 0; + coin.rate = data[coin.code]; }) this.listConfig.coinReceived.forEach(coin =>{ - coin.rateUSD = data[coin.code].USD ? data[coin.code].USD : 0; + coin.rate = data[coin.code]; }) }); } + handleCoinSwapChange(event){ + const coinSwapCodeSelected = event.detail.value; + this.coinSwapSelected = this.listConfig.coinSwap.find(s => s.code === coinSwapCodeSelected); + } + + handleCoinReceiveChange(event){ + const coinReceiveCodeSelected = event.detail.value; + this.coinReceiveSelected = this.listConfig.coinReceived.find(s => s.code === coinReceiveCodeSelected); + } + ionViewWillEnter() { this.currentTheme = this.themeProvider.getCurrentAppTheme() === 'Dark Mode' ? 'dark' : 'light'; } From 42e7a563a5c60f1a423109cd4eed54c95af0afd7 Mon Sep 17 00:00:00 2001 From: takYoon Date: Mon, 5 Sep 2022 15:31:45 +0700 Subject: [PATCH 11/28] commit code --- .../create-swap/create-swap.component.html | 34 +++-- .../create-swap/create-swap.component.scss | 6 + .../swap/create-swap/create-swap.component.ts | 133 ++++++++++++++---- 3 files changed, 134 insertions(+), 39 deletions(-) diff --git a/src/app/pages/swap/create-swap/create-swap.component.html b/src/app/pages/swap/create-swap/create-swap.component.html index 913bd9f1981..fea6c7402e5 100644 --- a/src/app/pages/swap/create-swap/create-swap.component.html +++ b/src/app/pages/swap/create-swap/create-swap.component.html @@ -39,7 +39,7 @@ 1 {{coinSwapSelected.code}} - {{(coinSwapSelected.rate.USD /coinReceiveSelected.rate.USD)}} {{coinReceiveSelected.code}} + {{formatAmountWithLimitDecimal((coinSwapSelected.rate.USD /coinReceiveSelected.rate.USD),8)}} {{coinReceiveSelected.code}}
@@ -57,13 +57,13 @@ - + - +

{{formatAmountWithLimitDecimal((swapValue * coinSwapSelected.rate[fiatCode]),8)}} {{fiatCode}}

-
+
You receive
@@ -72,20 +72,24 @@ + - + + +

{{formatAmountWithLimitDecimal((receiveValue * coinReceiveSelected.rate[fiatCode]),8)}} {{fiatCode}}

+
+
-
- Network fee: - - {{ coinReceiveSelected.networkFee | satToUnit: getChain(coinReceiveSelected.code) }} - - - {{ getFeeToken(coinReceiveSelected.networkFee) }} XEC - -
- +
+ Network fee: + + {{ coinReceiveSelected.networkFee | satToUnit: getChain(coinReceiveSelected.code) }} + + + {{ getFeeToken(coinReceiveSelected.networkFee) }} XEC +
+ \ No newline at end of file diff --git a/src/app/pages/swap/create-swap/create-swap.component.scss b/src/app/pages/swap/create-swap/create-swap.component.scss index c973dbed917..f75c6aea0cc 100644 --- a/src/app/pages/swap/create-swap/create-swap.component.scss +++ b/src/app/pages/swap/create-swap/create-swap.component.scss @@ -44,4 +44,10 @@ page-create-swap{ margin-left: 7px; } } + .swap-exchange-container{ + display: flex; + } + .right-part{ + margin-left: 20px; + } } diff --git a/src/app/pages/swap/create-swap/create-swap.component.ts b/src/app/pages/swap/create-swap/create-swap.component.ts index 2f3035a07a1..93ca6423d25 100644 --- a/src/app/pages/swap/create-swap/create-swap.component.ts +++ b/src/app/pages/swap/create-swap/create-swap.component.ts @@ -4,7 +4,9 @@ import _ from 'lodash'; import { CountdownComponent } from 'ngx-countdown'; import { Subject, Subscription } from 'rxjs'; import { debounceTime } from 'rxjs/operators'; -import { Coin, CurrencyProvider, RateProvider, ThemeProvider } from 'src/app/providers'; +import { Coin, CurrencyProvider, FilterProvider, RateProvider, ThemeProvider } from 'src/app/providers'; +import { Config, ConfigProvider } from '../../../providers/config/config'; +// import { Config } from 'src/app/providers/config/config'; @Component({ selector: 'page-create-swap', @@ -20,14 +22,18 @@ export class CreateSwapPage implements OnInit { public coinReceiveSelected: any; public swapValue = 0; public receiveValue= 0; + public swapAltValue = 0; + public receiveAltValue= 0; private modelChanged: Subject = new Subject(); private subscription: Subscription; + public usdRate: any; + public fiatCode: any; + public config: Config; debounceTime = 500; // public config: Config; - public fiatCode: any; @ViewChild('cd', { static: false }) private countdown: CountdownComponent; - @ViewChild('input-swap') inputSwap:ElementRef; - @ViewChild('input-receive') inputReceive:ElementRef; + @ViewChild('inputSwap') inputSwap:ElementRef; + @ViewChild('inputReceive') inputReceive:ElementRef; public listConfig = { "coinSwap": [ { @@ -35,32 +41,47 @@ export class CreateSwapPage implements OnInit { "isToken": false, "networkFee": 226, "rate": {}, + "min": 10, // USD + "unitDecimals": 0 }, { - "code": "btc", + "code": "xec", "isToken": false, "networkFee": 226, "rate": {}, + "min": 10, // USD + "unitDecimals": 0 + }, + { + "code": "bch", + "isToken": false, + "networkFee": 226, + "rate": {}, + "min": 10, // USD + "unitDecimals": 0 } ], "coinReceived": [ { - "code": "eat", + "code": "EAT", "isToken": true, "networkFee": 1342, - "rate": {} + "rate": {}, + "unitDecimals": 0 }, { - "code": "xec", - "isToken": false, + "code": "bcPro", + "isToken": true, "networkFee": 1342, - "rate": {} + "rate": {}, + "unitDecimals": 0 }, { "code": "xpi", "isToken": false, "networkFee": 226, - "rate": {} + "rate": {}, + "unitDecimals": 0 } ] } @@ -69,10 +90,13 @@ export class CreateSwapPage implements OnInit { private router: Router, private themeProvider: ThemeProvider, private rateProvider: RateProvider, - private currencyProvider: CurrencyProvider + private currencyProvider: CurrencyProvider, + private configProvider: ConfigProvider, + private filterProvider: FilterProvider ) { // this.router.navigate(['/setting']); + // this.config = this.configProvider.get(); } public getChain(coin: Coin): string { @@ -106,9 +130,6 @@ export class CreateSwapPage implements OnInit { } ngOnInit() { - // this.rates = this.rateProvider.getRates(); - // this.rates = this.rates.map() - // this.currentTheme = this.themeProvider.getCurrentAppTheme() === 'Dark Mode' ? 'dark' : 'light'; this.handleUpdateRate(); this.coinReceiveSelected = this.listConfig.coinReceived[0]; this.coinSwapSelected = this.listConfig.coinSwap[0]; @@ -119,46 +140,110 @@ export class CreateSwapPage implements OnInit { .subscribe((isSwap) => { this.handleInputChange(isSwap); }); - // this.fiatCode = - // this.config.wallet.settings.alternativeIsoCode || - // 'USD'; } handleInputChange(isSwap?:Boolean){ if(!!isSwap){ - this.receiveValue = this.swapValue * ( this.coinSwapSelected.rate.USD/ this.coinReceiveSelected.rate.USD); + const result = Number((this.swapValue * ( this.coinSwapSelected.rate.USD / this.coinReceiveSelected.rate.USD))); + this.receiveValue = this.formatAmountWithLimitDecimal(result, 8); } else{ - this.swapValue = this.receiveValue * ( this.coinReceiveSelected.rate.USD /this.coinSwapSelected.rate.USD); + const result = Number((this.receiveValue * ( this.coinReceiveSelected.rate.USD / this.coinSwapSelected.rate.USD)).toFixed(this.coinSwapSelected.unitDecimals)); + this.swapValue = this.formatAmountWithLimitDecimal(result, 8); + } + } + + validateInputSwap(input){ + if(this.swapValue.toString().split('.').length > 1){ + if(this.swapValue.toString().split('.')[1].length > this.coinSwapSelected.unitDecimals){ + const valueFixed = Number(Number(this.swapValue).toFixed(this.coinSwapSelected.unitDecimals)); + this.swapValue = valueFixed; + input.value = this.swapValue; + } + } + } + + validateInputReceive(input){ + if(this.receiveValue.toString().split('.').length > 1){ + if(this.receiveValue.toString().split('.')[1].length > this.coinReceiveSelected.unitDecimals){ + const valueFixed = Number(Number(this.receiveValue).toFixed(this.coinReceiveSelected.unitDecimals)); + this.receiveValue = valueFixed; + input.value = this.receiveValue; + } } } + formatAmountWithLimitDecimal(amount:number, maxDecimals):number { + if(amount.toString().split('.').length > 1){ + if(amount.toString().split('.')[1].length > maxDecimals){ + return Number(amount.toFixed(maxDecimals)); + } + return amount; + } else { + return amount; + } + } + + formatInput(balance){ + if (typeof balance === 'string') + balance = balance.replace(/,/g, '') + if (isNaN(Number(balance)) || Number(balance) <= 0) { + return "0.00"; + } else { + if (Number(balance) < 10) { + return Number(Number(balance).toFixed(Math.round(1/Number(balance)).toString().length+2)).toLocaleString("en-GB"); + } else { + return Number(Number(balance).toFixed(Math.round(1/Number(balance)).toString().length+1)).toLocaleString("en-GB"); + } + } + } + inputChanged(isSwap:boolean){ this.modelChanged.next(isSwap); + } handleUpdateRate(){ this.rateProvider.updateRatesCustom().then(data => { this.listConfig.coinSwap.forEach(coin =>{ - coin.rate = data[coin.code]; - }) + const code = coin.code.toLowerCase(); + coin.rate = data[code]; + const coinCode = coin.isToken ? 'xec' : coin.code; + if(coin.unitDecimals <= 0){ + const { unitDecimals } = this.currencyProvider.getPrecision(coinCode as Coin); + coin.unitDecimals = unitDecimals; + } + }); this.listConfig.coinReceived.forEach(coin =>{ - coin.rate = data[coin.code]; - }) + const code = coin.code.toLowerCase(); + coin.rate = data[code]; + const coinCode = coin.isToken ? 'xec' : coin.code; + if(coin.unitDecimals <= 0){ + const { unitDecimals } = this.currencyProvider.getPrecision(coinCode as Coin); + coin.unitDecimals = unitDecimals; + } + }); + this.usdRate = data['eat']; }); } handleCoinSwapChange(event){ const coinSwapCodeSelected = event.detail.value; this.coinSwapSelected = this.listConfig.coinSwap.find(s => s.code === coinSwapCodeSelected); + this.swapValue = 0; + this.receiveValue = 0; } handleCoinReceiveChange(event){ const coinReceiveCodeSelected = event.detail.value; this.coinReceiveSelected = this.listConfig.coinReceived.find(s => s.code === coinReceiveCodeSelected); + this.swapValue = 0; + this.receiveValue = 0; } ionViewWillEnter() { this.currentTheme = this.themeProvider.getCurrentAppTheme() === 'Dark Mode' ? 'dark' : 'light'; + this.config = this.configProvider.get(); + this.fiatCode = this.config.wallet.settings.alternativeIsoCode; } public openSettingPage() { From 04d00105f26038b67e34a29444fa14f784d385ea Mon Sep 17 00:00:00 2001 From: takYoon Date: Tue, 6 Sep 2022 07:33:02 +0700 Subject: [PATCH 12/28] update create swap code --- .../create-swap/create-swap.component.html | 16 +++-- .../swap/create-swap/create-swap.component.ts | 65 ++++++++++++------- 2 files changed, 49 insertions(+), 32 deletions(-) diff --git a/src/app/pages/swap/create-swap/create-swap.component.html b/src/app/pages/swap/create-swap/create-swap.component.html index fea6c7402e5..80d821d9943 100644 --- a/src/app/pages/swap/create-swap/create-swap.component.html +++ b/src/app/pages/swap/create-swap/create-swap.component.html @@ -57,10 +57,10 @@ - + -

{{formatAmountWithLimitDecimal((swapValue * coinSwapSelected.rate[fiatCode]),8)}} {{fiatCode}}

+
@@ -74,14 +74,16 @@ - + - -

{{formatAmountWithLimitDecimal((receiveValue * coinReceiveSelected.rate[fiatCode]),8)}} {{fiatCode}}

-
+
- +
+ {{altValue}} {{fiatCode}} +
Network fee: diff --git a/src/app/pages/swap/create-swap/create-swap.component.ts b/src/app/pages/swap/create-swap/create-swap.component.ts index 93ca6423d25..9c73877e430 100644 --- a/src/app/pages/swap/create-swap/create-swap.component.ts +++ b/src/app/pages/swap/create-swap/create-swap.component.ts @@ -22,7 +22,7 @@ export class CreateSwapPage implements OnInit { public coinReceiveSelected: any; public swapValue = 0; public receiveValue= 0; - public swapAltValue = 0; + public altValue = 0; public receiveAltValue= 0; private modelChanged: Subject = new Subject(); private subscription: Subscription; @@ -147,35 +147,50 @@ export class CreateSwapPage implements OnInit { const result = Number((this.swapValue * ( this.coinSwapSelected.rate.USD / this.coinReceiveSelected.rate.USD))); this.receiveValue = this.formatAmountWithLimitDecimal(result, 8); } else{ - const result = Number((this.receiveValue * ( this.coinReceiveSelected.rate.USD / this.coinSwapSelected.rate.USD)).toFixed(this.coinSwapSelected.unitDecimals)); + const result = Number((this.receiveValue * ( this.coinReceiveSelected.rate.USD / this.coinSwapSelected.rate.USD)));; this.swapValue = this.formatAmountWithLimitDecimal(result, 8); } } validateInputSwap(input){ - if(this.swapValue.toString().split('.').length > 1){ - if(this.swapValue.toString().split('.')[1].length > this.coinSwapSelected.unitDecimals){ - const valueFixed = Number(Number(this.swapValue).toFixed(this.coinSwapSelected.unitDecimals)); - this.swapValue = valueFixed; - input.value = this.swapValue; - } - } + this.swapValue = this.formatAmountWithLimitDecimal(this.swapValue, 8); + input.value = this.swapValue; } validateInputReceive(input){ - if(this.receiveValue.toString().split('.').length > 1){ - if(this.receiveValue.toString().split('.')[1].length > this.coinReceiveSelected.unitDecimals){ - const valueFixed = Number(Number(this.receiveValue).toFixed(this.coinReceiveSelected.unitDecimals)); - this.receiveValue = valueFixed; - input.value = this.receiveValue; + this.receiveValue = this.formatAmountWithLimitDecimal(this.receiveValue, 8); + input.value = this.receiveValue; + } + + handleKeyUp(isSwap: boolean, input, event){ + const keyInput = event.key; + const pattern = /^[a-zA-Z]*$/; + if(isSwap){ + if (pattern.test(keyInput)) { + // this.swapValue = Number(this.swapValue.toString().replace(/[^a-zA-Z]/g, "")); + input.value = Number(this.swapValue.toString().replace(/[a-zA-Z]/g, "")); + // invalid character, prevent input + } + else{ + this.modelChanged.next(isSwap); + this.altValue = this.formatAmountWithLimitDecimal(Number(this.swapValue) * this.coinSwapSelected.rate[this.fiatCode], 8); + } + } + else{ + if (pattern.test(keyInput)) { + input.value = Number(this.swapValue.toString().replace(/[a-zA-Z]/g, "")); } + else{ + this.modelChanged.next(isSwap); + this.altValue = this.formatAmountWithLimitDecimal(Number(this.receiveValue) * this.coinReceiveSelected.rate[this.fiatCode], 8); + } } } formatAmountWithLimitDecimal(amount:number, maxDecimals):number { if(amount.toString().split('.').length > 1){ if(amount.toString().split('.')[1].length > maxDecimals){ - return Number(amount.toFixed(maxDecimals)); + return Number(amount.toString().split('.')[0] + '.' + amount.toString().split('.')[1].substr(0, maxDecimals)); } return amount; } else { @@ -197,9 +212,9 @@ export class CreateSwapPage implements OnInit { } } - inputChanged(isSwap:boolean){ + inputChanged(isSwap:boolean, input, event){ this.modelChanged.next(isSwap); - + } handleUpdateRate(){ @@ -208,19 +223,19 @@ export class CreateSwapPage implements OnInit { const code = coin.code.toLowerCase(); coin.rate = data[code]; const coinCode = coin.isToken ? 'xec' : coin.code; - if(coin.unitDecimals <= 0){ - const { unitDecimals } = this.currencyProvider.getPrecision(coinCode as Coin); - coin.unitDecimals = unitDecimals; - } + // if(coin.unitDecimals <= 0){ + // const { unitDecimals } = this.currencyProvider.getPrecision(coinCode as Coin); + // coin.unitDecimals = unitDecimals; + // } }); this.listConfig.coinReceived.forEach(coin =>{ const code = coin.code.toLowerCase(); coin.rate = data[code]; const coinCode = coin.isToken ? 'xec' : coin.code; - if(coin.unitDecimals <= 0){ - const { unitDecimals } = this.currencyProvider.getPrecision(coinCode as Coin); - coin.unitDecimals = unitDecimals; - } + // if(coin.unitDecimals <= 0){ + // const { unitDecimals } = this.currencyProvider.getPrecision(coinCode as Coin); + // coin.unitDecimals = unitDecimals; + // } }); this.usdRate = data['eat']; }); From fd158cd4db024252c98c8f3fab938bf6fed6e018 Mon Sep 17 00:00:00 2001 From: takYoon Date: Wed, 7 Sep 2022 10:53:34 +0700 Subject: [PATCH 13/28] update code for create swap --- .../create-swap/create-swap.component.html | 45 ++++- .../swap/create-swap/create-swap.component.ts | 166 +++++++++++++++--- src/app/providers/rate/rate.ts | 6 +- 3 files changed, 179 insertions(+), 38 deletions(-) diff --git a/src/app/pages/swap/create-swap/create-swap.component.html b/src/app/pages/swap/create-swap/create-swap.component.html index 80d821d9943..96588bbe970 100644 --- a/src/app/pages/swap/create-swap/create-swap.component.html +++ b/src/app/pages/swap/create-swap/create-swap.component.html @@ -37,13 +37,23 @@
- 1 {{coinSwapSelected.code}} + 1  {{coinSwapSelected.code}} - {{formatAmountWithLimitDecimal((coinSwapSelected.rate.USD /coinReceiveSelected.rate.USD),8)}} {{coinReceiveSelected.code}} + {{formatAmountWithLimitDecimal((coinSwapSelected.rate.USD /coinReceiveSelected.rate.USD),8)}}  {{coinReceiveSelected.code}}
- +
+
+ +
+

Your {{ coinReceiveSelected.code }} address

+ +

{{ validAddress }}

+
+
You send
@@ -57,9 +67,10 @@ - + +
@@ -74,7 +85,7 @@ - + -

{{ validAddress }}

-
- -
-
-
You send
-
+
+
+
+
You send
+
+ + + + {{coin.code}} + + + + + + + + +
+
+
+
You receive
- - + + {{coin.code}} - - - + + + - - - +
-
-
You receive
- - - - {{coin.code}} - - - - - - - - +
+ {{altValueStr}} {{fiatCode}}
-
-
- {{altValueStr}} {{fiatCode}} -
- You need to deposit at least {{ minWithCurrentFiatStr }} {{fiatCode}} + You need to deposit at least {{ minWithCurrentFiatStr }} {{fiatCode}} + +
+ Network fee: + + {{ coinReceiveSelected.networkFee | satToUnit: getChain(coinReceiveSelected.code) }} + + + {{ getFeeToken(coinReceiveSelected.networkFee) }} XEC + +
+ -
- Network fee: - - {{ coinReceiveSelected.networkFee | satToUnit: getChain(coinReceiveSelected.code) }} - - - {{ getFeeToken(coinReceiveSelected.networkFee) }} XEC - +
+

Your {{ coinReceiveSelected.code }} address

+ + + + Wrong format addresss
- + +
@@ -122,7 +121,7 @@
- {{ 'Swap' | translate }} + {{ 'Swap' | translate }}
\ No newline at end of file diff --git a/src/app/pages/swap/create-swap/create-swap.component.ts b/src/app/pages/swap/create-swap/create-swap.component.ts index 5744895c7e1..dc7434895d9 100644 --- a/src/app/pages/swap/create-swap/create-swap.component.ts +++ b/src/app/pages/swap/create-swap/create-swap.component.ts @@ -1,5 +1,7 @@ -import { Component, ElementRef, OnInit, ViewChild, ViewEncapsulation } from '@angular/core'; +import { ChangeDetectionStrategy, ChangeDetectorRef, Component, ElementRef, OnInit, ViewChild, ViewEncapsulation } from '@angular/core'; +import { AbstractControl, FormBuilder, FormControl, FormGroup, ValidationErrors, ValidatorFn } from '@angular/forms'; import { Router } from '@angular/router'; +import { truncateSync } from 'fs'; import _ from 'lodash'; import { CountdownComponent } from 'ngx-countdown'; import { Subject, Subscription } from 'rxjs'; @@ -12,7 +14,8 @@ import { Config, ConfigProvider } from '../../../providers/config/config'; selector: 'page-create-swap', templateUrl: './create-swap.component.html', styleUrls: ['./create-swap.component.scss'], - encapsulation: ViewEncapsulation.None + encapsulation: ViewEncapsulation.None, + changeDetection: ChangeDetectionStrategy.OnPush }) export class CreateSwapPage implements OnInit { public isScroll = false; @@ -35,8 +38,9 @@ export class CreateSwapPage implements OnInit { public minAmount : any; public minStr : any; public validSwapAmount = true; + public minWithCurrentFiat: any; public minWithCurrentFiatStr: any; - + public createForm: FormGroup debounceTime = 500; // public config: Config; @ViewChild('cd', { static: false }) private countdown: CountdownComponent; @@ -120,11 +124,28 @@ export class CreateSwapPage implements OnInit { private currencyProvider: CurrencyProvider, private configProvider: ConfigProvider, private incomingDataProvider: IncomingDataProvider, - private addressProvider: AddressProvider + private addressProvider: AddressProvider, + private form: FormBuilder, + private _cdRef: ChangeDetectorRef ) { - // this.router.navigate(['/setting']); - // this.config = this.configProvider.get(); + this.createForm = this.form.group({ + swapAmount:[0,{ + validators: [this.amountMinValidator()], + updateOn: 'change' + }], + // swapAmount: [null], + receiveAmount:[0,{ + validators: [this.amountMinValidator()], + updateOn: 'change' + }], + address: [ + null, { + validators: [this.addressValidator()], + updateOn: 'change' + } + ] + }); } public getChain(coin: Coin): string { @@ -158,7 +179,8 @@ export class CreateSwapPage implements OnInit { } ngOnInit() { - this.handleUpdateRate(); + this.handleUpdateRate(); + this.coinReceiveSelected = this.listConfig.coinReceived[0]; this.coinSwapSelected = this.listConfig.coinSwap[0]; this.subscription = this.modelChanged @@ -172,75 +194,119 @@ export class CreateSwapPage implements OnInit { handleInputChange(isSwap: Boolean){ if(!!isSwap){ - const result = Number((this.swapValue * ( this.coinSwapSelected.rate.USD / this.coinReceiveSelected.rate.USD))); - this.receiveValue = this.formatAmountWithLimitDecimal(result, 8); - this.inputReceive.nativeElement.value = this.receiveValue; + const result = Number(this.createForm.controls['swapAmount'].value * ( this.coinSwapSelected.rate.USD / this.coinReceiveSelected.rate.USD)); + this.createForm.controls['receiveAmount'].setValue(this.formatAmountWithLimitDecimal(result, 8)); } else{ - const result = Number((this.receiveValue * ( this.coinReceiveSelected.rate.USD / this.coinSwapSelected.rate.USD)));; - this.swapValue = this.formatAmountWithLimitDecimal(result, 8); - this.inputSwap.nativeElement.value = this.swapValue; + const result = Number((this.createForm.controls['receiveAmount'].value * ( this.coinReceiveSelected.rate.USD / this.coinSwapSelected.rate.USD)));; + this.createForm.controls['swapAmount'].setValue(this.formatAmountWithLimitDecimal(result, 8)); } + } - if(this.altValue > 0 ){ - const minWithCurrentFiat = this.coinSwapSelected.min * this.usdRate[this.fiatCode]; - if(this.altValue < minWithCurrentFiat){ - this.validSwapAmount = false; - this.minWithCurrentFiatStr = new Intl.NumberFormat('en-GB').format(minWithCurrentFiat); + amountMinValidator(): ValidatorFn { + return (control: AbstractControl): ValidationErrors | null => { + if(control.value === 0){ + return { amountNotInput: true }; + } + if(this.altValue > 0 ){ + this.minWithCurrentFiat = this.coinSwapSelected.min * this.usdRate[this.fiatCode]; + if(this.altValue < this.minWithCurrentFiat){ + this.minWithCurrentFiatStr = new Intl.NumberFormat('en-GB').format(this.minWithCurrentFiat); + return { amountMinValidator: true }; + } else{ + return null; + } + } + else{ + return null; + } + }; + } + + addressValidator():ValidatorFn{ + return (control: AbstractControl): ValidationErrors | null => { + // handle case no address input + if(!control.value){ + return null; + } + if(control.value.length === 0){ + return { addressNotInput: true }; + } + + // handle case token + if(this.coinReceiveSelected.isToken){ + try { + const addressInputValue = this.createForm.controls['address'].value; + const { prefix, type, hash } = this.addressProvider.decodeAddress(addressInputValue); + if(prefix === 'etoken' || prefix === 'ecash'){ + return null; + } else{ + return { addressInvalid: true } + } + } + catch(e){ + return { addressInvalid: true } + } + } + + // handle case coin + const parsedData = this.incomingDataProvider.parseData(this.addressSwapValue); + if ( + parsedData && + _.indexOf(this.validDataTypeMap, parsedData.type) != -1 + ) { + this.validAddress = this.checkCoinAndNetwork(this.addressSwapValue); + if(this.validAddress){ + return null; + } else { + return { addressInvalid: true } + } } else{ - this.validSwapAmount = true; + return { addressInvalid: true } } } - else{ - this.validSwapAmount = true; - } - // this.inputReceive.nativeElement.value = new Intl.NumberFormat('en-GB').format(this.receiveValue); - // this.inputSwap.nativeElement.value = new Intl.NumberFormat('en-GB').format(this.swapValue); } validateInput(isSwap){ if(!!isSwap){ - this.swapValue = this.formatAmountWithLimitDecimal(this.swapValue, 8); + // this.createForm.controls['receiveAmount'].setValue + // this.swapValue = this.formatAmountWithLimitDecimal(this.swapValue, 8); + // this._cdRef.markForCheck(); // this.inputSwap.nativeElement.value = this.swapValue; } else{ this.receiveValue = this.formatAmountWithLimitDecimal(this.receiveValue, 8); // this.inputReceive.nativeElement.value = new Intl.NumberFormat('en-GB').format(this.swapValue); } - // this.inputSwap.nativeElement.value = new Intl.NumberFormat('en-GB').format(this.swapValue); + this.inputSwap.nativeElement.value = new Intl.NumberFormat('en-GB').format(this.swapValue); // this.inputReceive.nativeElement.value = this.receiveValue; } handleKeyDown(isSwap: boolean, event){ const keyInput = event.key; - // const pattern = /[^a-zA-Z]*$/; const pattern = /[^0-9\.]/; const keyCode = event.keyCode; const allowSpecialKeyCode = [37, 39, 8, 46]; - this.swapValue = Number(this.swapValue.toString().replace(/,/g, '')); - this.receiveValue = Number(this.receiveValue.toString().replace(/,/g, '')); + const swapValueInputStr = this.createForm.controls['swapAmount'].value.toString(); + const receiveValueInputStr = this.createForm.controls['receiveAmount'].value.toString(); if(isSwap){ if(keyInput === '.'){ - if(this.swapValue.toString().split('.').length > 1) { - // input.value = this.swapValue.toString().substring(0, this.swapValue.toString().length-1); + if(swapValueInputStr.split('.').length > 1) { event.preventDefault(); } } else if (!allowSpecialKeyCode.includes(keyCode) && pattern.test(keyInput)) { - // this.swapValue = Number(this.swapValue.toString().replace(/[^a-zA-Z]/g, "")); - // input.value = this.swapValue.toString().replace(/[^0-9\.]/g, ""); - // invalid character, prevent input event.preventDefault(); } else{ let swapValue; - if(keyCode === 8){ - swapValue = Number(this.swapValue.toString().substring(0, this.swapValue.toString().length -1)); + if(keyCode === 8 || keyCode === 46){ + swapValue = Number(swapValueInputStr.substring(0, swapValueInputStr.length -1)); } else if(!allowSpecialKeyCode.includes(keyCode)){ - swapValue = Number(this.swapValue + event.key); + swapValue = Number(swapValueInputStr + event.key); } else{ - swapValue = this.swapValue; + swapValue = swapValueInputStr; } - swapValue = isNaN(swapValue) ? 0 : swapValue; + swapValue = isNaN(swapValueInputStr) ? 0 : swapValue; this.modelChanged.next(isSwap); this.altValue = this.formatAmountWithLimitDecimal(swapValue * this.coinSwapSelected.rate[this.fiatCode], 8); this.altValueStr = new Intl.NumberFormat('en-GB').format(this.altValue); @@ -248,17 +314,16 @@ export class CreateSwapPage implements OnInit { } else{ if (!allowSpecialKeyCode.includes(keyCode) && pattern.test(keyInput)) { - // input.value = this.swapValue.toString().replace(/[^0-9\.]/g, ""); event.preventDefault(); } else{ let receiveValue; - if(keyCode === 8){ - receiveValue = Number(this.receiveValue.toString().substring(0, this.receiveValue.toString().length -1)); + if(keyCode === 8 || keyCode === 46){ + receiveValue = Number(receiveValueInputStr.substring(0, receiveValueInputStr.length -1)); } else if(!allowSpecialKeyCode.includes(keyCode)){ - receiveValue = Number(this.receiveValue + event.key); + receiveValue = Number(receiveValueInputStr + event.key); } else{ - receiveValue = this.receiveValue; + receiveValue = receiveValueInputStr; } receiveValue = isNaN(receiveValue) ? 0 : receiveValue; this.modelChanged.next(isSwap); @@ -266,13 +331,9 @@ export class CreateSwapPage implements OnInit { this.altValueStr = new Intl.NumberFormat('en-GB').format(this.altValue); } } + this.modelChanged.next(isSwap); } - // handleKeyUp(){ - // this.inputSwap.nativeElement.value = new Intl.NumberFormat('en-GB').format(this.swapValue); - // this.inputReceive.nativeElement.value = new Intl.NumberFormat('en-GB').format(this.receiveValue); - // } - formatAmountWithLimitDecimal(amount:number, maxDecimals):number { if(amount.toString().split('.').length > 1){ if(amount.toString().split('.')[1].length > maxDecimals){ @@ -304,49 +365,48 @@ export class CreateSwapPage implements OnInit { this.listConfig.coinSwap.forEach(coin =>{ const code = coin.code.toLowerCase(); coin.rate = data[code]; - // const coinCode = coin.isToken ? 'xec' : coin.code; - // if(coin.unitDecimals <= 0){ - // const { unitDecimals } = this.currencyProvider.getPrecision(coinCode as Coin); - // coin.unitDecimals = unitDecimals; - // } }); this.listConfig.coinReceived.forEach(coin =>{ const code = coin.code.toLowerCase(); coin.rate = data[code]; - // const coinCode = coin.isToken ? 'xec' : coin.code; - // if(coin.unitDecimals <= 0){ - // const { unitDecimals } = this.currencyProvider.getPrecision(coinCode as Coin); - // coin.unitDecimals = unitDecimals; - // } }); - }); } handleCoinSwapChange(event){ const coinSwapCodeSelected = event.detail.value; this.coinSwapSelected = this.listConfig.coinSwap.find(s => s.code === coinSwapCodeSelected); - this.swapValue = 0; - this.receiveValue = 0; + this.resetFormControl(); + // this.swapValue = 0; + // this.receiveValue = 0; } handleCoinReceiveChange(event){ const coinReceiveCodeSelected = event.detail.value; this.coinReceiveSelected = this.listConfig.coinReceived.find(s => s.code === coinReceiveCodeSelected); - this.swapValue = 0; - this.receiveValue = 0; - this.addressSwapValue = ''; + this.resetFormControl(); + // this.swapValue = 0; + // this.receiveValue = 0; + // this.addressSwapValue = ''; + } + + resetFormControl(){ + this.createForm.controls['swapAmount'].setValue(0); + this.createForm.controls['receiveAmount'].setValue(0); + this.createForm.controls['address'].setValue(''); } ionViewWillEnter() { - this.currentTheme = this.themeProvider.getCurrentAppTheme() === 'Dark Mode' ? 'dark' : 'light'; this.config = this.configProvider.get(); this.fiatCode = this.config.wallet.settings.alternativeIsoCode; - + this.currentTheme = this.themeProvider.getCurrentAppTheme() === 'Dark Mode' ? 'dark' : 'light'; + this._cdRef.markForCheck(); } validateAddress(){ + const parsedData = this.incomingDataProvider.parseData(this.addressSwapValue); + if ( parsedData && _.indexOf(this.validDataTypeMap, parsedData.type) != -1 @@ -376,4 +436,5 @@ export class CreateSwapPage implements OnInit { public openSettingPage() { this.router.navigate(['/setting']); } + } From 5e9a45e223d57295be4761dc6a5dd91db58e12b9 Mon Sep 17 00:00:00 2001 From: takYoon Date: Sat, 10 Sep 2022 12:31:53 +0700 Subject: [PATCH 15/28] refactor code + format amount on input --- package.json | 3 +- src/app/app.module.ts | 4 + .../create-swap/create-swap.component.html | 19 +---- .../swap/create-swap/create-swap.component.ts | 75 ++----------------- 4 files changed, 17 insertions(+), 84 deletions(-) diff --git a/package.json b/package.json index a12faa3bad7..27221ca1913 100644 --- a/package.json +++ b/package.json @@ -136,6 +136,7 @@ "ngx-build-plus": "^13.0.1", "ngx-countdown": "^13.0.0", "ngx-markdown": "^12.0.1", + "ngx-mask": "^13.1.15", "ngx-qrcode2": "^9.0.0", "ngx-text-overflow-clamp": "0.0.1", "nm": "^1.0.0", @@ -266,4 +267,4 @@ "trailingComma": "none", "arrowParens": "avoid" } -} \ No newline at end of file +} diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 6d89e35e323..50766c17b7b 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -52,6 +52,9 @@ import { FeatureFlagsService } from './providers/feature-flags.service'; import { AppInitService } from './app-init.service'; import { FeatureFlagDirective } from './directives/feature-flags/feature-flags'; +import { NgxMaskModule } from 'ngx-mask' + + export function translateParserFactory() { return new InterpolatedTranslateParser(); } @@ -106,6 +109,7 @@ const featureFactory = (featureFlagsService: FeatureFlagsService) => () => backButtonText: '', navAnimation: enterAnimation }), + NgxMaskModule.forRoot(), MatGridListModule, MatFormFieldModule, BrowserAnimationsModule, diff --git a/src/app/pages/swap/create-swap/create-swap.component.html b/src/app/pages/swap/create-swap/create-swap.component.html index 94f41d265bd..62505c447f1 100644 --- a/src/app/pages/swap/create-swap/create-swap.component.html +++ b/src/app/pages/swap/create-swap/create-swap.component.html @@ -58,7 +58,7 @@ - +
@@ -74,17 +74,14 @@ - + -
- {{altValueStr}} {{fiatCode}} + {{altValue | mask: 'separator.8':',' }} {{fiatCode}}
- You need to deposit at least {{ minWithCurrentFiatStr }} {{fiatCode}} + You need to deposit at least {{ minWithCurrentFiat | mask: 'separator.8':',' }} {{fiatCode}}
Network fee: @@ -105,14 +102,6 @@ Wrong format addresss
- diff --git a/src/app/pages/swap/create-swap/create-swap.component.ts b/src/app/pages/swap/create-swap/create-swap.component.ts index dc7434895d9..b3e2d522792 100644 --- a/src/app/pages/swap/create-swap/create-swap.component.ts +++ b/src/app/pages/swap/create-swap/create-swap.component.ts @@ -1,14 +1,12 @@ import { ChangeDetectionStrategy, ChangeDetectorRef, Component, ElementRef, OnInit, ViewChild, ViewEncapsulation } from '@angular/core'; import { AbstractControl, FormBuilder, FormControl, FormGroup, ValidationErrors, ValidatorFn } from '@angular/forms'; import { Router } from '@angular/router'; -import { truncateSync } from 'fs'; import _ from 'lodash'; import { CountdownComponent } from 'ngx-countdown'; import { Subject, Subscription } from 'rxjs'; import { debounceTime } from 'rxjs/operators'; import { AddressProvider, Coin, CurrencyProvider, FilterProvider, IncomingDataProvider, RateProvider, ThemeProvider } from 'src/app/providers'; import { Config, ConfigProvider } from '../../../providers/config/config'; -// import { Config } from 'src/app/providers/config/config'; @Component({ selector: 'page-create-swap', @@ -23,11 +21,7 @@ export class CreateSwapPage implements OnInit { public rates: any; public coinSwapSelected: any; public coinReceiveSelected: any; - public swapValue = 0; - public receiveValue= 0; public altValue = 0; - public altValueStr : any; - public receiveAltValue= 0; private modelChanged: Subject = new Subject(); private subscription: Subscription; public usdRate: any; @@ -36,10 +30,7 @@ export class CreateSwapPage implements OnInit { public addressSwapValue: any; public validAddress: any; public minAmount : any; - public minStr : any; - public validSwapAmount = true; public minWithCurrentFiat: any; - public minWithCurrentFiatStr: any; public createForm: FormGroup debounceTime = 500; // public config: Config; @@ -193,12 +184,15 @@ export class CreateSwapPage implements OnInit { } handleInputChange(isSwap: Boolean){ + if(!!isSwap){ - const result = Number(this.createForm.controls['swapAmount'].value * ( this.coinSwapSelected.rate.USD / this.coinReceiveSelected.rate.USD)); - this.createForm.controls['receiveAmount'].setValue(this.formatAmountWithLimitDecimal(result, 8)); + const result = this.createForm.controls['swapAmount'].value * ( this.coinSwapSelected.rate.USD / this.coinReceiveSelected.rate.USD); + this.createForm.controls['receiveAmount'].setValue(result); + this.altValue = this.createForm.controls['swapAmount'].value * this.coinSwapSelected.rate[this.fiatCode]; } else{ - const result = Number((this.createForm.controls['receiveAmount'].value * ( this.coinReceiveSelected.rate.USD / this.coinSwapSelected.rate.USD)));; - this.createForm.controls['swapAmount'].setValue(this.formatAmountWithLimitDecimal(result, 8)); + const result = (this.createForm.controls['receiveAmount'].value * ( this.coinReceiveSelected.rate.USD / this.coinSwapSelected.rate.USD));; + this.createForm.controls['swapAmount'].setValue(result); + this.altValue = this.createForm.controls['receiveAmount'].value * this.coinReceiveSelected.rate[this.fiatCode]; } } @@ -210,7 +204,6 @@ export class CreateSwapPage implements OnInit { if(this.altValue > 0 ){ this.minWithCurrentFiat = this.coinSwapSelected.min * this.usdRate[this.fiatCode]; if(this.altValue < this.minWithCurrentFiat){ - this.minWithCurrentFiatStr = new Intl.NumberFormat('en-GB').format(this.minWithCurrentFiat); return { amountMinValidator: true }; } else{ return null; @@ -266,21 +259,6 @@ export class CreateSwapPage implements OnInit { } } - validateInput(isSwap){ - if(!!isSwap){ - // this.createForm.controls['receiveAmount'].setValue - // this.swapValue = this.formatAmountWithLimitDecimal(this.swapValue, 8); - // this._cdRef.markForCheck(); - // this.inputSwap.nativeElement.value = this.swapValue; - } else{ - this.receiveValue = this.formatAmountWithLimitDecimal(this.receiveValue, 8); - // this.inputReceive.nativeElement.value = new Intl.NumberFormat('en-GB').format(this.swapValue); - } - this.inputSwap.nativeElement.value = new Intl.NumberFormat('en-GB').format(this.swapValue); - // this.inputReceive.nativeElement.value = this.receiveValue; - - } - handleKeyDown(isSwap: boolean, event){ const keyInput = event.key; const pattern = /[^0-9\.]/; @@ -298,18 +276,7 @@ export class CreateSwapPage implements OnInit { event.preventDefault(); } else{ - let swapValue; - if(keyCode === 8 || keyCode === 46){ - swapValue = Number(swapValueInputStr.substring(0, swapValueInputStr.length -1)); - } else if(!allowSpecialKeyCode.includes(keyCode)){ - swapValue = Number(swapValueInputStr + event.key); - } else{ - swapValue = swapValueInputStr; - } - swapValue = isNaN(swapValueInputStr) ? 0 : swapValue; this.modelChanged.next(isSwap); - this.altValue = this.formatAmountWithLimitDecimal(swapValue * this.coinSwapSelected.rate[this.fiatCode], 8); - this.altValueStr = new Intl.NumberFormat('en-GB').format(this.altValue); } } else{ @@ -317,18 +284,7 @@ export class CreateSwapPage implements OnInit { event.preventDefault(); } else{ - let receiveValue; - if(keyCode === 8 || keyCode === 46){ - receiveValue = Number(receiveValueInputStr.substring(0, receiveValueInputStr.length -1)); - } else if(!allowSpecialKeyCode.includes(keyCode)){ - receiveValue = Number(receiveValueInputStr + event.key); - } else{ - receiveValue = receiveValueInputStr; - } - receiveValue = isNaN(receiveValue) ? 0 : receiveValue; this.modelChanged.next(isSwap); - this.altValue = this.formatAmountWithLimitDecimal(receiveValue * this.coinReceiveSelected.rate[this.fiatCode], 8); - this.altValueStr = new Intl.NumberFormat('en-GB').format(this.altValue); } } this.modelChanged.next(isSwap); @@ -377,17 +333,12 @@ export class CreateSwapPage implements OnInit { const coinSwapCodeSelected = event.detail.value; this.coinSwapSelected = this.listConfig.coinSwap.find(s => s.code === coinSwapCodeSelected); this.resetFormControl(); - // this.swapValue = 0; - // this.receiveValue = 0; } handleCoinReceiveChange(event){ const coinReceiveCodeSelected = event.detail.value; this.coinReceiveSelected = this.listConfig.coinReceived.find(s => s.code === coinReceiveCodeSelected); this.resetFormControl(); - // this.swapValue = 0; - // this.receiveValue = 0; - // this.addressSwapValue = ''; } resetFormControl(){ @@ -403,18 +354,6 @@ export class CreateSwapPage implements OnInit { this._cdRef.markForCheck(); } - validateAddress(){ - - const parsedData = this.incomingDataProvider.parseData(this.addressSwapValue); - - if ( - parsedData && - _.indexOf(this.validDataTypeMap, parsedData.type) != -1 - ) { - this.validAddress = this.checkCoinAndNetwork(this.addressSwapValue); - } - } - private checkCoinAndNetwork(data): boolean { let isValid, addrData; From 7f650f9c43c36c868bb6e60f39368802e79f5b7e Mon Sep 17 00:00:00 2001 From: takYoon Date: Sun, 11 Sep 2022 09:58:11 +0700 Subject: [PATCH 16/28] fix app module after merge --- src/app/app.module.ts | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/app/app.module.ts b/src/app/app.module.ts index a384472666f..ff98ad8013c 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -1,5 +1,5 @@ import { HttpClientModule } from '@angular/common/http'; -import { CUSTOM_ELEMENTS_SCHEMA, ErrorHandler, NgModule } from '@angular/core'; +import { APP_INITIALIZER, CUSTOM_ELEMENTS_SCHEMA, ErrorHandler, NgModule } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; import { RouteReuseStrategy } from '@angular/router'; import { ServiceWorkerModule } from '@angular/service-worker'; @@ -50,6 +50,14 @@ import { ClickOutsideModule } from 'ng-click-outside'; import { CountdownModule } from 'ngx-countdown'; import { RECAPTCHA_V3_SITE_KEY, RecaptchaV3Module } from "ng-recaptcha"; +import { NgxMaskModule } from 'ngx-mask'; +import { FeatureFlagsService } from './providers/feature-flags.service'; + +const featureFactory = (featureFlagsService: FeatureFlagsService) => () => + featureFlagsService.loadConfig(); + + + export function translateParserFactory() { return new InterpolatedTranslateParser(); } @@ -95,6 +103,7 @@ export class MyMissingTranslationHandler implements MissingTranslationHandler { backButtonText: '', navAnimation: enterAnimation }), + NgxMaskModule.forRoot(), MatGridListModule, MatFormFieldModule, BrowserAnimationsModule, @@ -133,6 +142,13 @@ export class MyMissingTranslationHandler implements MissingTranslationHandler { ServiceWorkerModule.register('ngsw-worker.js', { enabled: env.name === 'production' }) ], providers: [ + { + provide: APP_INITIALIZER, + useFactory: featureFactory, + deps: [FeatureFlagsService], + multi: true + }, + { provide: RouteReuseStrategy, useClass: IonicRouteStrategy From cd379ad9d17c9077e3156b38193f803880232393 Mon Sep 17 00:00:00 2001 From: takYoon Date: Thu, 15 Sep 2022 17:09:09 +0700 Subject: [PATCH 17/28] create content for order detail --- .../add/create-wallet/create-wallet.html | 2 +- .../create-swap/create-swap.component.html | 2 +- .../swap/create-swap/create-swap.component.ts | 166 ++++++++++++++++-- .../swap/order-swap/order-swap.component.html | 21 ++- .../swap/order-swap/order-swap.component.ts | 67 ++++++- src/app/providers/index.ts | 1 + src/app/providers/order/order-provider.ts | 46 +++++ src/app/providers/providers.module.ts | 4 +- 8 files changed, 284 insertions(+), 25 deletions(-) create mode 100644 src/app/providers/order/order-provider.ts diff --git a/src/app/pages/add/create-wallet/create-wallet.html b/src/app/pages/add/create-wallet/create-wallet.html index 91eb27705e4..b4165da23fc 100755 --- a/src/app/pages/add/create-wallet/create-wallet.html +++ b/src/app/pages/add/create-wallet/create-wallet.html @@ -177,7 +177,7 @@ [ngClass]="{'with-label': createForm.value.singleAddress}">

{{ 'Single Address' | translate }}

- +
The single address feature will force the account to only use one address rather than diff --git a/src/app/pages/swap/create-swap/create-swap.component.html b/src/app/pages/swap/create-swap/create-swap.component.html index 62505c447f1..0b7da4629fc 100644 --- a/src/app/pages/swap/create-swap/create-swap.component.html +++ b/src/app/pages/swap/create-swap/create-swap.component.html @@ -110,7 +110,7 @@
- {{ 'Swap' | translate }} + {{ 'Swap' | translate }}
\ No newline at end of file diff --git a/src/app/pages/swap/create-swap/create-swap.component.ts b/src/app/pages/swap/create-swap/create-swap.component.ts index b3e2d522792..e37f8af0166 100644 --- a/src/app/pages/swap/create-swap/create-swap.component.ts +++ b/src/app/pages/swap/create-swap/create-swap.component.ts @@ -6,7 +6,69 @@ import { CountdownComponent } from 'ngx-countdown'; import { Subject, Subscription } from 'rxjs'; import { debounceTime } from 'rxjs/operators'; import { AddressProvider, Coin, CurrencyProvider, FilterProvider, IncomingDataProvider, RateProvider, ThemeProvider } from 'src/app/providers'; +import { OrderProvider } from 'src/app/providers/order/order-provider'; import { Config, ConfigProvider } from '../../../providers/config/config'; +import { TokenInforPage } from '../../token-info/token-info'; +interface TokenInfo { + coin: string; + blockCreated?: number; + circulatingSupply?: number; + containsBaton: true; + decimals: number; + documentHash?: string; + documentUri: string; + id: string; + initialTokenQty: number; + name: string; + symbol: string; + timestamp: string; + timestamp_unix?: number; + totalBurned: number; + totalMinted: number; + versionType: number; +} + +interface OrderOpts{ + fromCoinCode: string; + amountFrom: number; + isFromToken: boolean; + fromTokenId?: string; + toCoinCode: string; + isToToken: boolean; + toTokenId?: string; + createdRate: number; + addressUserReceive: string; + fromSatUnit: number; + toSatUnit: number; +} + +interface IOrder { + id: string | number; + version: number; + priority: number; + fromCoinCode: string; + fromTokenId?: string; + amountFrom: number; + fromSatUnit: number; + isFromToken: boolean; + toCoinCode: string; + isToToken: boolean; + toSatUnit: number; + amountSentToUser: number; + amountUserDeposit: number; + createdRate: number; + updatedRate: number; + addressUserReceive: string; + adddressUserDeposit: string; + toTokenId?: string; + txId?: string; + status?: string; + isSentToFund?: boolean; + isSentToUser?: boolean; + endedOn?: number; + createdOn?: number; + error?: string; +} @Component({ selector: 'page-create-swap', @@ -56,6 +118,7 @@ export class CreateSwapPage implements OnInit { 'ECashUri', 'LotusUri' ]; + public listConfig = { "coinSwap": [ { @@ -63,47 +126,66 @@ export class CreateSwapPage implements OnInit { "isToken": false, "networkFee": 226, "rate": {}, - "min": 10, // USD - "unitDecimals": 0 + "min": 0, // USD + "tokenInfo": {} }, { "code": "xec", "isToken": false, "networkFee": 226, "rate": {}, - "min": 10, // USD - "unitDecimals": 0 + "min": 0, // USD + "tokenInfo": {} }, { "code": "bch", "isToken": false, "networkFee": 226, "rate": {}, - "min": 10, // USD - "unitDecimals": 0 + "min": 0, // USD + "tokenInfo": {} + }, + { + "code": "abcslp", + "isToken": true, + "networkFee": 1342, + "rate": {}, + "min": 0, // USD + "tokenInfo": {} } ], "coinReceived": [ + { + "code": "abcslp", + "isToken": true, + "networkFee": 1342, + "rate": {}, + "min": 0, // USD + "tokenInfo": {} + }, { "code": "EAT", "isToken": true, "networkFee": 1342, "rate": {}, - "unitDecimals": 0 + "min": 0, // USD + "tokenInfo": {} }, { "code": "bcPro", "isToken": true, "networkFee": 1342, "rate": {}, - "unitDecimals": 0 + "min": 0, // USD + "tokenInfo": {} }, { "code": "xpi", "isToken": false, "networkFee": 226, "rate": {}, - "unitDecimals": 0 + "min": 0, // USD + "tokenInfo": {} } ] } @@ -117,7 +199,8 @@ export class CreateSwapPage implements OnInit { private incomingDataProvider: IncomingDataProvider, private addressProvider: AddressProvider, private form: FormBuilder, - private _cdRef: ChangeDetectorRef + private _cdRef: ChangeDetectorRef, + private orderProvider: OrderProvider ) { this.createForm = this.form.group({ @@ -143,6 +226,26 @@ export class CreateSwapPage implements OnInit { // return ''; return this.currencyProvider.getChain(coin).toLowerCase(); } + + public convertAmountToSatoshiAmount(coinConfig, amount): number{ + if(coinConfig.isToken){ + const decimals = coinConfig.tokenInfo.decimals; + return amount * Math.pow(10, decimals); + } else{ + const precision = _.get(this.currencyProvider.getPrecision(coinConfig.code), 'unitToSatoshi', 0); + return amount * precision; + } + } + + public getSatUnitFromCoin(coinConfig){ + if(coinConfig.isToken){ + const decimals = coinConfig.tokenInfo.decimals; + return Math.pow(10, decimals); + } else{ + const precision = _.get(this.currencyProvider.getPrecision(coinConfig.code), 'unitToSatoshi', 0); + return precision; + } + } handleEvent(event){ if(event.action === 'done'){ @@ -171,7 +274,16 @@ export class CreateSwapPage implements OnInit { ngOnInit() { this.handleUpdateRate(); - + this.orderProvider.getTokenInfo().then( (listTokenInfo : TokenInfo[] )=> { + const allConig = this.listConfig.coinSwap.concat(this.listConfig.coinReceived); + allConig.forEach(coinConfig => { + if(coinConfig.isToken){ + coinConfig.tokenInfo = listTokenInfo.find(s => s.symbol.toLowerCase() === coinConfig.code) + } + }) + }).catch(err => { + console.log(err); + }) this.coinReceiveSelected = this.listConfig.coinReceived[0]; this.coinSwapSelected = this.listConfig.coinSwap[0]; this.subscription = this.modelChanged @@ -224,11 +336,10 @@ export class CreateSwapPage implements OnInit { if(control.value.length === 0){ return { addressNotInput: true }; } - + const addressInputValue = this.createForm.controls['address'].value; // handle case token if(this.coinReceiveSelected.isToken){ try { - const addressInputValue = this.createForm.controls['address'].value; const { prefix, type, hash } = this.addressProvider.decodeAddress(addressInputValue); if(prefix === 'etoken' || prefix === 'ecash'){ return null; @@ -242,12 +353,12 @@ export class CreateSwapPage implements OnInit { } // handle case coin - const parsedData = this.incomingDataProvider.parseData(this.addressSwapValue); + const parsedData = this.incomingDataProvider.parseData(addressInputValue); if ( parsedData && _.indexOf(this.validDataTypeMap, parsedData.type) != -1 ) { - this.validAddress = this.checkCoinAndNetwork(this.addressSwapValue); + this.validAddress = this.checkCoinAndNetwork(addressInputValue); if(this.validAddress){ return null; } else { @@ -376,4 +487,29 @@ export class CreateSwapPage implements OnInit { this.router.navigate(['/setting']); } + public createOrder(){ + const orderOpts = { + fromCoinCode : this.coinSwapSelected.code, + amountFrom : this.convertAmountToSatoshiAmount(this.coinSwapSelected, (this.createForm.controls['swapAmount'].value as number)), + isFromToken: this.coinSwapSelected.isToken, + fromTokenId: this.coinSwapSelected.isToken ? this.coinSwapSelected.tokenInfo.id : null, + toCoinCode: this.coinReceiveSelected.code, + toTokenId: this.coinReceiveSelected.isToken? this.coinReceiveSelected.tokenInfo.id : null, + isToToken: this.coinReceiveSelected.isToken, + createdRate: this.coinSwapSelected.rate.USD / this.coinReceiveSelected.rate.USD, + addressUserReceive: this.createForm.controls['address'].value, + fromSatUnit: this.getSatUnitFromCoin(this.coinSwapSelected), + toSatUnit: this.getSatUnitFromCoin(this.coinReceiveSelected) + } as OrderOpts; + this.orderProvider.createOrder(orderOpts).then((result : IOrder) =>{ + this.router.navigate(['/order'], { + state: { + order: result + } + }); + }).catch(err => { + console.log(err); + }) + } + } diff --git a/src/app/pages/swap/order-swap/order-swap.component.html b/src/app/pages/swap/order-swap/order-swap.component.html index 9e2cb9b4e92..9bda4ad31b8 100644 --- a/src/app/pages/swap/order-swap/order-swap.component.html +++ b/src/app/pages/swap/order-swap/order-swap.component.html @@ -1,3 +1,18 @@ -

- order-swap works! -

+ +
+

status: {{ order.status}}

+

+ 1 {{ order.fromCoinCode}} + {{ order.amountFrom / order.fromSatUnit * ((order.updatedRate && order.updatedRate > 0) ? order.updatedRate : order.createdRate) }} + +

+

Deposit address : {{ order.adddressUserDeposit }}

+

Send exactly: {{ order.amountFrom / order.fromSatUnit}}

+

You receive: {{ order.amountFrom / order.fromSatUnit * ((order.updatedRate && order.updatedRate > 0) ? order.updatedRate : order.createdRate)}}

+ + +

TxId: {{order.txId}}

+ `
+
+
+ diff --git a/src/app/pages/swap/order-swap/order-swap.component.ts b/src/app/pages/swap/order-swap/order-swap.component.ts index 9a0eca0cf62..5ec9496195f 100644 --- a/src/app/pages/swap/order-swap/order-swap.component.ts +++ b/src/app/pages/swap/order-swap/order-swap.component.ts @@ -1,14 +1,73 @@ -import { Component, OnInit } from '@angular/core'; - +import { Component, OnInit, ViewChild } from '@angular/core'; +import { Router } from '@angular/router'; +import { NavParams } from '@ionic/angular'; +import { CountdownComponent } from 'ngx-countdown'; +import { OrderProvider } from 'src/app/providers'; +interface IOrder { + id: string | number; + version: number; + priority: number; + fromCoinCode: string; + fromTokenId?: string; + amountFrom: number; + fromSatUnit: number; + isFromToken: boolean; + toCoinCode: string; + isToToken: boolean; + toSatUnit: number; + amountSentToUser: number; + amountUserDeposit: number; + createdRate: number; + updatedRate: number; + addressUserReceive: string; + adddressUserDeposit: string; + toTokenId?: string; + txId?: string; + status?: string; + isSentToFund?: boolean; + isSentToUser?: boolean; + endedOn?: number; + createdOn?: number; + error?: string; +} @Component({ selector: 'app-order-swap', templateUrl: './order-swap.component.html', styleUrls: ['./order-swap.component.scss'], }) export class OrderSwapPage implements OnInit { + navPramss: any; + order: IOrder = null; + @ViewChild('cd', { static: false }) private countdown: CountdownComponent; + constructor( private router: Router, + private navParams: NavParams, + private orderProvider: OrderProvider) { + if (this.router.getCurrentNavigation()) { + this.navPramss = this.router.getCurrentNavigation().extras.state; + } else { + this.navPramss = history ? history.state : {}; + } + this.order = this.navPramss.order; + + } + + ngOnInit() { + // setInterval( + // this.getOrderInfo(), + // ) + } - constructor() { } + handleEvent(event){ + if(event.action === 'done'){ + this.countdown.restart(); + this.getOrderInfo(); + } + } - ngOnInit() {} + getOrderInfo(){ + this.orderProvider.getOrderInfo(this.order.id).then((res: IOrder) => { + this.order = res; + }) + } } diff --git a/src/app/providers/index.ts b/src/app/providers/index.ts index f15edb985b5..5f792bac85d 100644 --- a/src/app/providers/index.ts +++ b/src/app/providers/index.ts @@ -58,6 +58,7 @@ export { ProfileProvider } from './profile/profile'; export { PushNotificationsProvider } from './push-notifications/push-notifications'; export { RateProvider } from './rate/rate'; export { LixiLotusProvider } from './lixi-lotus/lixi-lotus'; +export { OrderProvider } from './order/order-provider'; export { ReplaceParametersProvider } from './replace-parameters/replace-parameters'; export { ScanProvider } from './scan/scan'; export { ThemeProvider } from './theme/theme'; diff --git a/src/app/providers/order/order-provider.ts b/src/app/providers/order/order-provider.ts new file mode 100644 index 00000000000..576f232d589 --- /dev/null +++ b/src/app/providers/order/order-provider.ts @@ -0,0 +1,46 @@ +import { HttpClient } from "@angular/common/http"; +import { Injectable } from "@angular/core"; +import { ConfigProvider } from "../config/config"; +import { Logger } from "../logger/logger"; + +@Injectable({ + providedIn: 'root' + }) + export class OrderProvider { + private bwsURL: string; + + + constructor( + private logger: Logger, + private configProvider: ConfigProvider, + private http: HttpClient + ) { + this.logger.debug('LixiLotusProvider initialized'); + const defaults = this.configProvider.getDefaults(); + this.bwsURL = defaults.bws.url; + } + + public getTokenInfo(): Promise { + return new Promise(resolve =>{ + this.http.get(`${this.bwsURL}/v3/tokenInfo/`).subscribe(res =>{ + resolve(res); + }); + }); + } + + public getOrderInfo(orderId): Promise { + return new Promise(resolve =>{ + this.http.get(`${this.bwsURL}/v3/order/${orderId}`).subscribe(res =>{ + resolve(res); + }); + }); + } + + public createOrder(orderOpts): Promise { + return new Promise(resolve =>{ + this.http.post(`${this.bwsURL}/v3/order/create/`, orderOpts).subscribe(res =>{ + resolve(res); + }); + }); + } + } \ No newline at end of file diff --git a/src/app/providers/providers.module.ts b/src/app/providers/providers.module.ts index 0e4fa7562e2..f2afdefbb50 100644 --- a/src/app/providers/providers.module.ts +++ b/src/app/providers/providers.module.ts @@ -53,6 +53,7 @@ import { QRScanner, RateProvider, LixiLotusProvider, + OrderProvider, TokenProvider, ReleaseProvider, ReplaceParametersProvider, @@ -72,7 +73,7 @@ import { CustomErrorHandler, ThemeDetection, RedirectGuard, - PreviousRouteService + PreviousRouteService, } from './index'; @NgModule({ @@ -122,6 +123,7 @@ import { PushNotificationsProvider, RateProvider, LixiLotusProvider, + OrderProvider, TokenProvider, ReplaceParametersProvider, ReleaseProvider, From 388143b2c97179cce3b086e8befc524f3323d2f8 Mon Sep 17 00:00:00 2001 From: takYoon Date: Tue, 20 Sep 2022 15:46:44 +0700 Subject: [PATCH 18/28] update code for swap --- src/app/pages/swap/config-swap.ts | 89 ++ .../create-swap/create-swap.component.html | 204 ++--- .../swap/create-swap/create-swap.component.ts | 793 ++++++++++-------- .../swap/order-swap/order-swap.component.html | 8 +- .../swap/order-swap/order-swap.component.ts | 3 +- src/app/providers/order/order-provider.ts | 9 + 6 files changed, 663 insertions(+), 443 deletions(-) create mode 100644 src/app/pages/swap/config-swap.ts diff --git a/src/app/pages/swap/config-swap.ts b/src/app/pages/swap/config-swap.ts new file mode 100644 index 00000000000..890e0a28c2d --- /dev/null +++ b/src/app/pages/swap/config-swap.ts @@ -0,0 +1,89 @@ +export interface TokenInfo { + coin: string; + blockCreated?: number; + circulatingSupply?: number; + containsBaton: true; + decimals: number; + documentHash?: string; + documentUri: string; + id: string; + initialTokenQty: number; + name: string; + symbol: string; + timestamp: string; + timestamp_unix?: number; + totalBurned: number; + totalMinted: number; + versionType: number; +} + +export interface TokenItem{ + tokenId : string; + tokenInfo: TokenInfo, + amountToken: number, + utxoToken: any; +} + + +export class ConfigSwap { + coinSwap: CoinConfig[]; + coinReceive: CoinConfig[]; + static create(opts){ + const x = new ConfigSwap(); + x.coinReceive = opts.coinReceive; + x.coinSwap = opts.coinSwap; + return x; + } + static fromObj(opts){ + const x = new ConfigSwap(); + x.coinReceive = opts.coinReceive; + x.coinSwap = opts.coinSwap; + + return x; + } +} + +export class CoinConfig{ + code: string; + isToken: boolean; + networkFee?: number; + rate?: any; + min?: number; + minConvertToSat?: number; + max?: number; + maxConvertToSat?: number; + tokenInfo?: TokenInfo; + isEnable?: boolean; + + static create(opts){ + const x = new CoinConfig(); + x.code = opts.code; + x.isToken = opts.isToken; + x.networkFee = opts.networkFee || 0; + x.rate = null; + x.min = opts.min || 0; + x.minConvertToSat = opts.minConvertToSat || 0; + x.max = opts.max || 0; + x.maxConvertToSat = opts.maxConvertToSat || 0; + x.tokenInfo = opts.tokenInfo || null; + x.isEnable = opts.isEnable || true; + + return x; + } + + static fromObj(opts){ + const x = new CoinConfig(); + x.code = opts.code; + x.isToken = opts.isToken; + x.networkFee = opts.networkFee; + x.rate = opts.rate; + x.min = opts.min; + x.minConvertToSat = opts.minConvertToSat; + x.max = opts.max; + x.maxConvertToSat = opts.maxConvertToSat; + x.tokenInfo = opts.tokenInfo; + x.isEnable = opts.isEnable; + + return x; + } +} diff --git a/src/app/pages/swap/create-swap/create-swap.component.html b/src/app/pages/swap/create-swap/create-swap.component.html index 0b7da4629fc..364c90d1353 100644 --- a/src/app/pages/swap/create-swap/create-swap.component.html +++ b/src/app/pages/swap/create-swap/create-swap.component.html @@ -1,116 +1,118 @@ - - -
- - + + + +
+ + +
+
+ + + + + + + + +
+ + +
+ + +
- - - - - - - - - - - - -
- - - -
- -
-
- {{'Swap' | translate}} + +
+
+ {{'Swap' | translate}} +
+ + + + + + + +
- - - - - - - - -
-
- - 1  {{coinSwapSelected.code}} - - {{formatAmountWithLimitDecimal((coinSwapSelected.rate.USD /coinReceiveSelected.rate.USD),8)}}  {{coinReceiveSelected.code}} - - -
-
-
-
-
-
You send
-
+
+ + 1  {{coinSwapSelected.code}} + + {{formatAmountWithLimitDecimal((coinSwapSelected.rate.USD /coinReceiveSelected.rate.USD),8)}}  {{coinReceiveSelected.code}} + + +
+
+ +
+
+
You send
+
+ + + + {{coin.code}} + + + + + + + + +
+
+
+
You receive
- - + + {{coin.code}} - + - + -
-
-
You receive
- - - - {{coin.code}} - - - - - - - +
+ {{altValue | mask: 'separator.8':',' }} {{fiatCode}}
-
-
- {{altValue | mask: 'separator.8':',' }} {{fiatCode}} -
- You need to deposit at least {{ minWithCurrentFiat | mask: 'separator.8':',' }} {{fiatCode}} + You need to deposit at least {{ minWithCurrentFiat | mask: 'separator.8':',' }} {{fiatCode}} + You can not deposit above {{ maxWithCurrentFiat | mask: 'separator.8':',' }} {{fiatCode}} +
+ Network fee: + + {{ coinReceiveSelected.networkFee | satToUnit: getChain((coinReceiveSelected.code)) }} + + + {{ getFeeToken(coinReceiveSelected.networkFee) }} XEC + +
+ -
- Network fee: - - {{ coinReceiveSelected.networkFee | satToUnit: getChain(coinReceiveSelected.code) }} - - - {{ getFeeToken(coinReceiveSelected.networkFee) }} XEC - +
+

Your {{ coinReceiveSelected.code }} address

+ + + + Wrong format addresss
- - -
-

Your {{ coinReceiveSelected.code }} address

- - - - Wrong format addresss +
- -
- - - - - - -
- {{ 'Swap' | translate }} -
-
-
\ No newline at end of file + + + + + + +
+ {{ 'Swap' | translate }} +
+
+
+ diff --git a/src/app/pages/swap/create-swap/create-swap.component.ts b/src/app/pages/swap/create-swap/create-swap.component.ts index e37f8af0166..f158b305e2d 100644 --- a/src/app/pages/swap/create-swap/create-swap.component.ts +++ b/src/app/pages/swap/create-swap/create-swap.component.ts @@ -1,14 +1,38 @@ -import { ChangeDetectionStrategy, ChangeDetectorRef, Component, ElementRef, OnInit, ViewChild, ViewEncapsulation } from '@angular/core'; -import { AbstractControl, FormBuilder, FormControl, FormGroup, ValidationErrors, ValidatorFn } from '@angular/forms'; +import { + ChangeDetectionStrategy, + ChangeDetectorRef, + Component, + ElementRef, + OnInit, + ViewChild, + ViewEncapsulation +} from '@angular/core'; +import { + AbstractControl, + FormBuilder, + FormControl, + FormGroup, + ValidationErrors, + ValidatorFn +} from '@angular/forms'; import { Router } from '@angular/router'; import _ from 'lodash'; import { CountdownComponent } from 'ngx-countdown'; import { Subject, Subscription } from 'rxjs'; import { debounceTime } from 'rxjs/operators'; -import { AddressProvider, Coin, CurrencyProvider, FilterProvider, IncomingDataProvider, RateProvider, ThemeProvider } from 'src/app/providers'; +import { + AddressProvider, + Coin, + CurrencyProvider, + FilterProvider, + IncomingDataProvider, + RateProvider, + ThemeProvider +} from 'src/app/providers'; import { OrderProvider } from 'src/app/providers/order/order-provider'; import { Config, ConfigProvider } from '../../../providers/config/config'; import { TokenInforPage } from '../../token-info/token-info'; +import { CoinConfig, ConfigSwap } from '../config-swap'; interface TokenInfo { coin: string; blockCreated?: number; @@ -28,7 +52,7 @@ interface TokenInfo { versionType: number; } -interface OrderOpts{ +interface OrderOpts { fromCoinCode: string; amountFrom: number; isFromToken: boolean; @@ -38,10 +62,11 @@ interface OrderOpts{ toTokenId?: string; createdRate: number; addressUserReceive: string; - fromSatUnit: number; - toSatUnit: number; + fromSatUnit?: number; + toSatUnit?: number; + toTokenInfo? : TokenInfo; + fromTokenInfo?: TokenInfo; } - interface IOrder { id: string | number; version: number; @@ -49,8 +74,8 @@ interface IOrder { fromCoinCode: string; fromTokenId?: string; amountFrom: number; - fromSatUnit: number; - isFromToken: boolean; + fromSatUnit?: number; + isFromToken?: boolean; toCoinCode: string; isToToken: boolean; toSatUnit: number; @@ -61,13 +86,16 @@ interface IOrder { addressUserReceive: string; adddressUserDeposit: string; toTokenId?: string; - txId?: string; + txIdUserDeposit?: string; + txIdUserReceive?: string; status?: string; isSentToFund?: boolean; isSentToUser?: boolean; endedOn?: number; createdOn?: number; error?: string; + toTokenInfo? : TokenInfo; + fromTokenInfo?: TokenInfo; } @Component({ @@ -79,10 +107,10 @@ interface IOrder { }) export class CreateSwapPage implements OnInit { public isScroll = false; - public currentTheme:any; + public currentTheme: any; public rates: any; - public coinSwapSelected: any; - public coinReceiveSelected: any; + public coinSwapSelected: CoinConfig; + public coinReceiveSelected: CoinConfig; public altValue = 0; private modelChanged: Subject = new Subject(); private subscription: Subscription; @@ -91,14 +119,15 @@ export class CreateSwapPage implements OnInit { public config: Config; public addressSwapValue: any; public validAddress: any; - public minAmount : any; + public minAmount: any; public minWithCurrentFiat: any; - public createForm: FormGroup + public maxWithCurrentFiat: any; + public createForm: FormGroup; debounceTime = 500; // public config: Config; @ViewChild('cd', { static: false }) private countdown: CountdownComponent; - @ViewChild('inputSwap') inputSwap:ElementRef; - @ViewChild('inputReceive') inputReceive:ElementRef; + @ViewChild('inputSwap') inputSwap: ElementRef; + @ViewChild('inputReceive') inputReceive: ElementRef; private validDataTypeMap: string[] = [ 'BitcoinAddress', 'BitcoinCashAddress', @@ -119,76 +148,78 @@ export class CreateSwapPage implements OnInit { 'LotusUri' ]; - public listConfig = { - "coinSwap": [ - { - "code": "xpi", - "isToken": false, - "networkFee": 226, - "rate": {}, - "min": 0, // USD - "tokenInfo": {} - }, - { - "code": "xec", - "isToken": false, - "networkFee": 226, - "rate": {}, - "min": 0, // USD - "tokenInfo": {} - }, - { - "code": "bch", - "isToken": false, - "networkFee": 226, - "rate": {}, - "min": 0, // USD - "tokenInfo": {} - }, - { - "code": "abcslp", - "isToken": true, - "networkFee": 1342, - "rate": {}, - "min": 0, // USD - "tokenInfo": {} - } - ], - "coinReceived": [ - { - "code": "abcslp", - "isToken": true, - "networkFee": 1342, - "rate": {}, - "min": 0, // USD - "tokenInfo": {} - }, - { - "code": "EAT", - "isToken": true, - "networkFee": 1342, - "rate": {}, - "min": 0, // USD - "tokenInfo": {} - }, - { - "code": "bcPro", - "isToken": true, - "networkFee": 1342, - "rate": {}, - "min": 0, // USD - "tokenInfo": {} - }, - { - "code": "xpi", - "isToken": false, - "networkFee": 226, - "rate": {}, - "min": 0, // USD - "tokenInfo": {} - } - ] - } + // public listConfig = { + // "coinSwap": [ + // { + // "code": "xpi", + // "isToken": false, + // "networkFee": 226, + // "rate": {}, + // "min": 0, // USD + // "tokenInfo": {} + // }, + // { + // "code": "xec", + // "isToken": false, + // "networkFee": 226, + // "rate": {}, + // "min": 0, // USD + // "tokenInfo": {} + // }, + // { + // "code": "bch", + // "isToken": false, + // "networkFee": 226, + // "rate": {}, + // "min": 0, // USD + // "tokenInfo": {} + // }, + // { + // "code": "abcslp", + // "isToken": true, + // "networkFee": 1342, + // "rate": {}, + // "min": 0, // USD + // "tokenInfo": {} + // } + // ], + // "coinReceive": [ + // { + // "code": "abcslp", + // "isToken": true, + // "networkFee": 1342, + // "rate": {}, + // "min": 0, // USD + // "tokenInfo": {} + // }, + // { + // "code": "EAT", + // "isToken": true, + // "networkFee": 1342, + // "rate": {}, + // "min": 0, // USD + // "tokenInfo": {} + // }, + // { + // "code": "bcPro", + // "isToken": true, + // "networkFee": 1342, + // "rate": {}, + // "min": 0, // USD + // "tokenInfo": {} + // }, + // { + // "code": "xpi", + // "isToken": false, + // "networkFee": 226, + // "rate": {}, + // "min": 0, // USD + // "tokenInfo": {} + // } + // ] + // } + + public listConfig: ConfigSwap = null; constructor( private router: Router, @@ -201,315 +232,399 @@ export class CreateSwapPage implements OnInit { private form: FormBuilder, private _cdRef: ChangeDetectorRef, private orderProvider: OrderProvider - ) - { - this.createForm = this.form.group({ - swapAmount:[0,{ - validators: [this.amountMinValidator()], + ) { + this.createForm = this.form.group({ + swapAmount: [ + 0, + { + validators: [this.amountMinValidator(true), this.amountMaxValidator()], + updateOn: 'change' + } + ], + // swapAmount: [null], + receiveAmount: [ + 0, + { + validators: [this.amountMinValidator(false)], updateOn: 'change' - }], - // swapAmount: [null], - receiveAmount:[0,{ - validators: [this.amountMinValidator()], + } + ], + address: [ + null, + { + validators: [this.addressValidator()], updateOn: 'change' - }], - address: [ - null, { - validators: [this.addressValidator()], - updateOn: 'change' - } - ] - }); - } + } + ] + }); + } - public getChain(coin: Coin): string { - // return ''; - return this.currencyProvider.getChain(coin).toLowerCase(); - } + public getChain(coin: string): string { + return this.currencyProvider.getChain(coin as Coin).toLowerCase(); + } + - public convertAmountToSatoshiAmount(coinConfig, amount): number{ - if(coinConfig.isToken){ - const decimals = coinConfig.tokenInfo.decimals; - return amount * Math.pow(10, decimals); - } else{ - const precision = _.get(this.currencyProvider.getPrecision(coinConfig.code), 'unitToSatoshi', 0); - return amount * precision; - } + public convertAmountToSatoshiAmount(coinConfig, amount): number { + if (coinConfig.isToken) { + const decimals = coinConfig.tokenInfo.decimals; + return amount * Math.pow(10, decimals); + } else { + const precision = _.get( + this.currencyProvider.getPrecision(coinConfig.code), + 'unitToSatoshi', + 0 + ); + return amount * precision; } + } - public getSatUnitFromCoin(coinConfig){ - if(coinConfig.isToken){ - const decimals = coinConfig.tokenInfo.decimals; - return Math.pow(10, decimals); - } else{ - const precision = _.get(this.currencyProvider.getPrecision(coinConfig.code), 'unitToSatoshi', 0); - return precision; - } - } - - handleEvent(event){ - if(event.action === 'done'){ - this.countdown.restart(); - this.handleUpdateRate(); - } + public getSatUnitFromCoin(coinConfig) { + if (coinConfig.isToken) { + const decimals = coinConfig.tokenInfo.decimals; + return Math.pow(10, decimals); + } else { + const precision = _.get( + this.currencyProvider.getPrecision(coinConfig.code), + 'unitToSatoshi', + 0 + ); + return precision; } + } - async handleScrolling(event) { - if (event.detail.currentY > 0) { - this.isScroll = true; - } - else { - this.isScroll = false; - } + handleEvent(event) { + if (event.action === 'done') { + this.countdown.restart(); + this.handleUpdateRate(); } + } - getFeeToken(networkFee) : number{ - const precision = _.get(this.currencyProvider.getPrecision('xec' as Coin), 'unitToSatoshi', 0); - if(!precision){ - return 0; - } else{ - return networkFee / precision; - } + async handleScrolling(event) { + if (event.detail.currentY > 0) { + this.isScroll = true; + } else { + this.isScroll = false; } + } - ngOnInit() { - this.handleUpdateRate(); - this.orderProvider.getTokenInfo().then( (listTokenInfo : TokenInfo[] )=> { - const allConig = this.listConfig.coinSwap.concat(this.listConfig.coinReceived); - allConig.forEach(coinConfig => { - if(coinConfig.isToken){ - coinConfig.tokenInfo = listTokenInfo.find(s => s.symbol.toLowerCase() === coinConfig.code) - } - }) - }).catch(err => { - console.log(err); - }) - this.coinReceiveSelected = this.listConfig.coinReceived[0]; - this.coinSwapSelected = this.listConfig.coinSwap[0]; - this.subscription = this.modelChanged - .pipe( - debounceTime(this.debounceTime), - ) - .subscribe(isSwap => { - this.handleInputChange(isSwap); - }); + getFeeToken(networkFee): number { + const precision = _.get( + this.currencyProvider.getPrecision('xec' as Coin), + 'unitToSatoshi', + 0 + ); + if (!precision) { + return 0; + } else { + return networkFee / precision; } + } - handleInputChange(isSwap: Boolean){ + ngOnInit() { + this.orderProvider.getConfigSwap().then(configSwap => { + this.listConfig = configSwap; + this._cdRef.markForCheck(); + this.orderProvider + .getTokenInfo() + .then((listTokenInfo: TokenInfo[]) => { + const allConig = this.listConfig.coinSwap.concat( + this.listConfig.coinReceive + ); + allConig.forEach(coinConfig => { + if (coinConfig.isToken) { + coinConfig.tokenInfo = listTokenInfo.find( + s => s.symbol.toLowerCase() === coinConfig.code + ); + } + }); + }) + .catch(err => { + console.log(err); + }); + this.coinReceiveSelected = this.listConfig.coinReceive[0]; + this.coinSwapSelected = this.listConfig.coinSwap[0]; + this.subscription = this.modelChanged + .pipe(debounceTime(this.debounceTime)) + .subscribe(isSwap => { + this.handleInputChange(isSwap); + }); + }); + } - if(!!isSwap){ - const result = this.createForm.controls['swapAmount'].value * ( this.coinSwapSelected.rate.USD / this.coinReceiveSelected.rate.USD); - this.createForm.controls['receiveAmount'].setValue(result); - this.altValue = this.createForm.controls['swapAmount'].value * this.coinSwapSelected.rate[this.fiatCode]; - } else{ - const result = (this.createForm.controls['receiveAmount'].value * ( this.coinReceiveSelected.rate.USD / this.coinSwapSelected.rate.USD));; - this.createForm.controls['swapAmount'].setValue(result); - this.altValue = this.createForm.controls['receiveAmount'].value * this.coinReceiveSelected.rate[this.fiatCode]; - } + handleInputChange(isSwap: Boolean) { + if (!!isSwap) { + const result = + this.createForm.controls['swapAmount'].value * + (this.coinSwapSelected.rate.USD / this.coinReceiveSelected.rate.USD); + this.createForm.controls['receiveAmount'].setValue(result); + } else { + const result = + this.createForm.controls['receiveAmount'].value * + (this.coinReceiveSelected.rate.USD / this.coinSwapSelected.rate.USD); + this.createForm.controls['swapAmount'].setValue(result); } + } - amountMinValidator(): ValidatorFn { - return (control: AbstractControl): ValidationErrors | null => { - if(control.value === 0){ - return { amountNotInput: true }; - } - if(this.altValue > 0 ){ - this.minWithCurrentFiat = this.coinSwapSelected.min * this.usdRate[this.fiatCode]; - if(this.altValue < this.minWithCurrentFiat){ - return { amountMinValidator: true }; - } else{ - return null; - } - } - else{ + amountMinValidator(isSwap: boolean): ValidatorFn { + return (control: AbstractControl): ValidationErrors | null => { + if (control.value === 0) { + return { amountNotInput: true }; + } + if (!!isSwap) { + this.altValue = + control.value * + this.coinSwapSelected.rate[this.fiatCode]; + } else { + this.altValue = + control.value * + this.coinReceiveSelected.rate[this.fiatCode]; + } + if (this.altValue > 0) { + this.minWithCurrentFiat = + this.coinSwapSelected.min * this.usdRate[this.fiatCode]; + if (this.altValue < this.minWithCurrentFiat) { + return { amountMinValidator: true }; + } else { return null; } - }; - } + } else { + return null; + } + }; + } - addressValidator():ValidatorFn{ - return (control: AbstractControl): ValidationErrors | null => { - // handle case no address input - if(!control.value){ + amountMaxValidator(): ValidatorFn { + return (control: AbstractControl): ValidationErrors | null => { + if (control.value === 0) { + return { amountNotInput: true }; + } + if (this.altValue > 0) { + this.maxWithCurrentFiat = + this.coinSwapSelected.max * this.usdRate[this.fiatCode]; + if (this.altValue > this.maxWithCurrentFiat) { + return { amountMaxValidator: true }; + } else { return null; } - if(control.value.length === 0){ - return { addressNotInput: true }; - } - const addressInputValue = this.createForm.controls['address'].value; - // handle case token - if(this.coinReceiveSelected.isToken){ - try { - const { prefix, type, hash } = this.addressProvider.decodeAddress(addressInputValue); - if(prefix === 'etoken' || prefix === 'ecash'){ - return null; - } else{ - return { addressInvalid: true } - } - } - catch(e){ - return { addressInvalid: true } - } - } - - // handle case coin - const parsedData = this.incomingDataProvider.parseData(addressInputValue); - if ( - parsedData && - _.indexOf(this.validDataTypeMap, parsedData.type) != -1 - ) { - this.validAddress = this.checkCoinAndNetwork(addressInputValue); - if(this.validAddress){ + } else { + return null; + } + }; + } + + + addressValidator(): ValidatorFn { + return (control: AbstractControl): ValidationErrors | null => { + // handle case no address input + if (!control.value) { + return null; + } + if (control.value.length === 0) { + return { addressNotInput: true }; + } + const addressInputValue = this.createForm.controls['address'].value; + // handle case token + if (this.coinReceiveSelected.isToken) { + try { + const { prefix, type, hash } = + this.addressProvider.decodeAddress(addressInputValue); + if (prefix === 'etoken' || prefix === 'ecash') { return null; } else { - return { addressInvalid: true } + return { addressInvalid: true }; } - } else{ - return { addressInvalid: true } + } catch (e) { + return { addressInvalid: true }; } } - } - handleKeyDown(isSwap: boolean, event){ - const keyInput = event.key; - const pattern = /[^0-9\.]/; - const keyCode = event.keyCode; - const allowSpecialKeyCode = [37, 39, 8, 46]; - const swapValueInputStr = this.createForm.controls['swapAmount'].value.toString(); - const receiveValueInputStr = this.createForm.controls['receiveAmount'].value.toString(); - if(isSwap){ - if(keyInput === '.'){ - if(swapValueInputStr.split('.').length > 1) { - event.preventDefault(); - } - } - else if (!allowSpecialKeyCode.includes(keyCode) && pattern.test(keyInput)) { - event.preventDefault(); + // handle case coin + const parsedData = this.incomingDataProvider.parseData(addressInputValue); + if ( + parsedData && + _.indexOf(this.validDataTypeMap, parsedData.type) != -1 + ) { + this.validAddress = this.checkCoinAndNetwork(addressInputValue); + if (this.validAddress) { + return null; + } else { + return { addressInvalid: true }; } - else{ - this.modelChanged.next(isSwap); - } + } else { + return { addressInvalid: true }; } - else{ - if (!allowSpecialKeyCode.includes(keyCode) && pattern.test(keyInput)) { + }; + } + + handleKeyDown(isSwap: boolean, event) { + const keyInput = event.key; + const pattern = /[^0-9\.]/; + const keyCode = event.keyCode; + const allowSpecialKeyCode = [37, 39, 8, 46]; + const swapValueInputStr = + this.createForm.controls['swapAmount'].value.toString(); + const receiveValueInputStr = + this.createForm.controls['receiveAmount'].value.toString(); + if (isSwap) { + if (keyInput === '.') { + if (swapValueInputStr.split('.').length > 1) { event.preventDefault(); } - else{ - this.modelChanged.next(isSwap); - } + } else if ( + !allowSpecialKeyCode.includes(keyCode) && + pattern.test(keyInput) + ) { + event.preventDefault(); + } else { + this.modelChanged.next(isSwap); + } + } else { + if (!allowSpecialKeyCode.includes(keyCode) && pattern.test(keyInput)) { + event.preventDefault(); + } else { + this.modelChanged.next(isSwap); } - this.modelChanged.next(isSwap); } + this.modelChanged.next(isSwap); + } - formatAmountWithLimitDecimal(amount:number, maxDecimals):number { - if(amount.toString().split('.').length > 1){ - if(amount.toString().split('.')[1].length > maxDecimals){ - return Number(amount.toString().split('.')[0] + '.' + amount.toString().split('.')[1].substr(0, maxDecimals)); - } - return amount; - } else { - return amount; + formatAmountWithLimitDecimal(amount: number, maxDecimals): number { + if (amount.toString().split('.').length > 1) { + if (amount.toString().split('.')[1].length > maxDecimals) { + return Number( + amount.toString().split('.')[0] + + '.' + + amount.toString().split('.')[1].substr(0, maxDecimals) + ); } + return amount; + } else { + return amount; } + } - formatInput(balance){ - if (typeof balance === 'string') - balance = balance.replace(/,/g, '') + formatInput(balance) { + if (typeof balance === 'string') balance = balance.replace(/,/g, ''); if (isNaN(Number(balance)) || Number(balance) <= 0) { - return "0.00"; + return '0.00'; } else { - if (Number(balance) < 10) { - return Number(Number(balance).toFixed(Math.round(1/Number(balance)).toString().length+2)).toLocaleString("en-GB"); - } else { - return Number(Number(balance).toFixed(Math.round(1/Number(balance)).toString().length+1)).toLocaleString("en-GB"); - } - } + if (Number(balance) < 10) { + return Number( + Number(balance).toFixed( + Math.round(1 / Number(balance)).toString().length + 2 + ) + ).toLocaleString('en-GB'); + } else { + return Number( + Number(balance).toFixed( + Math.round(1 / Number(balance)).toString().length + 1 + ) + ).toLocaleString('en-GB'); + } } + } - handleUpdateRate(){ - this.rateProvider.updateRatesCustom().then(data => { - this.usdRate = data['eat']; - this.listConfig.coinSwap.forEach(coin =>{ - const code = coin.code.toLowerCase(); - coin.rate = data[code]; - }); - this.listConfig.coinReceived.forEach(coin =>{ - const code = coin.code.toLowerCase(); - coin.rate = data[code]; - }); + handleUpdateRate() { + this.rateProvider.updateRatesCustom().then(data => { + this.usdRate = data['eat']; + this.listConfig.coinSwap.forEach(coin => { + const code = coin.code.toLowerCase(); + coin.rate = data[code]; }); - } + this.listConfig.coinReceive.forEach(coin => { + const code = coin.code.toLowerCase(); + coin.rate = data[code]; + }); + }); + } - handleCoinSwapChange(event){ - const coinSwapCodeSelected = event.detail.value; - this.coinSwapSelected = this.listConfig.coinSwap.find(s => s.code === coinSwapCodeSelected); - this.resetFormControl(); - } + handleCoinSwapChange(event) { + const coinSwapCodeSelected = event.detail.value; + this.coinSwapSelected = this.listConfig.coinSwap.find( + s => s.code === coinSwapCodeSelected + ); + this.resetFormControl(); + } - handleCoinReceiveChange(event){ - const coinReceiveCodeSelected = event.detail.value; - this.coinReceiveSelected = this.listConfig.coinReceived.find(s => s.code === coinReceiveCodeSelected); - this.resetFormControl(); - } + handleCoinReceiveChange(event) { + const coinReceiveCodeSelected = event.detail.value; + this.coinReceiveSelected = this.listConfig.coinReceive.find( + s => s.code === coinReceiveCodeSelected + ); + this.resetFormControl(); + } - resetFormControl(){ - this.createForm.controls['swapAmount'].setValue(0); - this.createForm.controls['receiveAmount'].setValue(0); - this.createForm.controls['address'].setValue(''); - } + resetFormControl() { + this.createForm.controls['swapAmount'].setValue(0); + this.createForm.controls['receiveAmount'].setValue(0); + this.createForm.controls['address'].setValue(''); + } - ionViewWillEnter() { - this.config = this.configProvider.get(); - this.fiatCode = this.config.wallet.settings.alternativeIsoCode; - this.currentTheme = this.themeProvider.getCurrentAppTheme() === 'Dark Mode' ? 'dark' : 'light'; - this._cdRef.markForCheck(); - } + ionViewWillEnter() { + this.config = this.configProvider.get(); + this.fiatCode = this.config.wallet.settings.alternativeIsoCode; + this.currentTheme = + this.themeProvider.getCurrentAppTheme() === 'Dark Mode' + ? 'dark' + : 'light'; + this._cdRef.markForCheck(); + } - private checkCoinAndNetwork(data): boolean { - let isValid, addrData; + private checkCoinAndNetwork(data): boolean { + let isValid, addrData; - addrData = this.addressProvider.getCoinAndNetwork( - data, - 'livenet' - ); - isValid = - this.currencyProvider.getChain(this.coinReceiveSelected.code as Coin).toLowerCase() == - addrData.coin && addrData.network == 'livenet'; - - if (isValid) { - return true; - } else { + addrData = this.addressProvider.getCoinAndNetwork(data, 'livenet'); + isValid = + this.currencyProvider + .getChain(this.coinReceiveSelected.code as Coin) + .toLowerCase() == addrData.coin && addrData.network == 'livenet'; + + if (isValid) { + return true; + } else { return false; } -} + } - public openSettingPage() { - this.router.navigate(['/setting']); - } + public openSettingPage() { + this.router.navigate(['/setting']); + } - public createOrder(){ - const orderOpts = { - fromCoinCode : this.coinSwapSelected.code, - amountFrom : this.convertAmountToSatoshiAmount(this.coinSwapSelected, (this.createForm.controls['swapAmount'].value as number)), - isFromToken: this.coinSwapSelected.isToken, - fromTokenId: this.coinSwapSelected.isToken ? this.coinSwapSelected.tokenInfo.id : null, - toCoinCode: this.coinReceiveSelected.code, - toTokenId: this.coinReceiveSelected.isToken? this.coinReceiveSelected.tokenInfo.id : null, - isToToken: this.coinReceiveSelected.isToken, - createdRate: this.coinSwapSelected.rate.USD / this.coinReceiveSelected.rate.USD, - addressUserReceive: this.createForm.controls['address'].value, - fromSatUnit: this.getSatUnitFromCoin(this.coinSwapSelected), - toSatUnit: this.getSatUnitFromCoin(this.coinReceiveSelected) - } as OrderOpts; - this.orderProvider.createOrder(orderOpts).then((result : IOrder) =>{ + public createOrder() { + const orderOpts = { + fromCoinCode: this.coinSwapSelected.code, + amountFrom: this.convertAmountToSatoshiAmount( + this.coinSwapSelected, + this.createForm.controls['swapAmount'].value as number + ), + isFromToken: this.coinSwapSelected.isToken, + fromTokenId: this.coinSwapSelected.isToken + ? this.coinSwapSelected.tokenInfo.id + : null, + toCoinCode: this.coinReceiveSelected.code, + toTokenId: this.coinReceiveSelected.isToken + ? this.coinReceiveSelected.tokenInfo.id + : null, + isToToken: this.coinReceiveSelected.isToken, + createdRate: + this.coinSwapSelected.rate.USD / this.coinReceiveSelected.rate.USD, + addressUserReceive: this.createForm.controls['address'].value, + // fromSatUnit: this.getSatUnitFromCoin(this.coinSwapSelected), + // toSatUnit: this.getSatUnitFromCoin(this.coinReceiveSelected), + toTokenInfo : this.coinReceiveSelected.tokenInfo || null, + fromTokenInfo : this.coinSwapSelected.tokenInfo || null, + } as OrderOpts; + this.orderProvider + .createOrder(orderOpts) + .then((result: IOrder) => { this.router.navigate(['/order'], { state: { order: result } }); - }).catch(err => { - console.log(err); }) - } - + .catch(err => { + console.log(err); + }); + } } diff --git a/src/app/pages/swap/order-swap/order-swap.component.html b/src/app/pages/swap/order-swap/order-swap.component.html index 9bda4ad31b8..cce00f450e5 100644 --- a/src/app/pages/swap/order-swap/order-swap.component.html +++ b/src/app/pages/swap/order-swap/order-swap.component.html @@ -10,8 +10,12 @@

Send exactly: {{ order.amountFrom / order.fromSatUnit}}

You receive: {{ order.amountFrom / order.fromSatUnit * ((order.updatedRate && order.updatedRate > 0) ? order.updatedRate : order.createdRate)}}

- -

TxId: {{order.txId}}

+ +

TxId User deposit: {{order.txIdUserDeposit}}

+ `
+ + +

TxId User receive: {{order.txIdUserReceive}}

`
diff --git a/src/app/pages/swap/order-swap/order-swap.component.ts b/src/app/pages/swap/order-swap/order-swap.component.ts index 5ec9496195f..3054c986a2c 100644 --- a/src/app/pages/swap/order-swap/order-swap.component.ts +++ b/src/app/pages/swap/order-swap/order-swap.component.ts @@ -22,7 +22,8 @@ interface IOrder { addressUserReceive: string; adddressUserDeposit: string; toTokenId?: string; - txId?: string; + txIdUserDeposit?: string; + txIdUserReceive?: string; status?: string; isSentToFund?: boolean; isSentToUser?: boolean; diff --git a/src/app/providers/order/order-provider.ts b/src/app/providers/order/order-provider.ts index 576f232d589..51d3ddc2c87 100644 --- a/src/app/providers/order/order-provider.ts +++ b/src/app/providers/order/order-provider.ts @@ -1,5 +1,6 @@ import { HttpClient } from "@angular/common/http"; import { Injectable } from "@angular/core"; +import { ConfigSwap } from "src/app/pages/swap/config-swap"; import { ConfigProvider } from "../config/config"; import { Logger } from "../logger/logger"; @@ -28,6 +29,14 @@ import { Logger } from "../logger/logger"; }); } + public getConfigSwap(): Promise { + return new Promise(resolve =>{ + this.http.get(`${this.bwsURL}/v3/configSwap/`).subscribe(res =>{ + resolve(ConfigSwap.fromObj(res)); + }); + }); + } + public getOrderInfo(orderId): Promise { return new Promise(resolve =>{ this.http.get(`${this.bwsURL}/v3/order/${orderId}`).subscribe(res =>{ From df294ad5c101c788a311269ae362387a2376d978 Mon Sep 17 00:00:00 2001 From: takYoon Date: Wed, 21 Sep 2022 06:51:30 +0700 Subject: [PATCH 19/28] add bignumber js handle case small number --- package.json | 1 + .../create-swap/create-swap.component.html | 2 +- .../swap/create-swap/create-swap.component.ts | 63 ++++++++++++++----- src/app/providers/order/order-provider.ts | 34 +++++++++- 4 files changed, 81 insertions(+), 19 deletions(-) diff --git a/package.json b/package.json index da1ccd5475b..d2a2e7bb3bf 100644 --- a/package.json +++ b/package.json @@ -92,6 +92,7 @@ "apexcharts": "^3.28.1", "apple-wallet-ng": "^1.1.1", "base64-js": "^1.5.1", + "bignumber.js": "^9.1.0", "bitauth": "git+https://github.com/bitpay/bitauth.git#68cf0353bf517a7e5293478608839fa904351eb6", "buffer-compare": "^1.1.1", "capacitor-resources": "^2.0.5", diff --git a/src/app/pages/swap/create-swap/create-swap.component.html b/src/app/pages/swap/create-swap/create-swap.component.html index 364c90d1353..964209eb5f3 100644 --- a/src/app/pages/swap/create-swap/create-swap.component.html +++ b/src/app/pages/swap/create-swap/create-swap.component.html @@ -80,7 +80,7 @@
- {{altValue | mask: 'separator.8':',' }} {{fiatCode}} + {{altValue.toNumber() | mask: 'separator.8':',' }} {{fiatCode}}
You need to deposit at least {{ minWithCurrentFiat | mask: 'separator.8':',' }} {{fiatCode}} You can not deposit above {{ maxWithCurrentFiat | mask: 'separator.8':',' }} {{fiatCode}} diff --git a/src/app/pages/swap/create-swap/create-swap.component.ts b/src/app/pages/swap/create-swap/create-swap.component.ts index f158b305e2d..26ea00a4627 100644 --- a/src/app/pages/swap/create-swap/create-swap.component.ts +++ b/src/app/pages/swap/create-swap/create-swap.component.ts @@ -22,8 +22,10 @@ import { Subject, Subscription } from 'rxjs'; import { debounceTime } from 'rxjs/operators'; import { AddressProvider, + BwcErrorProvider, Coin, CurrencyProvider, + ErrorsProvider, FilterProvider, IncomingDataProvider, RateProvider, @@ -33,6 +35,9 @@ import { OrderProvider } from 'src/app/providers/order/order-provider'; import { Config, ConfigProvider } from '../../../providers/config/config'; import { TokenInforPage } from '../../token-info/token-info'; import { CoinConfig, ConfigSwap } from '../config-swap'; +import BigNumber from "bignumber.js"; +import { TranslateService } from '@ngx-translate/core'; + interface TokenInfo { coin: string; blockCreated?: number; @@ -111,7 +116,7 @@ export class CreateSwapPage implements OnInit { public rates: any; public coinSwapSelected: CoinConfig; public coinReceiveSelected: CoinConfig; - public altValue = 0; + public altValue : BigNumber = new BigNumber(0); private modelChanged: Subject = new Subject(); private subscription: Subscription; public usdRate: any; @@ -231,7 +236,10 @@ export class CreateSwapPage implements OnInit { private addressProvider: AddressProvider, private form: FormBuilder, private _cdRef: ChangeDetectorRef, - private orderProvider: OrderProvider + private orderProvider: OrderProvider, + private errorsProvider: ErrorsProvider, + private translate: TranslateService, + private bwcErrorProvider: BwcErrorProvider ) { this.createForm = this.form.group({ swapAmount: [ @@ -370,19 +378,20 @@ export class CreateSwapPage implements OnInit { if (control.value === 0) { return { amountNotInput: true }; } + if (!!isSwap) { this.altValue = - control.value * - this.coinSwapSelected.rate[this.fiatCode]; + new BigNumber(control.value).multipliedBy(this.coinSwapSelected.rate[this.fiatCode]); } else { this.altValue = - control.value * - this.coinReceiveSelected.rate[this.fiatCode]; + new BigNumber(control.value).multipliedBy(this.coinReceiveSelected.rate[this.fiatCode]); } - if (this.altValue > 0) { + if (this.altValue.isGreaterThan(0)) { + // const result = new BigNumber(this.altValue).toString(); + // this.altValue = new BigNumber(this.altValue).toNumber(); this.minWithCurrentFiat = this.coinSwapSelected.min * this.usdRate[this.fiatCode]; - if (this.altValue < this.minWithCurrentFiat) { + if (this.altValue.toNumber() < this.minWithCurrentFiat) { return { amountMinValidator: true }; } else { return null; @@ -398,10 +407,10 @@ export class CreateSwapPage implements OnInit { if (control.value === 0) { return { amountNotInput: true }; } - if (this.altValue > 0) { + if (this.altValue.isGreaterThan(0)) { this.maxWithCurrentFiat = this.coinSwapSelected.max * this.usdRate[this.fiatCode]; - if (this.altValue > this.maxWithCurrentFiat) { + if (this.altValue.toNumber() > this.maxWithCurrentFiat) { return { amountMaxValidator: true }; } else { return null; @@ -609,8 +618,6 @@ export class CreateSwapPage implements OnInit { createdRate: this.coinSwapSelected.rate.USD / this.coinReceiveSelected.rate.USD, addressUserReceive: this.createForm.controls['address'].value, - // fromSatUnit: this.getSatUnitFromCoin(this.coinSwapSelected), - // toSatUnit: this.getSatUnitFromCoin(this.coinReceiveSelected), toTokenInfo : this.coinReceiveSelected.tokenInfo || null, fromTokenInfo : this.coinSwapSelected.tokenInfo || null, } as OrderOpts; @@ -622,9 +629,35 @@ export class CreateSwapPage implements OnInit { order: result } }); + }, err => { + this.showErrorInfoSheet(err); }) - .catch(err => { - console.log(err); - }); + } + + public showErrorInfoSheet( + error: Error | string, + title?: string, + exit?: boolean + ): void { + let msg: string; + if (!error) return; + // Currently the paypro error is the following string: 500 - "{}" + if (error.toString().includes('500 - "{}"')) { + msg = this.translate.instant( + 'Error 500 - There is a temporary problem, please try again later.' + ); + } + + const infoSheetTitle = title ? title : this.translate.instant('Error'); + + this.errorsProvider.showDefaultError( + msg || this.bwcErrorProvider.msg(error), + infoSheetTitle, + () => { + // if (exit) { + // this.location.back() + // } + } + ); } } diff --git a/src/app/providers/order/order-provider.ts b/src/app/providers/order/order-provider.ts index 51d3ddc2c87..9134f22e4af 100644 --- a/src/app/providers/order/order-provider.ts +++ b/src/app/providers/order/order-provider.ts @@ -1,5 +1,8 @@ -import { HttpClient } from "@angular/common/http"; +import { HttpClient, HttpErrorResponse, HttpResponse } from "@angular/common/http"; import { Injectable } from "@angular/core"; +import { reject } from "lodash"; +import { throwError } from "rxjs"; +import { catchError } from "rxjs/operators"; import { ConfigSwap } from "src/app/pages/swap/config-swap"; import { ConfigProvider } from "../config/config"; import { Logger } from "../logger/logger"; @@ -47,9 +50,34 @@ import { Logger } from "../logger/logger"; public createOrder(orderOpts): Promise { return new Promise(resolve =>{ - this.http.post(`${this.bwsURL}/v3/order/create/`, orderOpts).subscribe(res =>{ + try{ + this.http.post(`${this.bwsURL}/v3/order/create/`, orderOpts).pipe( + catchError(this.handleError) + ).subscribe( + (res: any) =>{ + if(res.status === 201 || res.status === 200) resolve(res); - }); + else reject(res); + + }, err => reject(err)); + }catch(e){ + reject(e); + } + }); } + + private handleError(error: HttpErrorResponse) { + if (error.status === 0) { + // A client-side or network error occurred. Handle it accordingly. + console.error('An error occurred:', error.error); + } else { + // The backend returned an unsuccessful response code. + // The response body may contain clues as to what went wrong. + console.error( + `Backend returned code ${error.status}, body was: `, error.error); + } + // Return an observable with a user-facing error message. + return throwError(() => new Error('Something bad happened; please try again later.')); + } } \ No newline at end of file From 17649e6b086c42eaaa9386abd144cc9b6564eda2 Mon Sep 17 00:00:00 2001 From: takYoon Date: Wed, 21 Sep 2022 22:27:27 +0700 Subject: [PATCH 20/28] update code for order swap --- .../create-swap/create-swap.component.html | 4 +- .../swap/create-swap/create-swap.component.ts | 41 ++++--- .../swap/order-swap/order-swap.component.html | 46 ++++++-- .../swap/order-swap/order-swap.component.ts | 106 ++++++++++++++++-- src/app/providers/feature-flags.service.ts | 4 +- src/app/providers/order/order-provider.ts | 23 +--- 6 files changed, 162 insertions(+), 62 deletions(-) diff --git a/src/app/pages/swap/create-swap/create-swap.component.html b/src/app/pages/swap/create-swap/create-swap.component.html index 964209eb5f3..dba3e839c61 100644 --- a/src/app/pages/swap/create-swap/create-swap.component.html +++ b/src/app/pages/swap/create-swap/create-swap.component.html @@ -28,7 +28,7 @@ {{'Swap' | translate}}
- + @@ -80,7 +80,7 @@
- {{altValue.toNumber() | mask: 'separator.8':',' }} {{fiatCode}} + {{ altValue.toFixed() | mask: 'separator.8':',' }} {{fiatCode}}
You need to deposit at least {{ minWithCurrentFiat | mask: 'separator.8':',' }} {{fiatCode}} You can not deposit above {{ maxWithCurrentFiat | mask: 'separator.8':',' }} {{fiatCode}} diff --git a/src/app/pages/swap/create-swap/create-swap.component.ts b/src/app/pages/swap/create-swap/create-swap.component.ts index 26ea00a4627..233eaf67373 100644 --- a/src/app/pages/swap/create-swap/create-swap.component.ts +++ b/src/app/pages/swap/create-swap/create-swap.component.ts @@ -91,8 +91,8 @@ interface IOrder { addressUserReceive: string; adddressUserDeposit: string; toTokenId?: string; - txIdUserDeposit?: string; - txIdUserReceive?: string; + listTxIdUserDeposit?: string[]; + listTxIdUserReceive?: string[]; status?: string; isSentToFund?: boolean; isSentToUser?: boolean; @@ -128,6 +128,7 @@ export class CreateSwapPage implements OnInit { public minWithCurrentFiat: any; public maxWithCurrentFiat: any; public createForm: FormGroup; + public searchValue = ''; debounceTime = 500; // public config: Config; @ViewChild('cd', { static: false }) private countdown: CountdownComponent; @@ -245,7 +246,7 @@ export class CreateSwapPage implements OnInit { swapAmount: [ 0, { - validators: [this.amountMinValidator(true), this.amountMaxValidator()], + validators: [this.amountMinValidator(true)], updateOn: 'change' } ], @@ -376,7 +377,7 @@ export class CreateSwapPage implements OnInit { amountMinValidator(isSwap: boolean): ValidatorFn { return (control: AbstractControl): ValidationErrors | null => { if (control.value === 0) { - return { amountNotInput: true }; + return null; } if (!!isSwap) { @@ -405,7 +406,7 @@ export class CreateSwapPage implements OnInit { amountMaxValidator(): ValidatorFn { return (control: AbstractControl): ValidationErrors | null => { if (control.value === 0) { - return { amountNotInput: true }; + return null; } if (this.altValue.isGreaterThan(0)) { this.maxWithCurrentFiat = @@ -484,19 +485,26 @@ export class CreateSwapPage implements OnInit { pattern.test(keyInput) ) { event.preventDefault(); - } else { - this.modelChanged.next(isSwap); } } else { if (!allowSpecialKeyCode.includes(keyCode) && pattern.test(keyInput)) { event.preventDefault(); - } else { - this.modelChanged.next(isSwap); } } this.modelChanged.next(isSwap); } + handleSearchInput(){ + if(this.searchValue.trim().length > 1){ + this.router.navigate(['/order'], { + replaceUrl: true, + state: { + orderId: this.searchValue + } + }); + } + } + formatAmountWithLimitDecimal(amount: number, maxDecimals): number { if (amount.toString().split('.').length > 1) { if (amount.toString().split('.')[1].length > maxDecimals) { @@ -625,27 +633,26 @@ export class CreateSwapPage implements OnInit { .createOrder(orderOpts) .then((result: IOrder) => { this.router.navigate(['/order'], { + replaceUrl: true, state: { - order: result + orderId: result.id } }); - }, err => { - this.showErrorInfoSheet(err); + }).catch(e => { + this.showErrorInfoSheet(e); }) } public showErrorInfoSheet( - error: Error | string, + error: any, title?: string, exit?: boolean ): void { let msg: string; if (!error) return; // Currently the paypro error is the following string: 500 - "{}" - if (error.toString().includes('500 - "{}"')) { - msg = this.translate.instant( - 'Error 500 - There is a temporary problem, please try again later.' - ); + if (error.status === 500) { + msg = error.error.error; } const infoSheetTitle = title ? title : this.translate.instant('Error'); diff --git a/src/app/pages/swap/order-swap/order-swap.component.html b/src/app/pages/swap/order-swap/order-swap.component.html index cce00f450e5..773ee757262 100644 --- a/src/app/pages/swap/order-swap/order-swap.component.html +++ b/src/app/pages/swap/order-swap/order-swap.component.html @@ -1,22 +1,48 @@ - +

status: {{ order.status}}

1 {{ order.fromCoinCode}} - {{ order.amountFrom / order.fromSatUnit * ((order.updatedRate && order.updatedRate > 0) ? order.updatedRate : order.createdRate) }} + {{ 1 * ( order.updatedRate || order.createdRate ) }} {{ order.toCoinCode }}

Deposit address : {{ order.adddressUserDeposit }}

-

Send exactly: {{ order.amountFrom / order.fromSatUnit}}

-

You receive: {{ order.amountFrom / order.fromSatUnit * ((order.updatedRate && order.updatedRate > 0) ? order.updatedRate : order.createdRate)}}

+ + +

Send exactly: {{ order.amountFrom / order.fromSatUnit}}

+

You receive: {{ order.amountFrom / order.fromSatUnit * ((order.updatedRate && order.updatedRate > 0) ? order.updatedRate : order.createdRate)}} {{ order.toCoinCode }}

+
+ + +

send between: {{ minSwapAmount }} {{ order.fromCoinCode }}

+

and: {{ maxSwapAmount }} {{ order.fromCoinCode }}

+
- -

TxId User deposit: {{order.txIdUserDeposit}}

- `
+ +

TxId User deposit:

+ + + {{ txId }} + + + +
+ + +

TxId User receive:

+ + + {{ txId }} + + + +
+ + +

Error: {{ order.error }}

+
- -

TxId User receive: {{order.txIdUserReceive}}

- `
+

Created on : {{ dateStr }}

diff --git a/src/app/pages/swap/order-swap/order-swap.component.ts b/src/app/pages/swap/order-swap/order-swap.component.ts index 3054c986a2c..26c85713f53 100644 --- a/src/app/pages/swap/order-swap/order-swap.component.ts +++ b/src/app/pages/swap/order-swap/order-swap.component.ts @@ -1,8 +1,13 @@ -import { Component, OnInit, ViewChild } from '@angular/core'; +import { ChangeDetectorRef, Component, OnInit, ViewChild } from '@angular/core'; import { Router } from '@angular/router'; import { NavParams } from '@ionic/angular'; import { CountdownComponent } from 'ngx-countdown'; -import { OrderProvider } from 'src/app/providers'; +import { BwcErrorProvider, ConfigProvider, ErrorsProvider, ExternalLinkProvider, OrderProvider } from 'src/app/providers'; +import { CoinConfig, TokenInfo } from '../config-swap'; +import { Location } from '@angular/common'; +import { TranslateService } from '@ngx-translate/core'; +import { runInThisContext } from 'vm'; + interface IOrder { id: string | number; version: number; @@ -10,8 +15,8 @@ interface IOrder { fromCoinCode: string; fromTokenId?: string; amountFrom: number; - fromSatUnit: number; - isFromToken: boolean; + fromSatUnit?: number; + isFromToken?: boolean; toCoinCode: string; isToToken: boolean; toSatUnit: number; @@ -22,14 +27,17 @@ interface IOrder { addressUserReceive: string; adddressUserDeposit: string; toTokenId?: string; - txIdUserDeposit?: string; - txIdUserReceive?: string; + listTxIdUserDeposit?: string[]; + listTxIdUserReceive?: string[]; status?: string; isSentToFund?: boolean; isSentToUser?: boolean; endedOn?: number; createdOn?: number; error?: string; + toTokenInfo? : TokenInfo; + fromTokenInfo?: TokenInfo; + coinConfig?: CoinConfig } @Component({ selector: 'app-order-swap', @@ -39,17 +47,38 @@ interface IOrder { export class OrderSwapPage implements OnInit { navPramss: any; order: IOrder = null; + orderId: string = ''; + coinSwap: CoinConfig = null; + coinReceive: CoinConfig = null; + minSwapAmount = 0; + maxSwapAmount = 0; + public dateStr = ''; + blockexplorerUrl = ''; @ViewChild('cd', { static: false }) private countdown: CountdownComponent; constructor( private router: Router, private navParams: NavParams, - private orderProvider: OrderProvider) { + private orderProvider: OrderProvider, + private location: Location, + private errorsProvider: ErrorsProvider, + private translate: TranslateService, + private _cdRef: ChangeDetectorRef, + private bwcErrorProvider: BwcErrorProvider, + private externalLinkProvider: ExternalLinkProvider, + private configProvider: ConfigProvider) { if (this.router.getCurrentNavigation()) { this.navPramss = this.router.getCurrentNavigation().extras.state; } else { this.navPramss = history ? history.state : {}; } - this.order = this.navPramss.order; - + if(this.navPramss.orderId){ + this.orderId = this.navPramss.orderId; + } + this.getOrderInfo(); + // else(this.navPramss.orderId) + // this.coinReceive = this.navPramss.coinReceive; + // // this.coinSwap = this.navPramss.coinSwap; + // this.maxSwapAmount = this.coinReceive.maxConvertToSat / this.order.toSatUnit; + // this.minSwapAmount = this.coinReceive.minConvertToSat / this.order.toSatUnit; } ngOnInit() { @@ -65,10 +94,67 @@ export class OrderSwapPage implements OnInit { } } + back() { + this.router.navigate['']; + } + getOrderInfo(){ - this.orderProvider.getOrderInfo(this.order.id).then((res: IOrder) => { + this.orderProvider.getOrderInfo(this.orderId).then((res: IOrder) => { this.order = res; + this.coinReceive = this.order.coinConfig; + this.maxSwapAmount = this.coinReceive.maxConvertToSat / this.order.toSatUnit / ( this.order.updatedRate || this.order.createdRate ); + this.minSwapAmount = this.coinReceive.minConvertToSat / this.order.toSatUnit / ( this.order.updatedRate || this.order.createdRate ); + this.dateStr = new Date(this.order.createdOn).toUTCString(); + this._cdRef.markForCheck(); + }).catch(e => { + }) } + public showErrorInfoSheet( + error: any, + title?: string, + exit?: boolean + ): void { + let msg: string; + if (!error) return; + // Currently the paypro error is the following string: 500 - "{}" + if (error.status === 500) { + msg = error.error.error; + } + + const infoSheetTitle = title ? title : this.translate.instant('Error'); + + this.errorsProvider.showDefaultError( + msg || this.bwcErrorProvider.msg(error), + infoSheetTitle, + () => { + // if (exit) { + // this.location.back() + // } + } + ); + } + + public viewOnBlockchain(coin, isToken, txId): void { + let defaults = this.configProvider.getDefaults(); + const coinSelected = isToken ? 'xec' : coin; + this.blockexplorerUrl = defaults.blockExplorerUrl[coinSelected]; + // let btx = this.btx; + // const coin = btx.coin; + const url = `https://${this.blockexplorerUrl}tx/${txId}`; + let optIn = true; + let title = null; + let message = this.translate.instant('View Transaction'); + let okText = this.translate.instant('Open'); + let cancelText = this.translate.instant('Go Back'); + this.externalLinkProvider.open( + url, + optIn, + title, + message, + okText, + cancelText + ); + } } diff --git a/src/app/providers/feature-flags.service.ts b/src/app/providers/feature-flags.service.ts index 92b55967074..85d797ea1fc 100644 --- a/src/app/providers/feature-flags.service.ts +++ b/src/app/providers/feature-flags.service.ts @@ -34,8 +34,8 @@ export interface FeatureConfig { // .pipe(tap(data => (this.config = data))) // .toPromise(); return of({ - abcpay: false, - swap: true + abcpay: true, + swap: false } as FeatureConfig).pipe(tap(data =>{ if(!data.abcpay && data.swap){ diff --git a/src/app/providers/order/order-provider.ts b/src/app/providers/order/order-provider.ts index 9134f22e4af..d75c22c68e1 100644 --- a/src/app/providers/order/order-provider.ts +++ b/src/app/providers/order/order-provider.ts @@ -41,30 +41,11 @@ import { Logger } from "../logger/logger"; } public getOrderInfo(orderId): Promise { - return new Promise(resolve =>{ - this.http.get(`${this.bwsURL}/v3/order/${orderId}`).subscribe(res =>{ - resolve(res); - }); - }); + return this.http.get(`${this.bwsURL}/v3/order/${orderId}`).toPromise(); } public createOrder(orderOpts): Promise { - return new Promise(resolve =>{ - try{ - this.http.post(`${this.bwsURL}/v3/order/create/`, orderOpts).pipe( - catchError(this.handleError) - ).subscribe( - (res: any) =>{ - if(res.status === 201 || res.status === 200) - resolve(res); - else reject(res); - - }, err => reject(err)); - }catch(e){ - reject(e); - } - - }); + return this.http.post(`${this.bwsURL}/v3/order/create/`, orderOpts).toPromise(); } private handleError(error: HttpErrorResponse) { From 500f56437cb9815d3c0900e312d95a2f800fca4b Mon Sep 17 00:00:00 2001 From: takYoon Date: Thu, 22 Sep 2022 11:16:01 +0700 Subject: [PATCH 21/28] integration abcpay with swap --- .env.example | 6 ++++-- scripts/setenv.ts | 4 +++- src/app/app-routing.module.ts | 20 +++++++++++++++++++ src/app/app.component.ts | 3 +++ src/app/pages/home/home.html | 3 +++ src/app/pages/home/home.ts | 4 ++++ src/app/pages/pages.ts | 2 ++ src/app/pages/settings/settings.html | 3 +-- src/app/pages/settings/settings.ts | 7 +++++-- .../create-swap/create-swap.component.html | 4 ++-- .../swap/create-swap/create-swap.component.ts | 3 +-- src/app/providers/feature-flags.service.ts | 17 +++++++++++----- 12 files changed, 60 insertions(+), 16 deletions(-) diff --git a/.env.example b/.env.example index 968d24ce834..609337e386c 100644 --- a/.env.example +++ b/.env.example @@ -1,5 +1,7 @@ -AWS_URL_CONFIG = https://domainname/bws/api +// AWS_URL_CONFIG = https://aws-dev.abcpay.cash/bws/api // ENABLE_ANIMATIONS change to false if env is desktop +AWS_URL_CONFIG = http://localhost:3232/bws/api ENABLE_ANIMATIONS = true ACTIVATE_SCANNER = true -LIXI_LOTUS_URL = https://domainname/api \ No newline at end of file +LIXI_LOTUS_URL = https://dev.lixilotus.com/api +BUILD_SWAP_STANDALONE = false \ No newline at end of file diff --git a/scripts/setenv.ts b/scripts/setenv.ts index 6c25ac3cb9d..d54205eec27 100644 --- a/scripts/setenv.ts +++ b/scripts/setenv.ts @@ -30,6 +30,7 @@ let awsUrl = ? awsUrlCLI : process.env.AWS_URL_CONFIG; let lixiLotusUrl = process.env.LIXI_LOTUS_URL; +let buildSwapAlone = process.env.BUILD_SWAP_STANDALONE; if (environment === 'production') { nameEnv = 'production'; } else if (environment === 'development') { @@ -49,7 +50,8 @@ export const env = { ratesAPI: new CurrencyProvider().getRatesApi(), activateScanner: ${activateScanner}, awsUrl: '${awsUrl}', - lixiLotusUrl: '${lixiLotusUrl}' + lixiLotusUrl: '${lixiLotusUrl}' , + buildSwapALone: ${buildSwapAlone} }; export default env;`; diff --git a/src/app/app-routing.module.ts b/src/app/app-routing.module.ts index 98dc0c9fe63..818aa3d053b 100644 --- a/src/app/app-routing.module.ts +++ b/src/app/app-routing.module.ts @@ -68,6 +68,8 @@ import { SearchContactPage } from './pages/search/search-contact/search-contact. import { SelectFlowPage } from './pages/onboarding/select-flow/select-flow'; import { ChartViewPage } from './pages/chart-view/chart-view'; import { FeatureGuard } from './providers/feature-gaurd.service'; +import { CreateSwapPage } from './pages/swap/create-swap/create-swap.component'; +import { OrderSwapPage } from './pages/swap/order-swap/order-swap.component'; const routes: Routes = [ { @@ -668,6 +670,24 @@ const routes: Routes = [ data: { feature: 'abcpay' } + }, + { + path: 'create-swap', + component: CreateSwapPage, + canActivate: [FeatureGuard], + + data: { + feature: 'swap' + } + }, + { + path: 'order-swap', + component: OrderSwapPage, + canActivate: [FeatureGuard], + + data: { + feature: 'swap' + } } ]; diff --git a/src/app/app.component.ts b/src/app/app.component.ts index 003e861ae2c..7a0961c6035 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -95,6 +95,9 @@ export class CopayApp { private featureFlagService: FeatureFlagsService ) { this.isSwap = this.featureFlagService.isFeatureEnabled('swap'); + if(this.featureFlagService.isFeatureEnabled('abcpay')){ + this.isSwap = false; + } this.imageLoaderConfig.setFileNameCachedWithExtension(true); this.imageLoaderConfig.useImageTag(true); this.imageLoaderConfig.enableSpinner(false); diff --git a/src/app/pages/home/home.html b/src/app/pages/home/home.html index 6c9ddb45e0e..f2d5de9edc0 100644 --- a/src/app/pages/home/home.html +++ b/src/app/pages/home/home.html @@ -18,6 +18,9 @@

{{ 'Home' | translate }}

+ + + diff --git a/src/app/pages/home/home.ts b/src/app/pages/home/home.ts index 329cdc619da..bfd42848271 100644 --- a/src/app/pages/home/home.ts +++ b/src/app/pages/home/home.ts @@ -566,6 +566,10 @@ export class HomePage { this.router.navigate(['/chart-view']); } + public openCreateSwapPage(): void { + this.router.navigate(['/create-swap']); + } + public addToHome(coin?: string, network?: string) { this.router.navigateByUrl('/accounts-page', { state: { diff --git a/src/app/pages/pages.ts b/src/app/pages/pages.ts index b9796fc23c0..6014368bc3c 100644 --- a/src/app/pages/pages.ts +++ b/src/app/pages/pages.ts @@ -157,6 +157,8 @@ export const PAGES = [ FingerprintModalPage, HomePage, ChartViewPage, + CreateSwapPage, + OrderSwapPage, // CardsPage, WalletsPage, AccountsPage, diff --git a/src/app/pages/settings/settings.html b/src/app/pages/settings/settings.html index ffb060b4990..26588198d34 100644 --- a/src/app/pages/settings/settings.html +++ b/src/app/pages/settings/settings.html @@ -76,8 +76,7 @@ - - + {{ 'Lock App' | translate }} diff --git a/src/app/pages/settings/settings.ts b/src/app/pages/settings/settings.ts index e1b4cd2dcee..e309845c502 100644 --- a/src/app/pages/settings/settings.ts +++ b/src/app/pages/settings/settings.ts @@ -27,7 +27,7 @@ import { EventManagerService } from 'src/app/providers/event-manager.service'; import { Router } from '@angular/router'; import { NewFeaturePage } from '../new-feature/new-feature'; import { ActionSheetProvider } from 'src/app/providers'; - +import { FeatureFlagsService } from '../../providers/feature-flags.service'; @Component({ selector: 'page-settings', templateUrl: 'settings.html', @@ -76,6 +76,7 @@ export class SettingsPage { public navigation: string; public featureList: any; public isScroll = false; + public isAbcpay = false; useLegacyQrCode; constructor( private app: AppProvider, @@ -95,12 +96,14 @@ export class SettingsPage { private themeProvider: ThemeProvider, private events: EventManagerService, private newFeatureData: NewFeatureData, - private router: Router + private router: Router, + private featureFlagsService: FeatureFlagsService ) { this.appName = this.app.info.nameCase; this.appVersion = this.app.info.version; this.isCordova = this.platformProvider.isCordova; this.isCopay = this.app.info.name === 'copay'; + this.isAbcpay = this.featureFlagsService.isFeatureEnabled('abcpay'); } async handleScrolling(event) { diff --git a/src/app/pages/swap/create-swap/create-swap.component.html b/src/app/pages/swap/create-swap/create-swap.component.html index dba3e839c61..0e096745a3d 100644 --- a/src/app/pages/swap/create-swap/create-swap.component.html +++ b/src/app/pages/swap/create-swap/create-swap.component.html @@ -59,7 +59,7 @@ - +
@@ -75,7 +75,7 @@ - +
diff --git a/src/app/pages/swap/create-swap/create-swap.component.ts b/src/app/pages/swap/create-swap/create-swap.component.ts index 233eaf67373..5a86b6e0366 100644 --- a/src/app/pages/swap/create-swap/create-swap.component.ts +++ b/src/app/pages/swap/create-swap/create-swap.component.ts @@ -491,7 +491,6 @@ export class CreateSwapPage implements OnInit { event.preventDefault(); } } - this.modelChanged.next(isSwap); } handleSearchInput(){ @@ -632,7 +631,7 @@ export class CreateSwapPage implements OnInit { this.orderProvider .createOrder(orderOpts) .then((result: IOrder) => { - this.router.navigate(['/order'], { + this.router.navigate(['/order-swap'], { replaceUrl: true, state: { orderId: result.id diff --git a/src/app/providers/feature-flags.service.ts b/src/app/providers/feature-flags.service.ts index 85d797ea1fc..e5024c784cd 100644 --- a/src/app/providers/feature-flags.service.ts +++ b/src/app/providers/feature-flags.service.ts @@ -8,7 +8,7 @@ import { Router } from '@angular/router'; import { CreateSwapPage } from "../pages/swap/create-swap/create-swap.component"; import { OrderSwapPage } from "../pages/swap/order-swap/order-swap.component"; import { SettingsPage } from "../pages/settings/settings"; - +import env from 'src/environments'; export interface FeatureConfig { abcpay: boolean, @@ -33,16 +33,23 @@ export interface FeatureConfig { // .get(this.configUrl) // .pipe(tap(data => (this.config = data))) // .toPromise(); + let buildSwapAlone = false; return of({ abcpay: true, - swap: false + swap: true } as FeatureConfig).pipe(tap(data =>{ - - if(!data.abcpay && data.swap){ + if(data.abcpay && data.swap){ + if(env.buildSwapALone){ + buildSwapAlone = true; + } + } + if(buildSwapAlone || !data.abcpay && data.swap){ const routes = this.Router.config; routes.shift(); routes.unshift({ path: '', component: CreateSwapPage }); - routes.push({ path: 'order', component: OrderSwapPage }); + const indexPath = routes.findIndex(r => r.path === 'create-swap'); + routes.splice(indexPath, 1); + routes.push({ path: 'order-swap', component: OrderSwapPage }); this.Router.resetConfig(routes); } // if(!data.abcpay && data.swap){ From 012cb9879d8dd3a84f582a2972f3cd750e4161b5 Mon Sep 17 00:00:00 2001 From: takYoon Date: Thu, 22 Sep 2022 14:36:06 +0700 Subject: [PATCH 22/28] update code for swap component --- .../pages/swap/create-swap/create-swap.component.ts | 2 +- .../pages/swap/order-swap/order-swap.component.html | 12 +++++++++--- .../pages/swap/order-swap/order-swap.component.ts | 6 ++++-- 3 files changed, 14 insertions(+), 6 deletions(-) diff --git a/src/app/pages/swap/create-swap/create-swap.component.ts b/src/app/pages/swap/create-swap/create-swap.component.ts index 5a86b6e0366..681cf11eafd 100644 --- a/src/app/pages/swap/create-swap/create-swap.component.ts +++ b/src/app/pages/swap/create-swap/create-swap.component.ts @@ -495,7 +495,7 @@ export class CreateSwapPage implements OnInit { handleSearchInput(){ if(this.searchValue.trim().length > 1){ - this.router.navigate(['/order'], { + this.router.navigate(['/order-swap'], { replaceUrl: true, state: { orderId: this.searchValue diff --git a/src/app/pages/swap/order-swap/order-swap.component.html b/src/app/pages/swap/order-swap/order-swap.component.html index 773ee757262..438fcf2d955 100644 --- a/src/app/pages/swap/order-swap/order-swap.component.html +++ b/src/app/pages/swap/order-swap/order-swap.component.html @@ -10,14 +10,18 @@

Send exactly: {{ order.amountFrom / order.fromSatUnit}}

-

You receive: {{ order.amountFrom / order.fromSatUnit * ((order.updatedRate && order.updatedRate > 0) ? order.updatedRate : order.createdRate)}} {{ order.toCoinCode }}

+

You receive: {{ order.amountFrom / order.fromSatUnit * ( order.updatedRate || order.createdRate )}} {{ order.toCoinCode }}

send between: {{ minSwapAmount }} {{ order.fromCoinCode }}

and: {{ maxSwapAmount }} {{ order.fromCoinCode }}

- + +

Created rate: {{ order.createdRate }}

+ +

Last rate used: {{ order.updatedRate }}

+

TxId User deposit:

@@ -42,7 +46,9 @@

Error: {{ order.error }}

-

Created on : {{ dateStr }}

+

Created on : {{ createdDateStr }}

+

Ended on : {{ endedDateStr }}

+ diff --git a/src/app/pages/swap/order-swap/order-swap.component.ts b/src/app/pages/swap/order-swap/order-swap.component.ts index 26c85713f53..ea334b903c6 100644 --- a/src/app/pages/swap/order-swap/order-swap.component.ts +++ b/src/app/pages/swap/order-swap/order-swap.component.ts @@ -52,7 +52,8 @@ export class OrderSwapPage implements OnInit { coinReceive: CoinConfig = null; minSwapAmount = 0; maxSwapAmount = 0; - public dateStr = ''; + public createdDateStr = ''; + public endedDateStr = ''; blockexplorerUrl = ''; @ViewChild('cd', { static: false }) private countdown: CountdownComponent; constructor( private router: Router, @@ -104,7 +105,8 @@ export class OrderSwapPage implements OnInit { this.coinReceive = this.order.coinConfig; this.maxSwapAmount = this.coinReceive.maxConvertToSat / this.order.toSatUnit / ( this.order.updatedRate || this.order.createdRate ); this.minSwapAmount = this.coinReceive.minConvertToSat / this.order.toSatUnit / ( this.order.updatedRate || this.order.createdRate ); - this.dateStr = new Date(this.order.createdOn).toUTCString(); + this.createdDateStr = new Date(this.order.createdOn).toUTCString(); + this.endedDateStr = new Date(this.order.endedOn).toUTCString(); this._cdRef.markForCheck(); }).catch(e => { From 3b6a9355a2a8bda7e8b5fe67b5a0f1886971c3e9 Mon Sep 17 00:00:00 2001 From: ericson Date: Thu, 22 Sep 2022 17:32:36 +0700 Subject: [PATCH 23/28] implement swap ui --- .../create-swap/create-swap.component.html | 254 ++++++++++++------ .../create-swap/create-swap.component.scss | 200 ++++++++++---- .../swap/create-swap/create-swap.component.ts | 7 + .../swap/order-swap/order-swap.component.html | 156 ++++++++--- .../swap/order-swap/order-swap.component.scss | 225 ++++++++++++++++ .../swap/order-swap/order-swap.component.ts | 42 ++- src/assets/img/countdown-ico.svg | 3 + src/theme/dark.scss | 118 ++++++++ 8 files changed, 830 insertions(+), 175 deletions(-) create mode 100644 src/assets/img/countdown-ico.svg diff --git a/src/app/pages/swap/create-swap/create-swap.component.html b/src/app/pages/swap/create-swap/create-swap.component.html index 0e096745a3d..97a73a60b7f 100644 --- a/src/app/pages/swap/create-swap/create-swap.component.html +++ b/src/app/pages/swap/create-swap/create-swap.component.html @@ -2,116 +2,210 @@
- - + +
- + - +
- - + +
- + -
- +
- {{'Swap' | translate}} + {{ 'Swap' | translate }}
- - - - - - - + + +
- 1  {{coinSwapSelected.code}} - - {{formatAmountWithLimitDecimal((coinSwapSelected.rate.USD /coinReceiveSelected.rate.USD),8)}}  {{coinReceiveSelected.code}} - + 1  + {{ coinSwapSelected.code.toUpperCase() }} + + {{ + formatAmountWithLimitDecimal( + coinSwapSelected.rate.USD / coinReceiveSelected.rate.USD, + 8 + ) + }}  {{ coinReceiveSelected.code.toUpperCase() }} +
+ + +
-
-
-
-
-
You send
-
- - - - {{coin.code}} - - - - - - - - +
+ +
+
+
You send
+
+ + + + {{ + coin.code + }} + + + + + + + +

+ {{ altValue.toFixed() | mask: 'separator.8':',' }} + {{ fiatCode }} +

+
+
+
+
You receive
+
+ + + + {{ + coin.code + }} + + + + + + + +

+ {{ altValue.toFixed() | mask: 'separator.8':',' }} + {{ fiatCode }} +

+
-
-
You receive
- - - - {{coin.code}} - - - - - - + You need to deposit at least + {{ minWithCurrentFiat | mask: 'separator.8':',' }} {{ fiatCode }} + + You can not deposit above + {{ maxWithCurrentFiat | mask: 'separator.8':',' }} {{ fiatCode }} + +
+ Network fee: + + {{ + coinReceiveSelected.networkFee + | satToUnit: getChain(coinReceiveSelected.code) + }} + + + {{ getFeeToken(coinReceiveSelected.networkFee) }} XEC + +
+ +
+

Your {{ coinReceiveSelected.code }} address

+ + + Wrong format addresss +
-
-
- {{ altValue.toFixed() | mask: 'separator.8':',' }} {{fiatCode}} -
- You need to deposit at least {{ minWithCurrentFiat | mask: 'separator.8':',' }} {{fiatCode}} - You can not deposit above {{ maxWithCurrentFiat | mask: 'separator.8':',' }} {{fiatCode}} -
- Network fee: - - {{ coinReceiveSelected.networkFee | satToUnit: getChain((coinReceiveSelected.code)) }} - - - {{ getFeeToken(coinReceiveSelected.networkFee) }} XEC - -
- - -
-

Your {{ coinReceiveSelected.code }} address

- - - - Wrong format addresss +
- -
- - - +
- {{ 'Swap' | translate }} + {{ 'Swap' | translate }}
diff --git a/src/app/pages/swap/create-swap/create-swap.component.scss b/src/app/pages/swap/create-swap/create-swap.component.scss index f75c6aea0cc..647498b9d7e 100644 --- a/src/app/pages/swap/create-swap/create-swap.component.scss +++ b/src/app/pages/swap/create-swap/create-swap.component.scss @@ -1,53 +1,155 @@ +page-create-swap { + .header-container { + display: flex; + flex-flow: row; + justify-content: space-between; + align-items: center; + .header-title { + font-weight: 400; + font-size: 32px; + color: #001e2e; + } + .search-container { + --background: linear-gradient( + 0deg, + rgba(0, 93, 141, 0.05), + rgba(0, 93, 141, 0.05) + ), + #fafafb; + background: linear-gradient( + 0deg, + rgba(0, 93, 141, 0.05), + rgba(0, 93, 141, 0.05) + ), + #fafafb; + --padding-top: 0; + --padding-end: 0; + --padding-bottom: 0; + --inner-padding-end: 0; + border: 1px solid rgba(28, 55, 69, 0.6); + border-radius: 4px; + padding: 0; + max-height: 40px; + display: flex; + .search-tx-modal { + --placeholder-color: #001e2e; + --color: #001e2e; + font-size: 14px; + letter-spacing: 0.5px; + } -page-create-swap{ - .header-container{ - display: flex; - flex-flow: row; - justify-content: space-between; - align-items: center; - .header-title{ - font-weight: 400; - font-size: 24px; - color: #001E2E; - } - .header-search-container{ - &::part(native) { - --background: transparent; - --border-color: 0.5px; - --border-color: rgba(112, 129, 138, 0.38); - --border-width: 3px; - --border-style: solid; - --border-radius: 4px; - --highlight-color-focused: rgba(112, 129, 138, 0.38); - --highlight-color-valid: rgba(112, 129, 138, 0.38); - --highlight-color-invalid: rgba(112, 129, 138, 0.38); - height: 49px; - font-size: 14px; - } - ion-input{ - --padding-top: 0; - --padding-bottom: 0; - color: rgba(112, 129, 138, 0.38); - } - } - } - .swap-exchange-rate-container{ + ion-icon { + margin: 0; + margin-right: 1rem; + width: 24px; + height: 24px; + color: rgba(28, 55, 69, 0.6); + } + } + } + .swap-exchange-rate-container { + font-size: 14px; + font-weight: 400; + display: flex; + align-items: center; + margin: 2rem 0; + .swap-ico { + margin: 0 8px; + } + .count-down-container { + margin-left: 8px; + display: flex; + align-items: center; + .count-down { + font-weight: 600; + font-size: 12px; + line-height: 16px; + text-align: center; + letter-spacing: 0.5px; + color: rgba(0, 30, 46, 0.6); + margin-left: 8px; + } + img { + position: absolute; + } + } + } + .swap-exchange-container { + background: #fafafb; + border-radius: 12px; + display: flex; + flex-direction: row; + align-items: flex-start; + border: 1px #d5e9f4 solid; + .hint { + margin: 0; + font-size: 12px; + letter-spacing: 0.4px; + color: rgba(0, 30, 46, 0.38); + } + ion-item { + margin: 1rem 0; + --background: #fafafb; + --padding-start: 0; + } + mat-form-field { + padding: 0; + .mat-form-field-infix { + padding: 10px 0 1rem 0 !important; + } + } + .title { + font-weight: 600; + font-size: 14px; + letter-spacing: 0.1px; + color: #001e2e; + } + } + .send-container { + flex: none; + order: 0; + flex-grow: 1; + padding: 1rem; + } + .receive-container { + flex: none; + order: 2; + flex-grow: 1; + border-left: 1px rgba(112, 129, 138, 0.38) solid; + padding: 1rem; + } + .network-fee-line { + text-align: right; + margin: 2rem 0; + .label-network { + color: rgba(28, 55, 69, 0.6); + font-size: 13px; + } + .amount-fee-network { + font-size: 13px; + } + } + .address-container { + padding: 1rem 1rem 2rem 1rem; + background: #fafafb; + border-radius: 12px; + border: 1px #d5e9f4 solid; + p { + color: #001e2e; + font-weight: 600; + letter-spacing: 0.1px; + margin: 0 0 10px 0; + } + mat-form-field { + padding: 0; + .mat-form-field-infix { + padding: 10px 0 1em 0; font-size: 14px; - font-weight: 400; - margin-top: 38px; - display: flex; - align-items: center; - img{ - margin: 0 8px; - } - .count-down{ - margin-left: 7px; - } - } - .swap-exchange-container{ - display: flex; - } - .right-part{ - margin-left: 20px; + } } + } + mat-error { + font-size: 12px; + padding-left: 1rem; + } } diff --git a/src/app/pages/swap/create-swap/create-swap.component.ts b/src/app/pages/swap/create-swap/create-swap.component.ts index 5a86b6e0366..d9df3a2d5f4 100644 --- a/src/app/pages/swap/create-swap/create-swap.component.ts +++ b/src/app/pages/swap/create-swap/create-swap.component.ts @@ -403,6 +403,13 @@ export class CreateSwapPage implements OnInit { }; } + getNameCoin(code) { + let nameCoin = ''; + const coin = this.currencyProvider.getCoin(code.toUpperCase()); + nameCoin = this.currencyProvider.getCoinName(coin) || ''; + return nameCoin; + } + amountMaxValidator(): ValidatorFn { return (control: AbstractControl): ValidationErrors | null => { if (control.value === 0) { diff --git a/src/app/pages/swap/order-swap/order-swap.component.html b/src/app/pages/swap/order-swap/order-swap.component.html index 773ee757262..5a52e6b5105 100644 --- a/src/app/pages/swap/order-swap/order-swap.component.html +++ b/src/app/pages/swap/order-swap/order-swap.component.html @@ -1,48 +1,120 @@
-

status: {{ order.status}}

-

- 1 {{ order.fromCoinCode}} - {{ 1 * ( order.updatedRate || order.createdRate ) }} {{ order.toCoinCode }} - -

-

Deposit address : {{ order.adddressUserDeposit }}

- - -

Send exactly: {{ order.amountFrom / order.fromSatUnit}}

-

You receive: {{ order.amountFrom / order.fromSatUnit * ((order.updatedRate && order.updatedRate > 0) ? order.updatedRate : order.createdRate)}} {{ order.toCoinCode }}

-
- - -

send between: {{ minSwapAmount }} {{ order.fromCoinCode }}

-

and: {{ maxSwapAmount }} {{ order.fromCoinCode }}

-
+
+ {{'Review the payment instructions carefully. Sending anything other than Bitcoin Cash to the specificed destination via the correct network can result in permanent loss of your finds.' | translate}} +
+ +
+

Order number: {{order.id.toString().slice(-10)}}

+

{{ getLabelStatus(order)}}

+
+
+ 1 {{ order.fromCoinCode.toUpperCase() }}   = +   {{ 1 * ( order.updatedRate || order.createdRate ) }} {{ order.toCoinCode.toUpperCase() }} +
+ + +
+
+
+ {{'The final rate will be determined upon receipt of your {Coin} payment.' | translate}} +
+
+ +
+ + +
+ +

Send exactly: {{ order.amountFrom / order.fromSatUnit}}

+

You receive: {{ order.amountFrom / order.fromSatUnit * ((order.updatedRate && order.updatedRate > 0) ? order.updatedRate : order.createdRate)}} {{ order.toCoinCode }}

+
+ +
+
+

Send between

+

{{ minSwapAmount }} {{ order.fromCoinCode.toUpperCase() }}

+
+
+

and

+

{{ maxSwapAmount }} {{ order.fromCoinCode.toUpperCase() }}

+
+
+ +
+ +
+ + {{'You can send more than ' + maxSwapAmount + ' ' + order.fromCoinCode.toUpperCase() }} + + + {{ ', however we will manually review the order which might cause a delay.' | translate }} + +
+
+ +
+ +
+
+

You'll send

+

{{ order.fromCoinCode.toUpperCase() }}

+
+
+

You'll receive

+

{{ order.toCoinCode.toUpperCase() }}

+

{{ order.addressUserReceive.slice(-10) }}

+
+
+
+
+ +
+ +
+ +

TxId user deposit:

+ + + {{ txId }} + + + +
+ + +

TxId ser receive:

+ + + {{ txId }} + + +
+ + +

Error: {{ order.error }}

+
+
+ +
+ + +
- -

TxId User deposit:

- - - {{ txId }} - - - -
- - -

TxId User receive:

- - - {{ txId }} - - - -
- - -

Error: {{ order.error }}

-
- -

Created on : {{ dateStr }}

diff --git a/src/app/pages/swap/order-swap/order-swap.component.scss b/src/app/pages/swap/order-swap/order-swap.component.scss index e69de29bb2d..7b979ffc958 100644 --- a/src/app/pages/swap/order-swap/order-swap.component.scss +++ b/src/app/pages/swap/order-swap/order-swap.component.scss @@ -0,0 +1,225 @@ +page-order-swap { + p { + margin: 0; + } + + .warning-order-swap { + background: #FFDDB6; + color: #2B1700; + font-size: 12px; + letter-spacing: 0.4px; + line-height: 16px; + padding: 12px 16px; + border-radius: 8px; + } + + .order-swap-container { + background: #FAFAFB; + border: 1px solid rgba(126, 208, 255, 0.16); + border-radius: 16px; + padding: 1rem; + margin-top: 1rem; + .oder-number { + text-align: center; + color: rgba(0, 30, 46, 0.6); + font-size: 12px; + letter-spacing: 0.4px; + } + .status-oder { + text-align: center; + color: #CC8000; + letter-spacing: 0.1px; + font-weight: 600; + line-height: 20px; + margin: 1rem 0; + } + .card-exchange-rate-oder { + padding: 8px 1rem; + border: 1px solid rgba(112, 129, 138, 0.16); + border-radius: 16px; + width: 56%; + margin: auto; + margin-bottom: 24px; + .count-down-card { + display: flex; + justify-content: center; + margin-bottom: 5px; + span { + color: #001E2E; + font-weight: 600; + font-size: 16px; + line-height: 24px; + letter-spacing: 0.1px; + } + .count-down-container { + margin-left: 8px; + display: flex; + align-items: center; + .count-down { + font-weight: 600; + font-size: 12px; + line-height: 16px; + text-align: center; + letter-spacing: 0.5px; + color: rgba(0, 30, 46, 0.6); + margin-left: 8px; + } + img { + position: absolute; + } + } + } + .sub-title { + font-size: 12px; + line-height: 16px; + text-align: center; + letter-spacing: 0.4px; + color: rgba(0, 30, 46, 0.6); + } + } + .info-card-account { + margin-top: 24px; + display: flex; + ngx-qrcode { + margin-right: 20px; + width: 90px; + height: 90px; + img { + border-radius: 8px; + } + } + .coin-name { + margin-top: 5px; + font-size: 12px; + line-height: 16px; + letter-spacing: 0.4px; + color: rgba(0, 30, 46, 0.6); + } + .address { + display: flex; + gap: 5px; + align-items: center; + margin: 5px 0; + .coin-address { + font-size: 16px; + line-height: 24px; + letter-spacing: 0.8px; + color: #001E2E; + } + ion-icon { + font-size: 23px; + color: #001E2E; + } + } + } + .card-amount-order { + .amount-container { + display: flex; + justify-content: space-between; + margin: 24px 0; + } + .start-amount { + flex: none; + order: 0; + flex-grow: 1; + .label-amount { + font-size: 12px; + line-height: 16px; + letter-spacing: 0.4px; + color: rgba(0, 30, 46, 0.6); + } + .amount { + font-weight: 600; + font-size: 16px; + line-height: 24px; + letter-spacing: 0.1px; + color: #001E2E; + } + } + .end-amount { + flex: none; + order: 2; + flex-grow: 1; + .label-amount { + font-size: 12px; + line-height: 16px; + letter-spacing: 0.4px; + color: rgba(0, 30, 46, 0.6); + } + .amount { + font-weight: 600; + font-size: 16px; + line-height: 24px; + letter-spacing: 0.1px; + color: #001E2E; + } + .address-received { + font-size: 12px; + line-height: 16px; + letter-spacing: 0.6px; + color: rgba(0, 30, 46, 0.6); + } + } + .notify-content { + display: flex; + padding: 8px; + border: 1px solid rgba(112, 129, 138, 0.16); + border-radius: 16px; + margin-bottom: 24px; + ion-icon { + font-size: 32px; + color: rgba(0, 30, 46, 0.38); + } + .warning-message { + margin-left: 10px; + span { + font-size: 12px; + line-height: 16px; + letter-spacing: 0.4px; + color: rgba(0, 30, 46, 0.6); + } + .title-message { + color: #CC8000; + } + } + } + } + } + + .list-user-deposit { + margin: 24px 0; + p { + margin-bottom: 8px; + font-size: 12px; + line-height: 16px; + letter-spacing: 0.4px; + color: rgba(0, 30, 46, 0.6); + } + .user-deposit { + margin-bottom: 8px; + } + } + + .footer-order-swap { + margin-top: 2rem; + text-align: center; + p { + font-size: 12px; + line-height: 16px; + letter-spacing: 0.4px; + color: rgba(0, 30, 46, 0.6); + } + span { + font-weight: 400; + font-size: 12px; + line-height: 16px; + letter-spacing: 0.4px; + color: #001E2E; + } + } + + .line-driver { + height: 1px; + background: rgba(112, 129, 138, 0.16); + } +} \ No newline at end of file diff --git a/src/app/pages/swap/order-swap/order-swap.component.ts b/src/app/pages/swap/order-swap/order-swap.component.ts index 26c85713f53..3a1da151516 100644 --- a/src/app/pages/swap/order-swap/order-swap.component.ts +++ b/src/app/pages/swap/order-swap/order-swap.component.ts @@ -1,8 +1,8 @@ -import { ChangeDetectorRef, Component, OnInit, ViewChild } from '@angular/core'; +import { ChangeDetectorRef, Component, OnInit, ViewChild, ViewEncapsulation } from '@angular/core'; import { Router } from '@angular/router'; import { NavParams } from '@ionic/angular'; import { CountdownComponent } from 'ngx-countdown'; -import { BwcErrorProvider, ConfigProvider, ErrorsProvider, ExternalLinkProvider, OrderProvider } from 'src/app/providers'; +import { BwcErrorProvider, Coin, ConfigProvider, CurrencyProvider, ErrorsProvider, ExternalLinkProvider, OrderProvider } from 'src/app/providers'; import { CoinConfig, TokenInfo } from '../config-swap'; import { Location } from '@angular/common'; import { TranslateService } from '@ngx-translate/core'; @@ -40,9 +40,10 @@ interface IOrder { coinConfig?: CoinConfig } @Component({ - selector: 'app-order-swap', + selector: 'page-order-swap', templateUrl: './order-swap.component.html', styleUrls: ['./order-swap.component.scss'], + encapsulation: ViewEncapsulation.None, }) export class OrderSwapPage implements OnInit { navPramss: any; @@ -64,7 +65,8 @@ export class OrderSwapPage implements OnInit { private _cdRef: ChangeDetectorRef, private bwcErrorProvider: BwcErrorProvider, private externalLinkProvider: ExternalLinkProvider, - private configProvider: ConfigProvider) { + private configProvider: ConfigProvider, + private currencyProvider: CurrencyProvider) { if (this.router.getCurrentNavigation()) { this.navPramss = this.router.getCurrentNavigation().extras.state; } else { @@ -87,6 +89,38 @@ export class OrderSwapPage implements OnInit { // ) } + getNameCoin(order: IOrder) { + let nameCoin = ''; + if (order && order.isToToken) { + nameCoin = order.toTokenInfo.name; + } else { + const coin = this.currencyProvider.getCoin(order.toCoinCode.toUpperCase()); + nameCoin = this.currencyProvider.getCoinName(coin) || ''; + } + return nameCoin; + } + + getLabelStatus(order: IOrder) { + if (order) { + let label = ''; + switch (order.status) { + case 'waiting': + label = `Waiting for ${order.toCoinCode.toUpperCase()} payment` + break; + case 'pending': + label = `Order is pending for review` + break; + case 'complete': + label = `Order completed` + break; + default: + break; + } + return label; + } + return ''; + } + handleEvent(event){ if(event.action === 'done'){ this.countdown.restart(); diff --git a/src/assets/img/countdown-ico.svg b/src/assets/img/countdown-ico.svg new file mode 100644 index 00000000000..b66360557b6 --- /dev/null +++ b/src/assets/img/countdown-ico.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/theme/dark.scss b/src/theme/dark.scss index e2af6e5db3e..62b122fc0bc 100644 --- a/src/theme/dark.scss +++ b/src/theme/dark.scss @@ -3724,4 +3724,122 @@ } } } + + page-create-swap { + .swap-exchange-container { + background: linear-gradient(0deg, rgba(126, 208, 255, 0.11), rgba(126, 208, 255, 0.11)), #001E2E; + border-color: #01293d; + .title { + color: var(--text-color-dark-theme); + } + ion-item { + --background: linear-gradient(0deg, rgba(126, 208, 255, 0.11), rgba(126, 208, 255, 0.11)), #001E2E; + } + .hint { + color: rgba(224, 228, 230, 0.6); + } + } + .swap-exchange-rate-container { + span { + color: var(--text-color-dark-theme); + } + countdown { + color: var(--text-color-dark-theme); + } + } + .address-container { + background: linear-gradient(0deg, rgba(126, 208, 255, 0.11), rgba(126, 208, 255, 0.11)), #001E2E; + border-color: #01293d; + } + .address-container { + p { + color: var(--text-color-dark-theme); + } + } + .search-container { + --background: linear-gradient(0deg, rgba(126, 208, 255, 0.11), rgba(126, 208, 255, 0.11)), #001E2E !important; + ion-icon { + color: rgba(237, 239, 240, 0.6) !important; + } + ion-input { + --color: var(--text-color-dark-theme) !important; + --placeholder-color: var(--text-color-dark-theme) !important; + } + } + .label-network { + color: rgba(224, 228, 230, 0.6) !important; + } + } + + page-order-swap { + .info-card-account { + .coin-name { + color: rgba(224, 228, 230, 0.6) !important; + } + .address { + .coin-address { + color: var(--text-color-dark-theme) !important; + } + ion-icon { + color: var(--text-color-dark-theme) !important; + } + } + } + .order-swap-container { + background: linear-gradient(0deg, rgba(126, 208, 255, 0.11), rgba(126, 208, 255, 0.11)), #001E2E !important; + border-color: rgba(0, 101, 141, 0.08) !important; + .oder-number { + color: rgba(224, 228, 230, 0.6) !important; + } + .status-oder { + color: #FFB85D !important; + } + .card-exchange-rate-oder { + .count-down-card { + span { + color: var(--text-color-dark-theme) !important; + } + countdown { + color: var(--text-color-dark-theme) !important; + } + } + .sub-title { + color: rgba(224, 228, 230, 0.6) !important; + } + } + } + .card-amount-order { + .label-amount { + color: rgba(224, 228, 230, 0.6) !important; + } + .amount { + color: var(--text-color-dark-theme) !important; + } + .address-received { + color: rgba(224, 228, 230, 0.6) !important; + } + } + .notify-content { + ion-icon { + color: rgba(224, 228, 230, 0.38) !important; + } + .title-message { + color: #FFB85D !important; + } + span { + color: rgba(224, 228, 230, 0.6) !important; + } + } + .line-driver { + background: rgba(112, 129, 138, 0.38) !important; + } + .footer-order-swap { + p { + color: rgba(224, 228, 230, 0.6) !important; + span { + color: var(--text-color-dark-theme) !important; + } + } + } + } } From 06ffd1eeebf96d07e3652e5461ff4726559c28da Mon Sep 17 00:00:00 2001 From: ericson Date: Mon, 26 Sep 2022 15:35:04 +0700 Subject: [PATCH 24/28] polish ui swap --- src/app/app.component.scss | 87 +++++++++++++++++- src/app/app.module.ts | 2 + .../create-swap/create-swap.component.html | 88 ++++++++++++------- .../create-swap/create-swap.component.scss | 21 ++++- .../swap/create-swap/create-swap.component.ts | 30 ++++++- .../swap/order-swap/order-swap.component.html | 24 ++--- .../swap/order-swap/order-swap.component.scss | 24 ++++- .../swap/order-swap/order-swap.component.ts | 10 ++- src/theme/dark.scss | 23 +++++ 9 files changed, 254 insertions(+), 55 deletions(-) diff --git a/src/app/app.component.scss b/src/app/app.component.scss index 0c66fb0a6c2..49cd2bec12e 100644 --- a/src/app/app.component.scss +++ b/src/app/app.component.scss @@ -132,7 +132,7 @@ body { wide-header-page { ion-content { - --padding-bottom: 7rem !important; + --padding-bottom: 7rem; } } @@ -2284,4 +2284,89 @@ ion-popover { } } } +} + +.mat-option { + height: fit-content !important; + background: #FAFAFB; + border: 1px solid rgba(0, 30, 46, 0.38); + border-top: 0; + border-left: 0; + border-right: 0; + .mat-option-text { + display: flex; + align-items: center; + height: fit-content; + padding: 1rem 0; + img { + width: 40px; + height: 40px; + margin-right: 8px; + } + .mat-coin-name { + margin: 0; + line-height: initial; + color: #001E2E; + font-weight: 600; + font-size: 16px; + } + .mat-symbol-name { + margin: 0; + line-height: initial; + color: rgba(0, 30, 46, 0.6); + letter-spacing: 0.4px; + font-size: 12px; + margin-top: 5px; + } + } + &:first-child { + .mat-option-text { + padding: 0; + font-size: 14px; + line-height: 32px; + font-weight: 500; + } + } + &.dark { + background: linear-gradient(0deg, rgba(126, 208, 255, 0.11), rgba(126, 208, 255, 0.11)), #001E2E !important; + border-color: #647a86; + .mat-option-text { + color: #EDEFF0 !important; + .mat-coin-name { + color: #EDEFF0 !important; + } + .mat-symbol-name { + color: rgba(237, 239, 240, 0.6) !important; + } + } + } +} + +mat-select-trigger { + display: flex !important; + img { + width: 40px; + height: 40px; + margin-right: 8px; + } + .mat-coin-name { + margin: 0; + line-height: initial; + color: #001E2E; + font-weight: 600; + font-size: 16px; + } + .mat-symbol-name { + margin: 0; + line-height: initial; + color: rgba(0, 30, 46, 0.6); + letter-spacing: 0.4px; + font-size: 12px; + margin-top: 5px; + } +} + +.mat-select-panel { + border: 1px solid #d5e9f4; + border-radius: 12px; } \ No newline at end of file diff --git a/src/app/app.module.ts b/src/app/app.module.ts index ff98ad8013c..02aa17f3a46 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -42,6 +42,7 @@ import { enterAnimation } from './animations/nav-animation'; import { MatGridListModule } from '@angular/material/grid-list'; import { MatFormFieldModule } from '@angular/material/form-field'; +import {MatSelectModule} from '@angular/material/select'; import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; import { MatInputModule } from '@angular/material/input'; import { MatIconModule } from '@angular/material/icon'; @@ -106,6 +107,7 @@ export class MyMissingTranslationHandler implements MissingTranslationHandler { NgxMaskModule.forRoot(), MatGridListModule, MatFormFieldModule, + MatSelectModule, BrowserAnimationsModule, MatIconModule, MatInputModule, diff --git a/src/app/pages/swap/create-swap/create-swap.component.html b/src/app/pages/swap/create-swap/create-swap.component.html index 97a73a60b7f..f99d2656088 100644 --- a/src/app/pages/swap/create-swap/create-swap.component.html +++ b/src/app/pages/swap/create-swap/create-swap.component.html @@ -1,24 +1,14 @@ - -
- - -
-
+ +
+ {{ 'Swap'| translate }} +
+
- - - - + +
@@ -44,7 +34,7 @@
{{ 'Swap' | translate }}
- +
-
+
You send
- - - - {{ - coin.code - }} - - - + + + + +
+

{{coinSwapSelected.code.toUpperCase()}}

+

{{getCoinName(coinSwapSelected)}}

+
+
+ + Select Coin + + + +
+

{{coin.code.toUpperCase()}}

+

{{getCoinName(coin)}}

+
+
+
+
You receive
- + + + + + +
+

{{coinReceiveSelected.code.toUpperCase()}}

+

{{getCoinName(coinReceiveSelected)}}

+
+
+ + Select Coin + + + +
+

{{coin.code.toUpperCase()}}

+

{{getCoinName(coin)}}

+
+
+
+
-

Your {{ coinReceiveSelected.code }} address

+

Your {{ getCoinName(coinReceiveSelected) }} address

{ this.router.navigate(['/order-swap'], { - replaceUrl: true, state: { orderId: result.id } diff --git a/src/app/pages/swap/order-swap/order-swap.component.html b/src/app/pages/swap/order-swap/order-swap.component.html index 0826518ccff..57deaf729e0 100644 --- a/src/app/pages/swap/order-swap/order-swap.component.html +++ b/src/app/pages/swap/order-swap/order-swap.component.html @@ -1,23 +1,23 @@ - -
+ +
{{'Review the payment instructions carefully. Sending anything other than Bitcoin Cash to the specificed destination via the correct network can result in permanent loss of your finds.' | translate}}

Order number: {{order.id.toString().slice(-10)}}

-

{{ getLabelStatus(order)}}

+

{{ getLabelStatus(order)}}

1 {{ order.fromCoinCode.toUpperCase() }}   = -   {{ 1 * ( order.updatedRate || order.createdRate ) }} {{ order.toCoinCode.toUpperCase() }} +   {{ (1 * ( order.updatedRate || order.createdRate )).toFixed(2) }} {{ order.toCoinCode.toUpperCase() }}
- {{'The final rate will be determined upon receipt of your {Coin} payment.' | translate}} + {{'The final rate will be determined upon receipt of your {coin} payment.' | translate: {coin: order.fromCoinCode.toUpperCase()} }}
@@ -44,11 +44,11 @@

Send between

-

{{ minSwapAmount }} {{ order.fromCoinCode.toUpperCase() }}

+

{{ minSwapAmount.toFixed(2) }} {{ order.fromCoinCode.toUpperCase() }}

and

-

{{ maxSwapAmount }} {{ order.fromCoinCode.toUpperCase() }}

+

{{ maxSwapAmount.toFixed(2) }} {{ order.fromCoinCode.toUpperCase() }}

@@ -56,7 +56,7 @@
- {{'You can send more than ' + maxSwapAmount + ' ' + order.fromCoinCode.toUpperCase() }} + {{'You can send more than ' + maxSwapAmount.toFixed(2) + ' ' + order.fromCoinCode.toUpperCase() }} {{ ', however we will manually review the order which might cause a delay.' | translate }} @@ -69,11 +69,11 @@

You'll send

-

{{ order.fromCoinCode.toUpperCase() }}

+

{{ order.amountFrom + ' ' + order.fromCoinCode.toUpperCase() }}

You'll receive

-

{{ order.toCoinCode.toUpperCase() }}

+

{{ order.amountFrom + ' ' + order.toCoinCode.toUpperCase() }}

{{ order.addressUserReceive.slice(-10) }}

@@ -110,8 +110,8 @@
diff --git a/src/app/pages/swap/order-swap/order-swap.component.scss b/src/app/pages/swap/order-swap/order-swap.component.scss index 7b979ffc958..7fff68a1fda 100644 --- a/src/app/pages/swap/order-swap/order-swap.component.scss +++ b/src/app/pages/swap/order-swap/order-swap.component.scss @@ -33,6 +33,9 @@ page-order-swap { line-height: 20px; margin: 1rem 0; } + .status-completed { + color: #006C44 + } .card-exchange-rate-oder { padding: 8px 1rem; border: 1px solid rgba(112, 129, 138, 0.16); @@ -57,12 +60,14 @@ page-order-swap { align-items: center; .count-down { font-weight: 600; - font-size: 12px; line-height: 16px; text-align: center; letter-spacing: 0.5px; color: rgba(0, 30, 46, 0.6); margin-left: 8px; + span { + font-size: 12px; + } } img { position: absolute; @@ -222,4 +227,21 @@ page-order-swap { height: 1px; background: rgba(112, 129, 138, 0.16); } + + .order-swap-content { + margin-bottom: 1rem; + } + + @media screen and (max-width: 390px) { + .order-swap-content { + padding: 0 1rem; + } + } + + wide-header-page { + ion-content { + --padding-bottom: 0 !important; + } + } + } \ No newline at end of file diff --git a/src/app/pages/swap/order-swap/order-swap.component.ts b/src/app/pages/swap/order-swap/order-swap.component.ts index 92c6a9db028..919af5e3ad0 100644 --- a/src/app/pages/swap/order-swap/order-swap.component.ts +++ b/src/app/pages/swap/order-swap/order-swap.component.ts @@ -101,6 +101,10 @@ export class OrderSwapPage implements OnInit { return nameCoin; } + back() { + this.router.navigate(['/'], { replaceUrl: true }); + } + getLabelStatus(order: IOrder) { if (order) { let label = ''; @@ -129,9 +133,9 @@ export class OrderSwapPage implements OnInit { } } - back() { - this.router.navigate['']; - } + // back() { + // this.router.navigate['']; + // } getOrderInfo(){ this.orderProvider.getOrderInfo(this.orderId).then((res: IOrder) => { diff --git a/src/theme/dark.scss b/src/theme/dark.scss index 62b122fc0bc..170c52bf7cf 100644 --- a/src/theme/dark.scss +++ b/src/theme/dark.scss @@ -394,6 +394,21 @@ } } + .mat-select { + .mat-select-arrow { + color: rgba(237, 239, 240, 0.6) !important; + } + } + + mat-select-trigger { + .mat-coin-name { + color: #EDEFF0 !important; + } + .mat-symbol-name { + color: rgba(237, 239, 240, 0.6) !important; + } +} + .swiper-pagination-bullet-active { background-color: var(--swiper-pagination-bullet-active-dark); } @@ -3758,6 +3773,8 @@ } .search-container { --background: linear-gradient(0deg, rgba(126, 208, 255, 0.11), rgba(126, 208, 255, 0.11)), #001E2E !important; + background: linear-gradient(0deg, rgba(126, 208, 255, 0.11), rgba(126, 208, 255, 0.11)), #001E2E !important; + border-color: rgba(112, 129, 138, 0.38) !important; ion-icon { color: rgba(237, 239, 240, 0.6) !important; } @@ -3769,6 +3786,9 @@ .label-network { color: rgba(224, 228, 230, 0.6) !important; } + .header-title { + color: var(--text-color-dark-theme) !important; + } } page-order-swap { @@ -3794,6 +3814,9 @@ .status-oder { color: #FFB85D !important; } + .status-completed { + color: #73DAA5 !important; + } .card-exchange-rate-oder { .count-down-card { span { From 3b25a7b75d6a1f0cf2e61eda1b990849c743f49d Mon Sep 17 00:00:00 2001 From: ericson Date: Mon, 26 Sep 2022 15:39:31 +0700 Subject: [PATCH 25/28] refactor code --- .../create-swap/create-swap.component.html | 4 ++-- .../swap/create-swap/create-swap.component.ts | 20 ------------------- 2 files changed, 2 insertions(+), 22 deletions(-) diff --git a/src/app/pages/swap/create-swap/create-swap.component.html b/src/app/pages/swap/create-swap/create-swap.component.html index f99d2656088..f55be77c77d 100644 --- a/src/app/pages/swap/create-swap/create-swap.component.html +++ b/src/app/pages/swap/create-swap/create-swap.component.html @@ -85,7 +85,7 @@
- Select Coin + Select coin send @@ -140,7 +140,7 @@
- Select Coin + Select coin receive diff --git a/src/app/pages/swap/create-swap/create-swap.component.ts b/src/app/pages/swap/create-swap/create-swap.component.ts index c1ea2bcaa35..549a12b9696 100644 --- a/src/app/pages/swap/create-swap/create-swap.component.ts +++ b/src/app/pages/swap/create-swap/create-swap.component.ts @@ -154,19 +154,6 @@ export class CreateSwapPage implements OnInit { 'LotusUri' ]; - categories = [ - {value: 'lav', viewValue: 'Laravel', image: 'assets/img/currencies/xpi.svg'}, - {value: 'ang', viewValue: 'Angular', image: 'assets/img/currencies/xec.svg'}, - {value: 'boo', viewValue: 'Bootstrap', image: 'assets/img/currencies/btc.svg'}, - {value: 'jsx', viewValue: 'JS', image: 'assets/img/currencies/bch.svg'}, - {value: 'git', viewValue: 'Git', image: 'assets/img/currencies/doge.svg'} - ]; - - listCoinSwap = []; - - selectedCoinSwap = null; - selectedCoinReceive = null; - // public listConfig = { // "coinSwap": [ // { @@ -285,11 +272,6 @@ export class CreateSwapPage implements OnInit { return this.currencyProvider.getChain(coin as Coin).toLowerCase(); } - public handleSelectOption(e) { - this.searchValue = e; - console.log('*********', e); - } - public convertAmountToSatoshiAmount(coinConfig, amount): number { if (coinConfig.isToken) { const decimals = coinConfig.tokenInfo.decimals; @@ -375,8 +357,6 @@ export class CreateSwapPage implements OnInit { this.handleInputChange(isSwap); }); }); - // this.selectedCoinSwap = this.listConfig.coinSwap[0]; - // this.selectedCoinReceive = this.listConfig.coinReceive[0]; } getCoinName(coin: CoinConfig) { From 7fd84412a766e4f74ac8944aafed46d076540bb6 Mon Sep 17 00:00:00 2001 From: takYoon Date: Tue, 27 Sep 2022 22:34:08 +0700 Subject: [PATCH 26/28] update code for swap --- .../create-swap/create-swap.component.html | 2 +- .../swap/create-swap/create-swap.component.ts | 94 +++---------------- .../swap/order-swap/order-swap.component.html | 32 ++++--- .../swap/order-swap/order-swap.component.ts | 67 ++++++++----- src/app/providers/feature-flags.service.ts | 10 -- 5 files changed, 78 insertions(+), 127 deletions(-) diff --git a/src/app/pages/swap/create-swap/create-swap.component.html b/src/app/pages/swap/create-swap/create-swap.component.html index f55be77c77d..b38636dcff3 100644 --- a/src/app/pages/swap/create-swap/create-swap.component.html +++ b/src/app/pages/swap/create-swap/create-swap.component.html @@ -62,7 +62,7 @@
diff --git a/src/app/pages/swap/create-swap/create-swap.component.ts b/src/app/pages/swap/create-swap/create-swap.component.ts index 549a12b9696..0c042a7f10a 100644 --- a/src/app/pages/swap/create-swap/create-swap.component.ts +++ b/src/app/pages/swap/create-swap/create-swap.component.ts @@ -154,77 +154,6 @@ export class CreateSwapPage implements OnInit { 'LotusUri' ]; - // public listConfig = { - // "coinSwap": [ - // { - // "code": "xpi", - // "isToken": false, - // "networkFee": 226, - // "rate": {}, - // "min": 0, // USD - // "tokenInfo": {} - // }, - // { - // "code": "xec", - // "isToken": false, - // "networkFee": 226, - // "rate": {}, - // "min": 0, // USD - // "tokenInfo": {} - // }, - // { - // "code": "bch", - // "isToken": false, - // "networkFee": 226, - // "rate": {}, - // "min": 0, // USD - // "tokenInfo": {} - // }, - // { - // "code": "abcslp", - // "isToken": true, - // "networkFee": 1342, - // "rate": {}, - // "min": 0, // USD - // "tokenInfo": {} - // } - // ], - // "coinReceive": [ - // { - // "code": "abcslp", - // "isToken": true, - // "networkFee": 1342, - // "rate": {}, - // "min": 0, // USD - // "tokenInfo": {} - // }, - // { - // "code": "EAT", - // "isToken": true, - // "networkFee": 1342, - // "rate": {}, - // "min": 0, // USD - // "tokenInfo": {} - // }, - // { - // "code": "bcPro", - // "isToken": true, - // "networkFee": 1342, - // "rate": {}, - // "min": 0, // USD - // "tokenInfo": {} - // }, - // { - // "code": "xpi", - // "isToken": false, - // "networkFee": 226, - // "rate": {}, - // "min": 0, // USD - // "tokenInfo": {} - // } - // ] - // } - public listConfig: ConfigSwap = null; constructor( @@ -246,7 +175,7 @@ export class CreateSwapPage implements OnInit { swapAmount: [ 0, { - validators: [this.amountMinValidator(true)], + validators: [this.amountMinValidator(true), this.amountMaxValidator()], updateOn: 'change' } ], @@ -254,7 +183,7 @@ export class CreateSwapPage implements OnInit { receiveAmount: [ 0, { - validators: [this.amountMinValidator(false)], + validators: [this.amountMinValidator(false), this.amountMaxValidator()], updateOn: 'change' } ], @@ -426,7 +355,7 @@ export class CreateSwapPage implements OnInit { } if (this.altValue.isGreaterThan(0)) { this.maxWithCurrentFiat = - this.coinSwapSelected.max * this.usdRate[this.fiatCode]; + this.coinReceiveSelected.max * this.usdRate[this.fiatCode]; if (this.altValue.toNumber() > this.maxWithCurrentFiat) { return { amountMaxValidator: true }; } else { @@ -510,13 +439,18 @@ export class CreateSwapPage implements OnInit { } handleSearchInput(){ + if(this.searchValue.trim().length > 1){ - this.router.navigate(['/order-swap'], { - replaceUrl: true, - state: { - orderId: this.searchValue - } - }); + this.orderProvider.getOrderInfo(this.searchValue).then((res: IOrder) => { + this.router.navigate(['/order-swap'], { + replaceUrl: true, + state: { + order: res + } + }); + }).catch(e => { + this.showErrorInfoSheet(e); + }) } } diff --git a/src/app/pages/swap/order-swap/order-swap.component.html b/src/app/pages/swap/order-swap/order-swap.component.html index 57deaf729e0..69638ac42db 100644 --- a/src/app/pages/swap/order-swap/order-swap.component.html +++ b/src/app/pages/swap/order-swap/order-swap.component.html @@ -6,13 +6,13 @@

Order number: {{order.id.toString().slice(-10)}}

-

{{ getLabelStatus(order)}}

+

{{ labelStatusString }}

1 {{ order.fromCoinCode.toUpperCase() }}   =   {{ (1 * ( order.updatedRate || order.createdRate )).toFixed(2) }} {{ order.toCoinCode.toUpperCase() }}
- +
@@ -36,11 +36,11 @@
- -

Send exactly: {{ order.amountFrom / order.fromSatUnit}}

-

You receive: {{ order.amountFrom / order.fromSatUnit * ((order.updatedRate && order.updatedRate > 0) ? order.updatedRate : order.createdRate)}} {{ order.toCoinCode }}

-
- + +

Send exactly: {{ order.amountFrom / order.fromSatUnit }} {{ order.fromCoinCode.toUpperCase() }}

+

You receive: {{ order.amountFrom / order.fromSatUnit * ((order.updatedRate && order.updatedRate > 0) ? order.updatedRate : order.createdRate)}} {{ order.toCoinCode.toUpperCase() }}

+ +

Send between

@@ -69,15 +69,15 @@

You'll send

-

{{ order.amountFrom + ' ' + order.fromCoinCode.toUpperCase() }}

+

{{ order.amountFrom / order.fromSatUnit + ' ' + order.fromCoinCode.toUpperCase() }}

You'll receive

-

{{ order.amountFrom + ' ' + order.toCoinCode.toUpperCase() }}

+

{{ ( order.amountFrom / order.fromSatUnit * (order.updatedRate || order.createdRate) ) + ' ' + order.toCoinCode.toUpperCase() }}

{{ order.addressUserReceive.slice(-10) }}

- +
@@ -94,7 +94,7 @@ -

TxId ser receive:

+

TxId user receive:

{{ txId }} @@ -102,9 +102,13 @@
- -

Error: {{ order.error }}

-
+

{{ errorStr }}

+
diff --git a/src/app/pages/swap/order-swap/order-swap.component.ts b/src/app/pages/swap/order-swap/order-swap.component.ts index 919af5e3ad0..0a753df8daf 100644 --- a/src/app/pages/swap/order-swap/order-swap.component.ts +++ b/src/app/pages/swap/order-swap/order-swap.component.ts @@ -15,8 +15,8 @@ interface IOrder { fromCoinCode: string; fromTokenId?: string; amountFrom: number; - fromSatUnit?: number; - isFromToken?: boolean; + fromSatUnit: number; + isFromToken: boolean; toCoinCode: string; isToToken: boolean; toSatUnit: number; @@ -35,10 +35,15 @@ interface IOrder { endedOn?: number; createdOn?: number; error?: string; - toTokenInfo? : TokenInfo; + coinConfig?: CoinConfig; + toTokenInfo?: TokenInfo; fromTokenInfo?: TokenInfo; - coinConfig?: CoinConfig + note?: string; + pendingReason?: string; + lastModified?: number; + isResolve?: boolean; } + @Component({ selector: 'page-order-swap', templateUrl: './order-swap.component.html', @@ -53,9 +58,11 @@ export class OrderSwapPage implements OnInit { coinReceive: CoinConfig = null; minSwapAmount = 0; maxSwapAmount = 0; + errorStr = ''; public createdDateStr = ''; public endedDateStr = ''; blockexplorerUrl = ''; + labelStatusString = ''; @ViewChild('cd', { static: false }) private countdown: CountdownComponent; constructor( private router: Router, private navParams: NavParams, @@ -73,10 +80,10 @@ export class OrderSwapPage implements OnInit { } else { this.navPramss = history ? history.state : {}; } - if(this.navPramss.orderId){ - this.orderId = this.navPramss.orderId; + if(this.navPramss.order){ + this.order = this.navPramss.order; } - this.getOrderInfo(); + // this.getOrderInfo(); // else(this.navPramss.orderId) // this.coinReceive = this.navPramss.coinReceive; // // this.coinSwap = this.navPramss.coinSwap; @@ -92,10 +99,10 @@ export class OrderSwapPage implements OnInit { getNameCoin(order: IOrder) { let nameCoin = ''; - if (order && order.isToToken) { - nameCoin = order.toTokenInfo.name; + if (order && order.isFromToken) { + nameCoin = order.fromTokenInfo.name; } else { - const coin = this.currencyProvider.getCoin(order.toCoinCode.toUpperCase()); + const coin = this.currencyProvider.getCoin(order.fromCoinCode.toUpperCase()); nameCoin = this.currencyProvider.getCoinName(coin) || ''; } return nameCoin; @@ -110,20 +117,25 @@ export class OrderSwapPage implements OnInit { let label = ''; switch (order.status) { case 'waiting': - label = `Waiting for ${order.toCoinCode.toUpperCase()} payment` + label = `Waiting for ${order.toCoinCode.toUpperCase()} payment`; break; case 'pending': - label = `Order is pending for review` + label = `Order is pending for review`; break; + case 'expired': + label = `Order is expired`; + break; case 'complete': - label = `Order completed` + label = `Order completed`; break; default: break; } - return label; + this.labelStatusString = label; + this._cdRef.markForCheck(); + } else{ + this.labelStatusString = ''; } - return ''; } handleEvent(event){ @@ -133,21 +145,19 @@ export class OrderSwapPage implements OnInit { } } - // back() { - // this.router.navigate['']; - // } - getOrderInfo(){ - this.orderProvider.getOrderInfo(this.orderId).then((res: IOrder) => { + this.orderProvider.getOrderInfo(this.order.id).then((res: IOrder) => { this.order = res; this.coinReceive = this.order.coinConfig; this.maxSwapAmount = this.coinReceive.maxConvertToSat / this.order.toSatUnit / ( this.order.updatedRate || this.order.createdRate ); this.minSwapAmount = this.coinReceive.minConvertToSat / this.order.toSatUnit / ( this.order.updatedRate || this.order.createdRate ); this.createdDateStr = new Date(this.order.createdOn).toUTCString(); this.endedDateStr = new Date(this.order.endedOn).toUTCString(); + this.getLabelStatus(this.order); + this.getErrorStr(this.order); this._cdRef.markForCheck(); }).catch(e => { - + this.showErrorInfoSheet(e); }) } @@ -175,7 +185,20 @@ export class OrderSwapPage implements OnInit { } ); } - + public getErrorStr(order: IOrder){ + if(order){ + if(order.status !== 'complete' && order.error && order.error.length > 0){ + if(order.pendingReason === 'OUT_OF_FUND'){ + this.errorStr = 'This order need to be reviewed by admin'; + } else{ + this.errorStr = "Error: " + order.error; + } + } + else{ + this.errorStr = ''; + } + } + } public viewOnBlockchain(coin, isToken, txId): void { let defaults = this.configProvider.getDefaults(); const coinSelected = isToken ? 'xec' : coin; diff --git a/src/app/providers/feature-flags.service.ts b/src/app/providers/feature-flags.service.ts index e5024c784cd..b42490d214c 100644 --- a/src/app/providers/feature-flags.service.ts +++ b/src/app/providers/feature-flags.service.ts @@ -29,10 +29,6 @@ export interface FeatureConfig { * be called by the APP_INITIALIZER */ loadConfig() : Promise { - // return this.http - // .get(this.configUrl) - // .pipe(tap(data => (this.config = data))) - // .toPromise(); let buildSwapAlone = false; return of({ abcpay: true, @@ -52,12 +48,6 @@ export interface FeatureConfig { routes.push({ path: 'order-swap', component: OrderSwapPage }); this.Router.resetConfig(routes); } - // if(!data.abcpay && data.swap){ - // const routes = this.Router.config; - // routes.shift(); - // routes.unshift({ path: '', component: SwapPage }); - // this.Router.resetConfig(routes); - // } this.config = data; } )) .toPromise();; From 11414aeb0dda76427e1cd0dfad4f7a8308eb0851 Mon Sep 17 00:00:00 2001 From: takYoon Date: Tue, 27 Sep 2022 22:39:23 +0700 Subject: [PATCH 27/28] fix bug create order --- src/app/pages/swap/order-swap/order-swap.component.ts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/app/pages/swap/order-swap/order-swap.component.ts b/src/app/pages/swap/order-swap/order-swap.component.ts index 0a753df8daf..90da1c151b4 100644 --- a/src/app/pages/swap/order-swap/order-swap.component.ts +++ b/src/app/pages/swap/order-swap/order-swap.component.ts @@ -82,8 +82,12 @@ export class OrderSwapPage implements OnInit { } if(this.navPramss.order){ this.order = this.navPramss.order; + this.orderId = this.order.id as string; + } + if(this.navPramss.orderId){ + this.orderId = this.navPramss.orderId; + this.getOrderInfo(); } - // this.getOrderInfo(); // else(this.navPramss.orderId) // this.coinReceive = this.navPramss.coinReceive; // // this.coinSwap = this.navPramss.coinSwap; @@ -146,7 +150,7 @@ export class OrderSwapPage implements OnInit { } getOrderInfo(){ - this.orderProvider.getOrderInfo(this.order.id).then((res: IOrder) => { + this.orderProvider.getOrderInfo(this.orderId).then((res: IOrder) => { this.order = res; this.coinReceive = this.order.coinConfig; this.maxSwapAmount = this.coinReceive.maxConvertToSat / this.order.toSatUnit / ( this.order.updatedRate || this.order.createdRate ); From 415fa4a7288df5227641b0f484b92a5456f04865 Mon Sep 17 00:00:00 2001 From: takYoon Date: Thu, 29 Sep 2022 15:58:38 +0700 Subject: [PATCH 28/28] add new code to handle network ( livenet, testnet ) --- src/app/pages/swap/config-swap.ts | 5 +- .../create-swap/create-swap.component.html | 129 ++++------------ .../swap/create-swap/create-swap.component.ts | 25 ++- .../swap/order-swap/order-swap.component.html | 146 +++++++++--------- .../swap/order-swap/order-swap.component.ts | 22 +-- 5 files changed, 129 insertions(+), 198 deletions(-) diff --git a/src/app/pages/swap/config-swap.ts b/src/app/pages/swap/config-swap.ts index 890e0a28c2d..a898257acae 100644 --- a/src/app/pages/swap/config-swap.ts +++ b/src/app/pages/swap/config-swap.ts @@ -54,6 +54,7 @@ export class CoinConfig{ maxConvertToSat?: number; tokenInfo?: TokenInfo; isEnable?: boolean; + network: string; static create(opts){ const x = new CoinConfig(); @@ -67,7 +68,7 @@ export class CoinConfig{ x.maxConvertToSat = opts.maxConvertToSat || 0; x.tokenInfo = opts.tokenInfo || null; x.isEnable = opts.isEnable || true; - + x.network = opts.network; return x; } @@ -83,7 +84,7 @@ export class CoinConfig{ x.maxConvertToSat = opts.maxConvertToSat; x.tokenInfo = opts.tokenInfo; x.isEnable = opts.isEnable; - + x.network = opts.network; return x; } } diff --git a/src/app/pages/swap/create-swap/create-swap.component.html b/src/app/pages/swap/create-swap/create-swap.component.html index b38636dcff3..6825a009586 100644 --- a/src/app/pages/swap/create-swap/create-swap.component.html +++ b/src/app/pages/swap/create-swap/create-swap.component.html @@ -13,20 +13,10 @@ - +
- +
@@ -34,37 +24,25 @@
{{ 'Swap' | translate }}
- + - +
1  {{ coinSwapSelected.code.toUpperCase() }} - + {{ formatAmountWithLimitDecimal( coinSwapSelected.rate.USD / coinReceiveSelected.rate.USD, 8 ) - }}  {{ coinReceiveSelected.code.toUpperCase() }} + }}  {{ coinReceiveSelected.code.toUpperCase() }}
- +
@@ -78,7 +56,8 @@ - +

{{coinSwapSelected.code.toUpperCase()}}

{{getCoinName(coinSwapSelected)}}

@@ -87,8 +66,9 @@ Select coin send - - + +

{{coin.code.toUpperCase()}}

{{getCoinName(coin)}}

@@ -98,16 +78,8 @@ - +

{{ altValue.toFixed() | mask: 'separator.8':',' }} @@ -118,22 +90,11 @@

You receive
- - +

{{coinReceiveSelected.code.toUpperCase()}}

{{getCoinName(coinReceiveSelected)}}

@@ -142,8 +103,9 @@ Select coin receive - - + +

{{coin.code.toUpperCase()}}

{{getCoinName(coin)}}

@@ -153,16 +115,9 @@ - +

{{ altValue.toFixed() | mask: 'separator.8':',' }} @@ -171,16 +126,12 @@

- You need to deposit at least + You need to deposit at + least {{ minWithCurrentFiat | mask: 'separator.8':',' }} {{ fiatCode }} - You can not deposit above + You can not deposit + above {{ maxWithCurrentFiat | mask: 'separator.8':',' }} {{ fiatCode }}
@@ -199,18 +150,10 @@

Your {{ getCoinName(coinReceiveSelected) }} address

- + - Wrong format addresss + + Wrong format addresss
@@ -220,13 +163,9 @@
- {{ 'Swap' | translate }} + + {{ 'Swap' | translate }}
- + \ No newline at end of file diff --git a/src/app/pages/swap/create-swap/create-swap.component.ts b/src/app/pages/swap/create-swap/create-swap.component.ts index 0c042a7f10a..68ddd1dde70 100644 --- a/src/app/pages/swap/create-swap/create-swap.component.ts +++ b/src/app/pages/swap/create-swap/create-swap.component.ts @@ -10,7 +10,6 @@ import { import { AbstractControl, FormBuilder, - FormControl, FormGroup, ValidationErrors, ValidatorFn @@ -26,14 +25,12 @@ import { Coin, CurrencyProvider, ErrorsProvider, - FilterProvider, IncomingDataProvider, RateProvider, ThemeProvider } from 'src/app/providers'; import { OrderProvider } from 'src/app/providers/order/order-provider'; import { Config, ConfigProvider } from '../../../providers/config/config'; -import { TokenInforPage } from '../../token-info/token-info'; import { CoinConfig, ConfigSwap } from '../config-swap'; import BigNumber from "bignumber.js"; import { TranslateService } from '@ngx-translate/core'; @@ -71,6 +68,8 @@ interface OrderOpts { toSatUnit?: number; toTokenInfo? : TokenInfo; fromTokenInfo?: TokenInfo; + fromNetwork: string; + toNetwork: string; } interface IOrder { id: string | number; @@ -101,6 +100,8 @@ interface IOrder { error?: string; toTokenInfo? : TokenInfo; fromTokenInfo?: TokenInfo; + fromNetwork: string; + toNetwork: string; } @Component({ @@ -130,7 +131,6 @@ export class CreateSwapPage implements OnInit { public createForm: FormGroup; public searchValue = ''; debounceTime = 500; - // public config: Config; @ViewChild('cd', { static: false }) private countdown: CountdownComponent; @ViewChild('inputSwap') inputSwap: ElementRef; @ViewChild('inputReceive') inputReceive: ElementRef; @@ -179,7 +179,6 @@ export class CreateSwapPage implements OnInit { updateOn: 'change' } ], - // swapAmount: [null], receiveAmount: [ 0, { @@ -326,8 +325,6 @@ export class CreateSwapPage implements OnInit { new BigNumber(control.value).multipliedBy(this.coinReceiveSelected.rate[this.fiatCode]); } if (this.altValue.isGreaterThan(0)) { - // const result = new BigNumber(this.altValue).toString(); - // this.altValue = new BigNumber(this.altValue).toNumber(); this.minWithCurrentFiat = this.coinSwapSelected.min * this.usdRate[this.fiatCode]; if (this.altValue.toNumber() < this.minWithCurrentFiat) { @@ -399,7 +396,7 @@ export class CreateSwapPage implements OnInit { parsedData && _.indexOf(this.validDataTypeMap, parsedData.type) != -1 ) { - this.validAddress = this.checkCoinAndNetwork(addressInputValue); + this.validAddress = this.checkCoinAndNetwork(addressInputValue, this.coinReceiveSelected.network); if (this.validAddress) { return null; } else { @@ -536,14 +533,14 @@ export class CreateSwapPage implements OnInit { this._cdRef.markForCheck(); } - private checkCoinAndNetwork(data): boolean { + private checkCoinAndNetwork(data, network): boolean { let isValid, addrData; - addrData = this.addressProvider.getCoinAndNetwork(data, 'livenet'); + addrData = this.addressProvider.getCoinAndNetwork(data, network); isValid = this.currencyProvider .getChain(this.coinReceiveSelected.code as Coin) - .toLowerCase() == addrData.coin && addrData.network == 'livenet'; + .toLowerCase() == addrData.coin && addrData.network == network; if (isValid) { return true; @@ -577,6 +574,9 @@ export class CreateSwapPage implements OnInit { addressUserReceive: this.createForm.controls['address'].value, toTokenInfo : this.coinReceiveSelected.tokenInfo || null, fromTokenInfo : this.coinSwapSelected.tokenInfo || null, + fromNetwork: this.coinSwapSelected.network, + toNetwork: this.coinReceiveSelected.network + } as OrderOpts; this.orderProvider .createOrder(orderOpts) @@ -609,9 +609,6 @@ export class CreateSwapPage implements OnInit { msg || this.bwcErrorProvider.msg(error), infoSheetTitle, () => { - // if (exit) { - // this.location.back() - // } } ); } diff --git a/src/app/pages/swap/order-swap/order-swap.component.html b/src/app/pages/swap/order-swap/order-swap.component.html index 69638ac42db..ee0b39dc0cc 100644 --- a/src/app/pages/swap/order-swap/order-swap.component.html +++ b/src/app/pages/swap/order-swap/order-swap.component.html @@ -1,46 +1,49 @@ -
-
- {{'Review the payment instructions carefully. Sending anything other than Bitcoin Cash to the specificed destination via the correct network can result in permanent loss of your finds.' | translate}} -
+
+
+ {{'Review the payment instructions carefully. Sending anything other than Bitcoin Cash to the specificed destination via the correct network can result in permanent loss of your finds.' | translate}} +
-
-

Order number: {{order.id.toString().slice(-10)}}

-

{{ labelStatusString }}

-
-
- 1 {{ order.fromCoinCode.toUpperCase() }}   = -   {{ (1 * ( order.updatedRate || order.createdRate )).toFixed(2) }} {{ order.toCoinCode.toUpperCase() }} -
- - +
+

Order number: {{order.id.toString().slice(-10)}}

+

+ {{ labelStatusString }}

+
+
+ 1 {{ order.fromCoinCode.toUpperCase() }}   = +   {{ (1 * ( order.updatedRate || order.createdRate )).toFixed(2) }} + {{ order.toCoinCode.toUpperCase() }} +
+ + + +
+
+
+ {{'The final rate will be determined upon receipt of your {coin} payment.' | translate: {coin: order.fromCoinCode.toUpperCase()} }}
-
- {{'The final rate will be determined upon receipt of your {coin} payment.' | translate: {coin: order.fromCoinCode.toUpperCase()} }} -
-
-
+
- - +
+ \ No newline at end of file diff --git a/src/app/pages/swap/order-swap/order-swap.component.ts b/src/app/pages/swap/order-swap/order-swap.component.ts index 90da1c151b4..d0cbf3d4c91 100644 --- a/src/app/pages/swap/order-swap/order-swap.component.ts +++ b/src/app/pages/swap/order-swap/order-swap.component.ts @@ -6,7 +6,6 @@ import { BwcErrorProvider, Coin, ConfigProvider, CurrencyProvider, ErrorsProvide import { CoinConfig, TokenInfo } from '../config-swap'; import { Location } from '@angular/common'; import { TranslateService } from '@ngx-translate/core'; -import { runInThisContext } from 'vm'; interface IOrder { id: string | number; @@ -88,17 +87,11 @@ export class OrderSwapPage implements OnInit { this.orderId = this.navPramss.orderId; this.getOrderInfo(); } - // else(this.navPramss.orderId) - // this.coinReceive = this.navPramss.coinReceive; - // // this.coinSwap = this.navPramss.coinSwap; - // this.maxSwapAmount = this.coinReceive.maxConvertToSat / this.order.toSatUnit; - // this.minSwapAmount = this.coinReceive.minConvertToSat / this.order.toSatUnit; + } ngOnInit() { - // setInterval( - // this.getOrderInfo(), - // ) + } getNameCoin(order: IOrder) { @@ -183,9 +176,7 @@ export class OrderSwapPage implements OnInit { msg || this.bwcErrorProvider.msg(error), infoSheetTitle, () => { - // if (exit) { - // this.location.back() - // } + } ); } @@ -203,12 +194,13 @@ export class OrderSwapPage implements OnInit { } } } - public viewOnBlockchain(coin, isToken, txId): void { + public viewOnBlockchain(coin, isToken, txId, network): void { let defaults = this.configProvider.getDefaults(); const coinSelected = isToken ? 'xec' : coin; + if(network === 'livenet') this.blockexplorerUrl = defaults.blockExplorerUrl[coinSelected]; - // let btx = this.btx; - // const coin = btx.coin; + else + this.blockexplorerUrl = defaults.blockExplorerUrlTestnet[coinSelected]; const url = `https://${this.blockexplorerUrl}tx/${txId}`; let optIn = true; let title = null;