Add copy to clipboard functionality to addresses.
This commit is contained in:
		
							parent
							
								
									a2e320d923
								
							
						
					
					
						commit
						4030f709fc
					
				
							
								
								
									
										54
									
								
								src/app/_helpers/clipboard-copy.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								src/app/_helpers/clipboard-copy.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,54 @@
 | 
			
		||||
function copyToClipboard(text: any): boolean {
 | 
			
		||||
  // create our hidden div element
 | 
			
		||||
  const hiddenCopy = document.createElement('div');
 | 
			
		||||
  // set the innerHTML of the div
 | 
			
		||||
  hiddenCopy.innerHTML = text;
 | 
			
		||||
  // set the position to be absolute and off the screen
 | 
			
		||||
  hiddenCopy.style.position = 'absolute';
 | 
			
		||||
  hiddenCopy.style.left = '-9999px';
 | 
			
		||||
 | 
			
		||||
  // check and see if the user had a text selection range
 | 
			
		||||
  let currentRange;
 | 
			
		||||
  if (document.getSelection().rangeCount > 0) {
 | 
			
		||||
  // the user has a text selection range, store it
 | 
			
		||||
  currentRange = document.getSelection().getRangeAt(0);
 | 
			
		||||
  // remove the current selection
 | 
			
		||||
  window.getSelection().removeRange(currentRange);
 | 
			
		||||
  } else {
 | 
			
		||||
    // they didn't have anything selected
 | 
			
		||||
    currentRange = false;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // append the div to the body
 | 
			
		||||
  document.body.appendChild(hiddenCopy);
 | 
			
		||||
  // create a selection range
 | 
			
		||||
  const copyRange = document.createRange();
 | 
			
		||||
  // set the copy range to be the hidden div
 | 
			
		||||
  copyRange.selectNode(hiddenCopy);
 | 
			
		||||
  // add the copy range
 | 
			
		||||
  window.getSelection().addRange(copyRange);
 | 
			
		||||
 | 
			
		||||
  // since not all browsers support this, use a try block
 | 
			
		||||
  try {
 | 
			
		||||
    // copy the text
 | 
			
		||||
    document.execCommand('copy');
 | 
			
		||||
  } catch (err) {
 | 
			
		||||
    window.alert('Your Browser Doesn\'t support this! Error : ' + err);
 | 
			
		||||
    return false;
 | 
			
		||||
  }
 | 
			
		||||
  // remove the selection range (Chrome throws a warning if we don't.)
 | 
			
		||||
  window.getSelection().removeRange(copyRange);
 | 
			
		||||
  // remove the hidden div
 | 
			
		||||
  document.body.removeChild(hiddenCopy);
 | 
			
		||||
 | 
			
		||||
  // return the old selection range
 | 
			
		||||
  if (currentRange) {
 | 
			
		||||
    window.getSelection().addRange(currentRange);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export {
 | 
			
		||||
  copyToClipboard
 | 
			
		||||
};
 | 
			
		||||
@ -6,3 +6,4 @@ export * from '@app/_helpers/http-getter';
 | 
			
		||||
export * from '@app/_helpers/global-error-handler';
 | 
			
		||||
export * from '@app/_helpers/export-csv';
 | 
			
		||||
export * from '@app/_helpers/read-csv';
 | 
			
		||||
export * from '@app/_helpers/clipboard-copy';
 | 
			
		||||
 | 
			
		||||
@ -35,7 +35,10 @@
 | 
			
		||||
          </h3>
 | 
			
		||||
          <span class="ml-auto"><strong>Balance:</strong> {{account?.balance | tokenRatio}} SRF</span>
 | 
			
		||||
          <span class="ml-2"><strong>Created:</strong> {{account?.date_registered | date}}</span>
 | 
			
		||||
          <span class="ml-2"><strong>Address:</strong><a href="{{bloxbergLink}}" target="_blank"> {{account?.identities.evm['bloxberg:8996']}} </a></span>
 | 
			
		||||
          <span class="ml-2"><strong>Address:</strong>
 | 
			
		||||
            <a href="{{bloxbergLink}}" target="_blank"> {{accountAddress}} </a>
 | 
			
		||||
            <img src="assets/images/checklist.svg" class="ml-2" height="20rem" (click)="copyAddress()" alt="Copy">
 | 
			
		||||
          </span>
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
      <div *ngIf="account" class="card mt-3 mb-3">
 | 
			
		||||
@ -176,13 +179,13 @@
 | 
			
		||||
              </div>
 | 
			
		||||
 | 
			
		||||
              <div class="col-md-6 col-lg-4">
 | 
			
		||||
                <button mat-raised-button color="primary" type="button" class="btn btn btn-outline-primary mb-3">
 | 
			
		||||
                <button mat-raised-button color="primary" type="button" class="btn btn-outline-primary mb-3">
 | 
			
		||||
                  Add User KYC
 | 
			
		||||
                </button>
 | 
			
		||||
              </div>
 | 
			
		||||
 | 
			
		||||
              <div class="col-md-6 col-lg-4">
 | 
			
		||||
                <button mat-raised-button color="primary" type="button" class="btn btn btn-outline-success mb-3"
 | 
			
		||||
                <button mat-raised-button color="primary" type="button" class="btn btn-outline-success mb-3"
 | 
			
		||||
                        (click)="resetPin()">
 | 
			
		||||
                  Reset Pin
 | 
			
		||||
                </button>
 | 
			
		||||
 | 
			
		||||
@ -6,7 +6,8 @@ import {BlockSyncService, LocationService, LoggingService, TokenService, Transac
 | 
			
		||||
import {ActivatedRoute, Params, Router} from '@angular/router';
 | 
			
		||||
import {first} from 'rxjs/operators';
 | 
			
		||||
import {FormBuilder, FormGroup, Validators} from '@angular/forms';
 | 
			
		||||
import {CustomErrorStateMatcher, exportCsv} from '@app/_helpers';
 | 
			
		||||
import {copyToClipboard, CustomErrorStateMatcher, exportCsv} from '@app/_helpers';
 | 
			
		||||
import {MatSnackBar} from '@angular/material/snack-bar';
 | 
			
		||||
 | 
			
		||||
@Component({
 | 
			
		||||
  selector: 'app-account-details',
 | 
			
		||||
@ -54,6 +55,7 @@ export class AccountDetailsComponent implements OnInit {
 | 
			
		||||
    private loggingService: LoggingService,
 | 
			
		||||
    private blockSyncService: BlockSyncService,
 | 
			
		||||
    private cdr: ChangeDetectorRef,
 | 
			
		||||
    private snackBar: MatSnackBar,
 | 
			
		||||
  ) {
 | 
			
		||||
    this.accountInfoForm = this.formBuilder.group({
 | 
			
		||||
      name: ['', Validators.required],
 | 
			
		||||
@ -190,4 +192,10 @@ export class AccountDetailsComponent implements OnInit {
 | 
			
		||||
  downloadCsv(data: any, filename: string): void {
 | 
			
		||||
    exportCsv(data, filename);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  copyAddress(): void {
 | 
			
		||||
    if (copyToClipboard(this.accountAddress)) {
 | 
			
		||||
      this.snackBar.open(this.accountAddress + ' copied successfully!', 'Close', { duration: 3000 });
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -25,6 +25,7 @@ import {MatRippleModule} from '@angular/material/core';
 | 
			
		||||
import {MatProgressSpinnerModule} from '@angular/material/progress-spinner';
 | 
			
		||||
import {ReactiveFormsModule} from '@angular/forms';
 | 
			
		||||
import { AccountSearchComponent } from './account-search/account-search.component';
 | 
			
		||||
import {MatSnackBarModule} from '@angular/material/snack-bar';
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@NgModule({
 | 
			
		||||
@ -55,7 +56,8 @@ import { AccountSearchComponent } from './account-search/account-search.componen
 | 
			
		||||
    MatTabsModule,
 | 
			
		||||
    MatRippleModule,
 | 
			
		||||
    MatProgressSpinnerModule,
 | 
			
		||||
    ReactiveFormsModule
 | 
			
		||||
    ReactiveFormsModule,
 | 
			
		||||
    MatSnackBarModule,
 | 
			
		||||
  ]
 | 
			
		||||
})
 | 
			
		||||
export class AccountsModule { }
 | 
			
		||||
 | 
			
		||||
@ -13,12 +13,20 @@
 | 
			
		||||
          <ul class="list-group list-group-flush">
 | 
			
		||||
            <li class="list-group-item">
 | 
			
		||||
              <span>Sender: {{transaction.sender?.vcard.fn[0].value}}</span><br><br>
 | 
			
		||||
              <span>Sender Address: <a href="{{senderBloxbergLink}}" target="_blank"> {{transaction.from}} </a></span><br><br>
 | 
			
		||||
              <span>
 | 
			
		||||
                Sender Address:
 | 
			
		||||
                <a href="{{senderBloxbergLink}}" target="_blank"> {{transaction.from}} </a>
 | 
			
		||||
                <img src="assets/images/checklist.svg" class="ml-2" height="20rem" (click)="copyAddress(transaction.from)" alt="Copy">
 | 
			
		||||
              </span><br><br>
 | 
			
		||||
              <button mat-raised-button color="primary" class="btn btn-outline-info" (click)="viewSender()">View Sender</button>
 | 
			
		||||
            </li>
 | 
			
		||||
            <li class="list-group-item">
 | 
			
		||||
              <span>Recipient: {{transaction.recipient?.vcard.fn[0].value}}</span><br><br>
 | 
			
		||||
              <span>Recipient Address: <a href="{{recipientBloxbergLink}}" target="_blank"> {{transaction.to}} </a></span><br><br>
 | 
			
		||||
              <span>
 | 
			
		||||
                Recipient Address:
 | 
			
		||||
                <a href="{{recipientBloxbergLink}}" target="_blank"> {{transaction.to}} </a>
 | 
			
		||||
                <img src="assets/images/checklist.svg" class="ml-2" height="20rem" (click)="copyAddress(transaction.to)" alt="Copy">
 | 
			
		||||
              </span><br><br>
 | 
			
		||||
              <button mat-raised-button color="primary" class="btn btn-outline-info" (click)="viewRecipient()">View Recipient</button>
 | 
			
		||||
            </li>
 | 
			
		||||
            <li class="list-group-item">
 | 
			
		||||
@ -28,7 +36,11 @@
 | 
			
		||||
          <h4 class="mt-2">Token: </h4>
 | 
			
		||||
          <ul class="list-group list-group-flush">
 | 
			
		||||
            <li class="list-group-item">
 | 
			
		||||
              <span>Address: {{transaction.token._address}}</span>
 | 
			
		||||
              <span>
 | 
			
		||||
                Address:
 | 
			
		||||
                {{transaction.token._address}}
 | 
			
		||||
                <img src="assets/images/checklist.svg" class="ml-2" height="20rem" (click)="copyAddress(transaction.token._address)" alt="Copy">
 | 
			
		||||
              </span>
 | 
			
		||||
            </li>
 | 
			
		||||
            <li class="list-group-item">
 | 
			
		||||
              <span>Name: Sarafu Token</span>
 | 
			
		||||
@ -73,17 +85,25 @@
 | 
			
		||||
          <span><strong>Trader: {{transaction.sender?.vcard.fn[0].value}}</strong></span>
 | 
			
		||||
        </li>
 | 
			
		||||
        <li class="list-group-item">
 | 
			
		||||
          <span>Trader Address: {{transaction.trader}}</span>
 | 
			
		||||
          <span>
 | 
			
		||||
            Trader Address:
 | 
			
		||||
            <a href="{{traderBloxbergLink}}" target="_blank"> {{transaction.trader}} </a>
 | 
			
		||||
            <img src="assets/images/checklist.svg" class="ml-2" height="20rem" (click)="copyAddress(transaction.trader)" alt="Copy">
 | 
			
		||||
          </span>
 | 
			
		||||
        </li>
 | 
			
		||||
      </ul>
 | 
			
		||||
      <button mat-raised-button color="primary" class="btn btn-outline-info" routerLink="/accounts/1">View Trader</button>
 | 
			
		||||
      <button mat-raised-button color="primary" class="btn btn-outline-info" (click)="viewTrader()">View Trader</button>
 | 
			
		||||
      <br><br>
 | 
			
		||||
      <div class="row">
 | 
			
		||||
        <div class="col-md-6">
 | 
			
		||||
          <h4>Source Token: </h4>
 | 
			
		||||
          <ul class="list-group list-group-flush">
 | 
			
		||||
            <li class="list-group-item">
 | 
			
		||||
              <span>Address: {{transaction.sourceToken.address}}</span>
 | 
			
		||||
              <span>
 | 
			
		||||
                Address:
 | 
			
		||||
                {{transaction.sourceToken.address}}
 | 
			
		||||
                <img src="assets/images/checklist.svg" class="ml-2" height="20rem" (click)="copyAddress(transaction.sourceToken.address)" alt="Copy">
 | 
			
		||||
              </span>
 | 
			
		||||
            </li>
 | 
			
		||||
            <li class="list-group-item">
 | 
			
		||||
              <span>Name: {{transaction.sourceToken.name}}</span>
 | 
			
		||||
@ -100,7 +120,11 @@
 | 
			
		||||
          <h4>Destination Token: </h4>
 | 
			
		||||
          <ul class="list-group list-group-flush">
 | 
			
		||||
            <li class="list-group-item">
 | 
			
		||||
              <span>Address: {{transaction.destinationToken.address}}</span>
 | 
			
		||||
              <span>
 | 
			
		||||
                Address:
 | 
			
		||||
                {{transaction.destinationToken.address}}
 | 
			
		||||
                <img src="assets/images/checklist.svg" class="ml-2" height="20rem" (click)="copyAddress(transaction.destinationToken.address)" alt="Copy">
 | 
			
		||||
              </span>
 | 
			
		||||
            </li>
 | 
			
		||||
            <li class="list-group-item">
 | 
			
		||||
              <span>Name: {{transaction.destinationToken.name}}</span>
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,8 @@
 | 
			
		||||
import {ChangeDetectionStrategy, Component, Input, OnInit} from '@angular/core';
 | 
			
		||||
import {Router} from '@angular/router';
 | 
			
		||||
import {TransactionService} from '@app/_services';
 | 
			
		||||
import {copyToClipboard} from '../../../_helpers';
 | 
			
		||||
import {MatSnackBar} from '@angular/material/snack-bar';
 | 
			
		||||
 | 
			
		||||
@Component({
 | 
			
		||||
  selector: 'app-transaction-details',
 | 
			
		||||
@ -12,15 +14,21 @@ export class TransactionDetailsComponent implements OnInit {
 | 
			
		||||
  @Input() transaction;
 | 
			
		||||
  senderBloxbergLink: string;
 | 
			
		||||
  recipientBloxbergLink: string;
 | 
			
		||||
  traderBloxbergLink: string;
 | 
			
		||||
 | 
			
		||||
  constructor(
 | 
			
		||||
    private router: Router,
 | 
			
		||||
    private transactionService: TransactionService
 | 
			
		||||
    private transactionService: TransactionService,
 | 
			
		||||
    private snackBar: MatSnackBar,
 | 
			
		||||
  ) { }
 | 
			
		||||
 | 
			
		||||
  ngOnInit(): void {
 | 
			
		||||
    this.senderBloxbergLink = 'https://blockexplorer.bloxberg.org/address/' + this.transaction?.from + '/transactions';
 | 
			
		||||
    this.recipientBloxbergLink = 'https://blockexplorer.bloxberg.org/address/' + this.transaction?.to + '/transactions';
 | 
			
		||||
    if (this.transaction.type === 'conversion') {
 | 
			
		||||
      this.traderBloxbergLink = 'https://blockexplorer.bloxberg.org/address/' + this.transaction?.trader + '/transactions';
 | 
			
		||||
    } else {
 | 
			
		||||
      this.senderBloxbergLink = 'https://blockexplorer.bloxberg.org/address/' + this.transaction?.from + '/transactions';
 | 
			
		||||
      this.recipientBloxbergLink = 'https://blockexplorer.bloxberg.org/address/' + this.transaction?.to + '/transactions';
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  async viewSender(): Promise<void> {
 | 
			
		||||
@ -31,6 +39,10 @@ export class TransactionDetailsComponent implements OnInit {
 | 
			
		||||
    await this.router.navigateByUrl(`/accounts/${this.transaction.to}`);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  async viewTrader(): Promise<void> {
 | 
			
		||||
    await this.router.navigateByUrl(`/accounts/${this.transaction.trader}`);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  async reverseTransaction(): Promise<void> {
 | 
			
		||||
    await this.transactionService.transferRequest(
 | 
			
		||||
      this.transaction.token.address,
 | 
			
		||||
@ -39,4 +51,10 @@ export class TransactionDetailsComponent implements OnInit {
 | 
			
		||||
      this.transaction.value
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  copyAddress(address: string): void {
 | 
			
		||||
    if (copyToClipboard(address)) {
 | 
			
		||||
      this.snackBar.open(address + ' copied successfully!', 'Close', { duration: 3000 });
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -17,6 +17,7 @@ import {MatIconModule} from '@angular/material/icon';
 | 
			
		||||
import {MatSelectModule} from '@angular/material/select';
 | 
			
		||||
import {MatCardModule} from '@angular/material/card';
 | 
			
		||||
import {MatRippleModule} from '@angular/material/core';
 | 
			
		||||
import {MatSnackBarModule} from '@angular/material/snack-bar';
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@NgModule({
 | 
			
		||||
@ -39,7 +40,8 @@ import {MatRippleModule} from '@angular/material/core';
 | 
			
		||||
        MatIconModule,
 | 
			
		||||
        MatSelectModule,
 | 
			
		||||
        MatCardModule,
 | 
			
		||||
        MatRippleModule
 | 
			
		||||
        MatRippleModule,
 | 
			
		||||
      MatSnackBarModule,
 | 
			
		||||
    ]
 | 
			
		||||
})
 | 
			
		||||
export class TransactionsModule { }
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										1
									
								
								src/assets/images/checklist.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								src/assets/images/checklist.svg
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							| 
		 After Width: | Height: | Size: 7.8 KiB  | 
		Loading…
	
		Reference in New Issue
	
	Block a user