From 784f00b7258d325d773f454dee8fc094bf37147e Mon Sep 17 00:00:00 2001 From: softsimon Date: Thu, 8 Oct 2020 17:51:10 +0700 Subject: [PATCH] Enhancements to the sponsorship GUI fixes #128 --- backend/src/api/donations.ts | 21 +-- .../app/components/about/about.component.html | 153 +++++++++++------- .../app/components/about/about.component.scss | 1 + .../app/components/about/about.component.ts | 8 +- .../components/api-docs/api-docs.component.ts | 4 + .../master-page/master-page.component.html | 6 +- frontend/src/app/services/api.service.ts | 4 + frontend/src/resources/profile_softsimon.jpg | Bin 0 -> 6697 bytes frontend/src/resources/profile_wiz.jpg | Bin 0 -> 4122 bytes 9 files changed, 122 insertions(+), 75 deletions(-) create mode 100644 frontend/src/resources/profile_softsimon.jpg create mode 100644 frontend/src/resources/profile_wiz.jpg diff --git a/backend/src/api/donations.ts b/backend/src/api/donations.ts index d9c96aa6e..efde7116a 100644 --- a/backend/src/api/donations.ts +++ b/backend/src/api/donations.ts @@ -63,15 +63,18 @@ class Donations { } let imageUrl = ''; + let handle = ''; if (response.orderId !== '') { try { - imageUrl = await this.$getTwitterImageUrl(response.orderId); + const hiveData = await this.$getTwitterImageUrl(response.orderId); + imageUrl = hiveData.imageUrl; + handle = hiveData.screenName; } catch (e) { console.log('Error fetching twitter image', e.message); } } - this.$addDonationToDatabase(response, imageUrl); + this.$addDonationToDatabase(response.btcPaid, handle, response.id, imageUrl); } private getStatus(id: string): Promise { @@ -90,7 +93,7 @@ class Donations { async $getDonationsFromDatabase() { try { const connection = await DB.pool.getConnection(); - const query = `SELECT handle, imageUrl FROM donations WHERE handle != ''`; + const query = `SELECT handle, imageUrl FROM donations WHERE handle != '' ORDER BY id ASC`; const [rows] = await connection.query(query); connection.release(); return rows; @@ -99,14 +102,14 @@ class Donations { } } - private async $addDonationToDatabase(response: any, imageUrl: string): Promise { + private async $addDonationToDatabase(btcPaid: number, handle: string, orderId: string, imageUrl: string): Promise { try { const connection = await DB.pool.getConnection(); const query = `INSERT INTO donations(added, amount, handle, order_id, imageUrl) VALUES (NOW(), ?, ?, ?, ?)`; const params: (string | number)[] = [ - response.btcPaid, - response.orderId, - response.id, + btcPaid, + handle, + orderId, imageUrl, ]; const [result]: any = await connection.query(query, params); @@ -116,14 +119,14 @@ class Donations { } } - private async $getTwitterImageUrl(handle: string): Promise { + private async $getTwitterImageUrl(handle: string): Promise { return new Promise((resolve, reject) => { request.get({ uri: `https://api.hive.one/v1/influencers/screen_name/${handle}/?format=json`, json: true, }, (err, res, body) => { if (err) { return reject(err); } - resolve(body.data.imageUrl); + resolve(body.data); }); }); } diff --git a/frontend/src/app/components/about/about.component.html b/frontend/src/app/components/about/about.component.html index f84270ca1..b99f888d8 100644 --- a/frontend/src/app/components/about/about.component.html +++ b/frontend/src/app/components/about/about.component.html @@ -4,82 +4,111 @@

-

Contributors

+

Mempool Open Source Project

+ +
+ + + + + + + + + + + + + + + + + + + +


+ +

Maintainers

+ +
+
+
+
+ + @softsimon_ +
+ Development +
+
+
+ + @wiz +
+ Operations +
+
+
-

Development @softsimon_ -
Operations @wiz -
Logo & theme design @markjborg

- +

Sponsors

-

❤️ Sponsors

+
+
+
+
+
+

+ + +

+ Navigate to https://mempool.space/about to sponsor +

-
-

- - - -
-
-
-
- -
- +
+ +
+
+
-
-
- @ -
- -
-
- -
- -
- - -
- If you donate 0.01 BTC or more, your profile photo will be added to the list of sponsors above :) +
-
- -
-
- +
+
+ @ +
+
-
-

{{ donationObj.address }}

-

{{ donationObj.amount }} BTC

+
+ +
+ +
-

Waiting for transaction...

-
+ +
+ If you donate 0.01 BTC or more, your profile photo will be added to the list of sponsors above :)
- -
-

Donation confirmed!
Thank you!

-

If you specified a Twitter handle, the profile photo should now be visible on this page when you reload.

-
- -

-
-

Open source

+
+
+ +
+
+

{{ donationObj.address }}

+

{{ donationObj.amount }} BTC

+ +

Waiting for transaction...

+
+
+ +
+

Donation confirmed!
Thank you!

+

If you specified a Twitter handle, the profile photo should now be visible on this page when you reload.

+
- - - - Git - - - - - - github.com/mempool/mempool

diff --git a/frontend/src/app/components/about/about.component.scss b/frontend/src/app/components/about/about.component.scss index 0bb662b1e..1917fd536 100644 --- a/frontend/src/app/components/about/about.component.scss +++ b/frontend/src/app/components/about/about.component.scss @@ -10,6 +10,7 @@ background-size: 100%, 100%; border-radius: 50%; cursor: pointer; + margin: 10px; } .text-small { diff --git a/frontend/src/app/components/about/about.component.ts b/frontend/src/app/components/about/about.component.ts index fbdeb73dc..7e8eaefca 100644 --- a/frontend/src/app/components/about/about.component.ts +++ b/frontend/src/app/components/about/about.component.ts @@ -19,6 +19,7 @@ export class AboutComponent implements OnInit { sponsors$: Observable; donationObj: any; sponsorsEnabled = env.SPONSORS_ENABLED; + sponsors = null; constructor( private websocketService: WebsocketService, @@ -38,7 +39,12 @@ export class AboutComponent implements OnInit { handle: [''], }); - this.sponsors$ = this.apiService.getDonation$(); + (this.sponsorsEnabled ? this.apiService.getDonation$() : this.apiService.getDonationRemote$()) + .subscribe((sponsors) => { + this.sponsors = sponsors; + }); + + this.apiService.getDonation$() this.stateService.donationConfirmed$.subscribe(() => this.donationStatus = 4); } diff --git a/frontend/src/app/components/api-docs/api-docs.component.ts b/frontend/src/app/components/api-docs/api-docs.component.ts index f6fcfe94f..3ec89c27b 100644 --- a/frontend/src/app/components/api-docs/api-docs.component.ts +++ b/frontend/src/app/components/api-docs/api-docs.component.ts @@ -1,5 +1,6 @@ import { Component, OnInit } from '@angular/core'; import { StateService } from 'src/app/services/state.service'; +import { WebsocketService } from 'src/app/services/websocket.service'; @Component({ selector: 'app-api-docs', @@ -12,9 +13,12 @@ export class ApiDocsComponent implements OnInit { constructor( private stateService: StateService, + private websocketService: WebsocketService, ) { } ngOnInit(): void { + this.websocketService.want(['blocks']); + if (this.stateService.network === 'bisq') { this.active = 2; } diff --git a/frontend/src/app/components/master-page/master-page.component.html b/frontend/src/app/components/master-page/master-page.component.html index 6aa8d4291..65809e329 100644 --- a/frontend/src/app/components/master-page/master-page.component.html +++ b/frontend/src/app/components/master-page/master-page.component.html @@ -52,12 +52,12 @@ - +
diff --git a/frontend/src/app/services/api.service.ts b/frontend/src/app/services/api.service.ts index 5f97481fb..2a28e5b05 100644 --- a/frontend/src/app/services/api.service.ts +++ b/frontend/src/app/services/api.service.ts @@ -73,4 +73,8 @@ export class ApiService { getDonation$(): Observable { return this.httpClient.get(this.apiBaseUrl + '/donations'); } + + getDonationRemote$(): Observable { + return this.httpClient.get('http://mempool.space/api/v1/donations'); + } } diff --git a/frontend/src/resources/profile_softsimon.jpg b/frontend/src/resources/profile_softsimon.jpg new file mode 100644 index 0000000000000000000000000000000000000000..2e8966120fa11a6e4d0fa7e1365ed590dce72bb8 GIT binary patch literal 6697 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 Xp9i*>HE{F6V&!QUPooGwJk0$M#7TV+ literal 0 HcmV?d00001 diff --git a/frontend/src/resources/profile_wiz.jpg b/frontend/src/resources/profile_wiz.jpg new file mode 100644 index 0000000000000000000000000000000000000000..9247a675e045b00293ce0271dda275b788997757 GIT binary patch literal 4122 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 Ni^+KOse literal 0 HcmV?d00001