Last active
February 17, 2020 23:48
-
-
Save alexytiger/c5cccfce784252813cb1593d7590bc83 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { Component, ViewChild, ElementRef, OnInit, OnDestroy } | |
from '@angular/core'; | |
import { FormBuilder, FormGroup, Validators, AbstractControl } | |
from '@angular/forms'; | |
import { MatDialog, MatDialogConfig } from '@angular/material'; | |
import { Observable } from 'rxjs'; | |
import { tap } from 'rxjs/operators'; | |
import { utils } from 'ethers'; | |
import { Store, select } from '@ngrx/store'; | |
import * as fromPurchaseContract from '../../store/reducers'; | |
import { IpfsImageActions, PurchaseContractActions } | |
from '../../store/actions'; | |
import { FileUploadStatus } | |
from '../../store/reducers/ipfs-product-image.reducer' | |
import { ShowIpfsImageComponent } | |
from '../../components/show-ipfs-image/show-ipfs-image.component'; | |
// Utility function. Check if string is less then 32 bytes. | |
// Needed to pass into the smart contract | |
function bites32StringValidator(control: AbstractControl): | |
{ [key: string]: any } | null { | |
let pathTest = false; | |
try { | |
utils.formatBytes32String(control.value); | |
pathTest = true; | |
} catch (error) { | |
// console.log('bites32StringValidator', error) | |
} | |
return !pathTest ? { | |
forbiddenKey: { | |
value: control.value | |
} | |
} : null; | |
} | |
@Component({ | |
selector: 'app-new-purchase-contract', | |
templateUrl: './new-purchase-contract.component.html', | |
styleUrls: ['./new-purchase-contract.component.css'] | |
}) | |
export class NewPurchaseContractComponent implements OnInit, OnDestroy { | |
@ViewChild('file') fileControl: ElementRef; | |
fileBlob: File; | |
fileContent: ArrayBuffer; | |
ipfsHash$: Observable<string>; | |
uploadStatus$: Observable<FileUploadStatus>; | |
private readonly IMAGE_PATTERN: RegExp = /^.+\.(png|jpg|jpeg|gif|png)$/; | |
commissions: string[] = ['2.0', '2.5', '3.0', '3.5', '4.0']; | |
constructor( | |
private store$: Store<fromPurchaseContract.AppState>, | |
private formBuilder: FormBuilder, | |
public dialog: MatDialog | |
) { } | |
frmGroup: FormGroup = this.formBuilder.group({ | |
productKey: ['', [Validators.required, bites32StringValidator]], | |
description: ['', Validators.required], | |
etherValue: ['', [Validators.required, | |
Validators.pattern(/^\d+(\.\d{1,3})?$/)]], | |
commission: ['', Validators.required], | |
fileArg: ['', [Validators.required, Validators.pattern(this.IMAGE_PATTERN)]], | |
ipfsHash: ['', Validators.required] // to hold ipfsHash value | |
}); | |
ngOnInit() { | |
this.uploadStatus$ = | |
this.store$.pipe(select(fromPurchaseContract.getIpfsUploadStatus)); | |
this.ipfsHash$ = this.store$.pipe( | |
select(fromPurchaseContract.getIpfsHash), | |
tap(value => this.frmGroup.get('ipfsHash').patchValue(value)) | |
); | |
} | |
formControl = (name: string) => this.frmGroup.get(`${name}`); | |
required = (name: string) => | |
this.formControl(name).hasError('required') && this.formControl(name).touched | |
invalidPattern = (name: string) => | |
this.formControl(name).hasError('pattern') && this.formControl(name).dirty | |
invalid32BytesKey = (name: string) => | |
this.formControl(name).hasError('forbiddenKey') && this.formControl(name).dirty | |
requiredFile = (name: string) => this.formControl(name).hasError('required'); | |
invalidPatternFile = (name: string) => this.formControl(name).hasError('pattern'); | |
// here is the way to emulate the click on the file input control | |
selectFile() { | |
this.fileControl.nativeElement.click(); | |
} | |
onFileChange(event) { | |
if (event.target.files && event.target.files.length) { | |
this.fileBlob = event.target.files[0]; | |
this.frmGroup.get('fileArg').patchValue(this.fileBlob.name); | |
const reader = new FileReader(); | |
reader.readAsDataURL(this.fileBlob); | |
reader.onload = _ => { | |
this.fileContent = reader.result as ArrayBuffer; | |
this.store$.dispatch(IpfsImageActions.reset()); | |
}; | |
} | |
} | |
uploadFile() { | |
this.store$.dispatch(IpfsImageActions.uploadImage({ file: this.fileBlob })); | |
} | |
isPending = (status: FileUploadStatus) => status === FileUploadStatus.Pending; | |
isSuccess = (status: FileUploadStatus) => status === FileUploadStatus.Success; | |
isError = (status: FileUploadStatus) => status === FileUploadStatus.Error; | |
inProgress = (status: FileUploadStatus) => status === FileUploadStatus.Progress; | |
loadImage() { | |
const dialogConfig = new MatDialogConfig(); | |
dialogConfig.width = '460px'; | |
dialogConfig.disableClose = true; | |
dialogConfig.autoFocus = true; | |
this.dialog.open(ShowIpfsImageComponent, dialogConfig); | |
} | |
onCreate(): void { | |
const { valid } = this.frmGroup; | |
if (valid) { | |
const { fileArg, ...model } = this.frmGroup.value; | |
this.store$.dispatch(PurchaseContractActions. | |
createPurchaseContract({ payload: model })); | |
} | |
} | |
ngOnDestroy(): void { | |
this.store$.dispatch(IpfsImageActions.reset()); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment