@@ -12,7 +12,49 @@
|
||||
|
||||
<br><br>
|
||||
|
||||
<iframe src='https://btcpay.wiz.biz/apps/4XrJdGCE2a8FMEkRd52YwoiwzJqP/pos' style='height: 600px; width: 400px; border: 0;'></iframe>
|
||||
<h2>❤️ Sponsors</h2>
|
||||
|
||||
<div *ngFor="let sponsor of sponsors$ | async; let i = index" (click)="openTwitterProfile(sponsor.handle)" class="profile_photo d-inline-block" [class.ml-3]="i > 0" [ngStyle]="{'background-image': 'url(' + sponsor.imageUrl + ')'}" [title]="sponsor.handle"></div>
|
||||
<br><br>
|
||||
|
||||
<button type="button" class="btn btn-primary" (click)="donationStatus = 2" [hidden]="donationStatus !== 1">Become a sponsor</button>
|
||||
|
||||
<div style="max-width: 300px;" class="mx-auto" [hidden]="donationStatus !== 2">
|
||||
<form [formGroup]="donationForm" (submit)="submitDonation()" class="form">
|
||||
<div class="input-group mb-2">
|
||||
<div class="input-group-prepend" style="width: 42px;">
|
||||
<span class="input-group-text">₿</span>
|
||||
</div>
|
||||
<input formControlName="amount" class="form-control" type="number" min="0.0001" step="1E-03">
|
||||
</div>
|
||||
<div class="input-group mb-4">
|
||||
<div class="input-group-prepend" style="width: 42px;">
|
||||
<span class="input-group-text">@</span>
|
||||
</div>
|
||||
<input formControlName="handle" class="form-control" type="text" placeholder="Twitter handle (Optional)">
|
||||
</div>
|
||||
<div class="input-group">
|
||||
<button class="btn btn-primary mx-auto" type="submit">Request invoice</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div *ngIf="donationStatus === 3" class="text-center">
|
||||
<div class="qr-wrapper mt-4 mb-2">
|
||||
<app-qrcode [data]="donationObj.address + '?amount=' + donationObj.amount"></app-qrcode>
|
||||
</div>
|
||||
<br>
|
||||
<p style="font-size: 10px;">{{ donationObj.address }}</p>
|
||||
<p>Waiting for transaction... </p>
|
||||
<div class="spinner-border text-light"></div>
|
||||
</div>
|
||||
|
||||
<div *ngIf="donationStatus === 4" class="text-center">
|
||||
<h2>Donation confirmed!<br>Thank you!</h2>
|
||||
<p>If you specified a Twitter handle, the profile photo should now be visible on this page when you reload.</p>
|
||||
</div>
|
||||
|
||||
<br><br>
|
||||
|
||||
<h2>GitHub</h2>
|
||||
|
||||
|
||||
@@ -14,3 +14,17 @@ tr {
|
||||
.nowrap {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.qr-wrapper {
|
||||
background-color: #FFF;
|
||||
padding: 10px;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.profile_photo {
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
background-size: 100%, 100%;
|
||||
border-radius: 50%;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
@@ -3,22 +3,29 @@ import { WebsocketService } from '../../services/websocket.service';
|
||||
import { SeoService } from 'src/app/services/seo.service';
|
||||
import { StateService } from 'src/app/services/state.service';
|
||||
import { Observable } from 'rxjs';
|
||||
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
|
||||
import { ApiService } from 'src/app/services/api.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-about',
|
||||
templateUrl: './about.component.html',
|
||||
styleUrls: ['./about.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class AboutComponent implements OnInit {
|
||||
active = 1;
|
||||
hostname = document.location.hostname;
|
||||
gitCommit$: Observable<string>;
|
||||
donationForm: FormGroup;
|
||||
donationStatus = 1;
|
||||
sponsors$: Observable<any>;
|
||||
donationObj: any;
|
||||
|
||||
constructor(
|
||||
private websocketService: WebsocketService,
|
||||
private seoService: SeoService,
|
||||
private stateService: StateService,
|
||||
private formBuilder: FormBuilder,
|
||||
private apiService: ApiService,
|
||||
) { }
|
||||
|
||||
ngOnInit() {
|
||||
@@ -31,5 +38,32 @@ export class AboutComponent implements OnInit {
|
||||
if (document.location.port !== '') {
|
||||
this.hostname = this.hostname + ':' + document.location.port;
|
||||
}
|
||||
|
||||
this.donationForm = this.formBuilder.group({
|
||||
amount: [0.001],
|
||||
handle: [''],
|
||||
});
|
||||
|
||||
this.sponsors$ = this.apiService.getDonation$();
|
||||
this.stateService.donationConfirmed$.subscribe(() => this.donationStatus = 4);
|
||||
}
|
||||
|
||||
submitDonation() {
|
||||
if (this.donationForm.invalid) {
|
||||
return;
|
||||
}
|
||||
this.apiService.requestDonation$(
|
||||
this.donationForm.get('amount').value,
|
||||
this.donationForm.get('handle').value
|
||||
)
|
||||
.subscribe((response) => {
|
||||
this.websocketService.trackDonation(response.id);
|
||||
this.donationObj = response;
|
||||
this.donationStatus = 3;
|
||||
});
|
||||
}
|
||||
|
||||
openTwitterProfile(handle: string) {
|
||||
window.open('https://twitter.com/' + handle, '_blank');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,10 +14,12 @@ export interface WebsocketResponse {
|
||||
tx?: Transaction;
|
||||
rbfTransaction?: Transaction;
|
||||
transactions?: TransactionStripped[];
|
||||
donationConfirmed?: boolean;
|
||||
'track-tx'?: string;
|
||||
'track-address'?: string;
|
||||
'track-asset'?: string;
|
||||
'watch-mempool'?: boolean;
|
||||
'track-donation'?: string;
|
||||
}
|
||||
|
||||
export interface MempoolBlock {
|
||||
|
||||
@@ -61,4 +61,16 @@ export class ApiService {
|
||||
});
|
||||
return this.httpClient.get<number[]>(this.apiBaseUrl + '/transaction-times', { params });
|
||||
}
|
||||
|
||||
requestDonation$(amount: number, orderId: string): Observable<any> {
|
||||
const params = {
|
||||
amount: amount,
|
||||
orderId: orderId,
|
||||
};
|
||||
return this.httpClient.post<any>(this.apiBaseUrl + '/donations', params);
|
||||
}
|
||||
|
||||
getDonation$(): Observable<any[]> {
|
||||
return this.httpClient.get<any[]>(this.apiBaseUrl + '/donations');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,6 +34,7 @@ export class StateService {
|
||||
vbytesPerSecond$ = new ReplaySubject<number>(1);
|
||||
lastDifficultyAdjustment$ = new ReplaySubject<number>(1);
|
||||
gitCommit$ = new ReplaySubject<string>(1);
|
||||
donationConfirmed$ = new Subject();
|
||||
|
||||
live2Chart$ = new Subject<OptimizedMempoolStats>();
|
||||
|
||||
|
||||
@@ -155,6 +155,10 @@ export class WebsocketService {
|
||||
this.stateService.gitCommit$.next(response['git-commit']);
|
||||
}
|
||||
|
||||
if (response.donationConfirmed) {
|
||||
this.stateService.donationConfirmed$.next(true);
|
||||
}
|
||||
|
||||
if (this.goneOffline === true) {
|
||||
this.goneOffline = false;
|
||||
if (this.lastWant) {
|
||||
@@ -189,6 +193,10 @@ export class WebsocketService {
|
||||
this.isTrackingTx = true;
|
||||
}
|
||||
|
||||
trackDonation(id: string) {
|
||||
this.websocketSubject.next({ 'track-donation': id });
|
||||
}
|
||||
|
||||
stopTrackingTransaction() {
|
||||
if (!this.isTrackingTx) {
|
||||
return;
|
||||
|
||||
@@ -21,6 +21,11 @@ $pagination-hover-bg: #12131e;
|
||||
$pagination-hover-border-color: #1d1f31;
|
||||
$pagination-disabled-bg: #1d1f31;
|
||||
|
||||
.input-group-text {
|
||||
background-color: #1c2031 !important;
|
||||
border: 1px solid #20263e !important;
|
||||
}
|
||||
|
||||
$link-color: #1bd8f4;
|
||||
$link-decoration: none !default;
|
||||
$link-hover-color: darken($link-color, 15%) !default;
|
||||
|
||||
Reference in New Issue
Block a user