Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

Already on GitHub? Sign in to your account

Improves the donation handling #1731

Merged
merged 12 commits into from Aug 7, 2017

Conversation

Projects
None yet
6 participants
Contributor

kuzzmi commented Aug 5, 2017 edited

This PR improves donations UI and closes #1728.

What was done in this PR:

  • Adds Donations configuration to _config.yml
  • Adds collapsible Donations bar to the top of the page
  • Displays Donations bar only on desktop
  • Adds modal window with QR code
  • Adds buttons for suggested donations
  • Adds custom donation inputs with auto-conversion USD <-> BTC based on Blockchain.info ticker
  • Adds field for an optional message
  • Auto-generates QR code based on the amount and optional message
  • Adds support for future translations of a Donations bar and modal window

Screenshots

image

image

image

Any feedback is highly appreciated.

! Warning !

This PR modifies JavaScript and CSS files, which are cached with Nginx with no control over the changes (we've seen that after wallets pages were refactored). This might result in bugs if users get old main.js and main.css.


Bounty can be sent to:
14kafbQ3WBmvMhAA3y6gwohUuYQ4zLZrLq

@kuzzmi kuzzmi changed the title from Feature donation to Improves the donation handling Aug 5, 2017

Contributor

crwatkins commented Aug 5, 2017

This comment may be out of the scope of this particular effort (particularly because we currently don't have any dynamic content capabilities deployed) but it would be good to eventually have a unique payment address (perhaps BIP32-based) for each user for privacy reasons.

Contributor

kuzzmi commented Aug 5, 2017

@crwatkins It makes sense, however, the transparency is equally important in my opinion. Anyway, with current configuration it won't be difficult to tweak the front-end code to support this.

Left a few comments. Please let me know if there's anything not clear enough.

_includes/layout/base/html-head.html
@@ -16,6 +16,8 @@
{% if page.lang == 'bg' or page.lang == 'el' or page.lang == 'ko' or page.lang == 'hi' or page.lang == 'pl' or page.lang == 'sl' or page.lang == 'ro' or page.lang == 'ru' or page.lang == 'tr' or page.lang == 'uk' or page.lang == 'zh_CN' or page.lang == 'zh_TW' %}<link rel="stylesheet" href="/css/sans.css">{% endif %}
<script type="text/javascript" src="/js/base.js"></script>
{% if page.id != 'download' %}<script type="text/javascript" src="/js/main.js"></script>{% endif %}
+<script src="/js/jquery/jquery-1.11.2.min.js"></script>
@Francisc

Francisc Aug 5, 2017

jQuery is way too expensive to be added as a dependency for the banner alone.
As far as I can see, it's only loaded on a handful of pages.

@kuzzmi

kuzzmi Aug 6, 2017

Contributor

It's used for QR code generation. Currently nginx uses very long-living cache and Gzip, so I don't see a big problem in the long run, as in the end it will result in additional 32kb file to be loaded.

If this is everybody's concern, I'll rework this without jQuery.

@Cobra-Bitcoin

Cobra-Bitcoin Aug 6, 2017

Contributor

jQuery is fine, and keep in mind that this should only be shown to non-mobile users, so having some extra dependencies isn't the worst thing.

@Francisc

Francisc Aug 6, 2017

Good to hear caching and compression are enabled.

However, it's not just download size that matters.
While the file may be cached (never a guarantee), it's parsed and executed by the JS engine every time and takes up memory afterwards.

I realize bitcoin.org isn't a web application where performance is crucial, but why load anything that isn't required? Generally, not just jQuery. Even if you have super-fast internet, last-gen processors and huge SSD drive, I'd still try to deliver the smallest payload possible.

Also, keep in mind this is version 1.11.2 which dates back to December 2014. "Old" is an understatement.

TL;DR:

  • I'd use a QR generator that's has no dependencies. If not complicated, I'd do this at build time rather than each time a users opens bitcoin.org.
  • I'd use CSS animations and tricks like forcing repaints or requestAnimationFrame / setInterval. It's just a div sliding down after all.
  • For XHR, I'd use the lightest possible wrapper for XMLHttpRequest object I could find, unless bitcoin.org already has one (which isn't jQuery).
  • DOM "interrogation" hasn't required jQuery since IE8, just use native methods.

However, if you guys still want to keep jQuery, at the very least update it to latest.

@kuzzmi

kuzzmi Aug 6, 2017 edited

Contributor

Also, keep in mind this is version 1.11.2 which dates back to December 2014. "Old" is an understatement.

The "old" jQuery is sitting in the repository for two years. It makes absolute sense to upgrade it, however it's out of scope of this PR. And feel free to open a PR with a newer version, this will be highly appreciated.

I'd still try to deliver the smallest payload possible.

That's great! Good for you and I'm all in. Furthermore I totally agree with each point that you raised (except requestAnimationFrame and setInterval for the animations, they are just simple CSS transitions).

TL;DR:

  • No doubts there are a lot of things that can be optimized and you always can open a separate PR aside/later to address those issues and do what.
  • The work done here is basically just working with what is already present in the repository.

Agree, QR generator could be used without jQuery and DOM modifications could be done with native document and node methods.

If anybody else has the same concerns about performance and minimal footprint of the website, it won't be hard to get rid of jQuery.

_includes/layout/base/html-head.html
@@ -16,6 +16,8 @@
{% if page.lang == 'bg' or page.lang == 'el' or page.lang == 'ko' or page.lang == 'hi' or page.lang == 'pl' or page.lang == 'sl' or page.lang == 'ro' or page.lang == 'ru' or page.lang == 'tr' or page.lang == 'uk' or page.lang == 'zh_CN' or page.lang == 'zh_TW' %}<link rel="stylesheet" href="/css/sans.css">{% endif %}
<script type="text/javascript" src="/js/base.js"></script>
{% if page.id != 'download' %}<script type="text/javascript" src="/js/main.js"></script>{% endif %}
+<script src="/js/jquery/jquery-1.11.2.min.js"></script>
+<script src="/js/jquery.qrcode.min.js"></script>
@Francisc

Francisc Aug 5, 2017

Why not generate QR code at build time rather than every time the modal is opened?
Would spare an extra dependency too.

@kuzzmi

kuzzmi Aug 6, 2017 edited

Contributor

QR code is regenerated anytime a user selects a sum, and/or enters a message. This can be removed, however there will be no need for quick donation buttons, and for neither custom amount input, nor optional message input. In the end the donation window will contain only static QR code and address.

If this is what we want to show people - a boring modal window, then jQuery and QR code generation and appropriate code can be removed.

@Cobra-Bitcoin

Cobra-Bitcoin Aug 6, 2017

Contributor

I think the interactive way with the QR code being regenerated each time is much better and more likely to produce better results. No need to change anything.

@Francisc

Francisc Aug 6, 2017

Fair point, I thought the QR code was static.

+ <p>
+ {% translate donation-banner-text layout %}
+ </p>
+ <button class="donation-btn" onclick="openDonationModal()">
@Francisc

Francisc Aug 5, 2017 edited

Please add type="button" so that it does not default to a submit button.

+ other occurrences in code below.

@kuzzmi

kuzzmi Aug 6, 2017

Contributor

type="button" is needed in the forms, otherwise it will default to a submit type and submit a form. In the modal <form> is not needed, thus not used, therefore type="button" not needed either.

@Francisc

Francisc Aug 6, 2017

Actually, type submit is required in forms since they are the only element for which a submit action makes sense.
Outside of forms, buttons should be just buttons.
Internet Explorer (10- or 9-) will trigger the first submit button found in DOM when pressing enter in an input that is outside of a form.

@kuzzmi

kuzzmi Aug 6, 2017

Contributor

Agree, this is addressed in the additional commit.

+ </p>
+ <button class="donation-btn" onclick="openDonationModal()">
+ {% translate donation-banner-donate-button layout %}
+ </button>
@Francisc

Francisc Aug 5, 2017

Is it common to have onclick handlers for bitcoin.org?

@kuzzmi

kuzzmi Aug 6, 2017

Contributor

Yes, it's used in a handful of pages and in this scenario is used as an entry point for loading BTC/USD rates and setting up event handlers.

+ </div>
+ <div class="donation-visibility-toggle" onclick="toggleDonationBanner()">
+ {% translate donation-banner-toggle-button layout %}
+ </div>
@Francisc

Francisc Aug 5, 2017 edited

Please use a button element. It enables keyboard navigation, screen readers handle it properly and is generally semantically correct.

@kuzzmi

kuzzmi Aug 6, 2017

Contributor

Agree, will update. Don't know why I didn't use it in a first place.

+
+<div
+ id="donation-modal"
+ style="display: none"
@Francisc

Francisc Aug 5, 2017

Are style attributes common for bitcoin.org?
Otherwise, classes are the way to go.

+ <div class="modal-body bg-white" style="overflow-y:hidden;text-align: center;">
+ <div>
+ {% for amount in site.donation_banner.amounts_in_usd %}
+ <button class="donation-amount-btn" data-amount-usd="{{ amount }}">
@Francisc

Francisc Aug 5, 2017

Please set type="button".

@kuzzmi

kuzzmi Aug 6, 2017

Contributor

See comment above regarding type="button".

_sass/_donation-banner.scss
@@ -0,0 +1,160 @@
+.donation-btn {
+ background-color: #4CAF50;
+ background-image: -webkit-linear-gradient(bottom, #318f20 14%, #4cad2c 70%);
@Francisc

Francisc Aug 5, 2017 edited

Missing other vendor prefixes and non-prefixed version.

+ other occurrences in code below.

_sass/_donation-banner.scss
+ border-radius: 10px;
+ padding: 10px 20px;
+ color: white;
+ font-weight: 600;
@Francisc

Francisc Aug 5, 2017 edited

Just use bold (or 700). 600 probably doesn't exist and browsers will approximate to bold, or worse, try to improvise the weight.

_sass/_donation-banner.scss
+}
+
+.donation-modal {
+/* display: block; */
@Francisc

Francisc Aug 5, 2017

This should probably be removed.

+
+ amountBtc = parseFloat(amountBtc);
+
+ if (!isNaN(amountBtc)) {
@Francisc

Francisc Aug 5, 2017 edited

Check that amountBtc is a number first.
For example, isNaN('') returns false because it first tries to convert to number, than checks NaN.
Alternatively, depending on baseline browser support, use Number.isNaN().
Some comment for a few other places below.

Also, should there be a >0 check?

@kuzzmi

kuzzmi Aug 6, 2017

Contributor

Check that amountBtc is a number first.
For example, isNaN('') returns false because it first tries to convert to number, than checks NaN.

A check for being a number is already done using parseFloat:

amountBtc = parseFloat('') // NaN
isNaN(amountBtc) // true

> 0 check is not really necessary as this transaction doesn't make sense. As I will make a few changes, I'll add it.

@Francisc

Francisc Aug 6, 2017

I missed the parseFloat() statement, sorry about that.
The greater than 0 checks is useful in protecting users from themselves. :)

js/main.js
+ generateDonationQrCode();
+ });
+
+ $('#donation-input-amount-btc').on('keyup', function() {
@Francisc

Francisc Aug 5, 2017

I'd use input event to cover paste operations.

@kuzzmi

kuzzmi Aug 6, 2017

Contributor

Makes sense, thank you!

@@ -582,6 +582,14 @@ collections:
platforms:
output: false
+donation_banner:
+ address: 1GwV7fPX97hmavc6iNrUZUogmjpLPrPFoE
+ display: true
@Francisc

Francisc Aug 5, 2017

This should also be used for conditionally loading other files (e.g. in index.html).

@kuzzmi

kuzzmi Aug 6, 2017

Contributor

Agree, will update a template to use/ignore additional files.

Contributor

Cobra-Bitcoin commented Aug 6, 2017

Looks really good so far, should be ready to be merged soon. Test should pass once you force JSHint to ignore the jQuery files, similar to what was done here.

Contributor

kuzzmi commented Aug 6, 2017

Thank you. Moving a jQuery QR generator to /js/jquery helped with passing JSHint.

Contributor

wbnns commented Aug 6, 2017

Here's a live preview for anyone who wants to check it out:
https://bitcoin.cryptopelago.com/

Francisc commented Aug 6, 2017

Checked out the live preview and it looks nice.
Good job, @kuzzmi.

_sass/_donation-banner.scss
+ &.expanded {
+ margin-top: 0;
+ border-bottom: 4px solid #ef9e5b;
+ box-shadow: 0 5px 10px rgba(0, 0, 0, 0.22);
@Francisc

Francisc Aug 6, 2017

I'd offset the shadow 2px lower, in the live preview you can (barely) see the shadow of the pulldown over the expanded banner.

@kuzzmi

kuzzmi Aug 6, 2017

Contributor

Good catch! Done.

Contributor

Mirobit commented Aug 6, 2017 edited

@kuzzmi Looks great.

Some suggestions:

  • The description for the textarea should be changed. The message doesn't reach bitcoin.org. It is only for the user's wallet.
  • Do we need the collapsible bar? Why not just open the pop up directly. There could be a container with the same text on the top part of the donation pop up.
  • Not sure about this, but we could have a "Donated" checkbox that users can check after they donated. This creats a cookie that prevents the notice from beeing shown to the user.
Contributor

wbnns commented Aug 6, 2017

Let's avoid pop ups. I think it's OK to have it collapsed in the current state.

People just won't click to open/reopen it if they've already donated (or aren't interested).

Contributor

kuzzmi commented Aug 6, 2017

@Mirobit:

The description for the textarea should be changed. The message doesn't reach bitcoin.org. It is only for the user's wallet.

Totally agree, addressed this in a separate commit.

I also included Ukrainian and Russian translations for the bar and modal.

Contributor

Cobra-Bitcoin commented Aug 6, 2017

Unless others object, this will be merged Monday 7th August.

@wbnns wbnns merged commit 6f770b3 into bitcoin-dot-org:master Aug 7, 2017

1 check passed

continuous-integration/travis-ci/pr The Travis CI build passed
Details

@kuzzmi kuzzmi deleted the kuzzmi:feature-donation branch Aug 7, 2017

Contributor

wbnns commented Aug 7, 2017

@kuzzmi Thanks for all of the work on this. Here's the transaction confirmation for the bounty.

Contributor

kuzzmi commented Aug 7, 2017

@wbnns Thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment