-
-
Notifications
You must be signed in to change notification settings - Fork 8
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
donate button v3 that only supports crypto #141
Conversation
This pull request is being automatically deployed with Vercel (learn more). 🔍 Inspect: https://vercel.com/everydotorg/donate-button/CkLeQ8ZgaacjoccHwX8NGY1cw5ap |
b2e18bb
to
2a6eadc
Compare
2a6eadc
to
41200d8
Compare
] | ||
} | ||
], | ||
"@babel/preset-typescript" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
mostly teh same as donate-button
, but adds this line.
"xo": "^0.37.1" | ||
}, | ||
"dependencies": { | ||
"@compiled/react": "^0.6.10", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is the new thing
const {options: babelOptions, ...babelLoaderRule} = config.module.rules[0]; // Get the babel rule and options | ||
config.module.rules[0] = { | ||
...babelLoaderRule, | ||
loader: undefined, // Disable the predefined babel-loader on the rule | ||
use: [ | ||
{loader: 'babel-loader', options: babelOptions}, | ||
{loader: '@compiled/webpack-loader', options: {babelOptions}} | ||
] | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This block adds webpack support for compiled CSS in JS; the rest is same as donate-button
import constructEveryUrl from 'src/helpers/construct-every-url'; | ||
import {EmbedButtonOptions} from 'src/helpers/options-types'; | ||
|
||
const buttonCss = css` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
CSS in JS!
declare module 'preact' { | ||
interface Attributes { | ||
css?: CSSProps; | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is how we get the CSS prop to work.
export interface DonateButtonOptions { | ||
/** | ||
* Identifier for nonprofit on Every.org; you can get it by going to the | ||
* nonprofit's profile on Every.org and looking at its URL | ||
* | ||
* @example | ||
* If the URL is https://www.every.org/givedirectly, the slug is givedirectly | ||
*/ | ||
readonly nonprofitSlug: string; | ||
/** | ||
* Whether or not to render Crypto donation flow instead of the normal | ||
* donation flow | ||
* | ||
* @default false | ||
* For now, only crypto is supported | ||
*/ | ||
readonly crypto: boolean; // For now only this is supported | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is nowhere near supporting the kinds of stuff we have in donate-button
, but I wanted to keep it as minimal as possible since that one is huge. We can expand over time.
Also I cut out all the modal stuff, since for now the pressing concern is to get crypto donation embeds working, and this is the quickest way there.
readonly crypto: boolean; // For now only this is supported | ||
} | ||
|
||
export interface EmbedButtonOptions extends DonateButtonOptions { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Renamed it from GenericButton
since it's not a very descriptive name.
@@ -0,0 +1,40 @@ | |||
import {render} from 'preact'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just moved the logic for making the donate button into this file since it's so short.
everyDotOrgDonateButton?: GlobalExport; | ||
}; | ||
|
||
window.everyDotOrgDonateButton = { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is renamed since we don't call it everyMonth
anymore.
window.addEventListener("load", function() { | ||
everyDotOrgDonateButton.createButton({ | ||
selector: "#button-root", | ||
nonprofitSlug: "everydotorg", | ||
crypto: true | ||
}); | ||
}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Very basic example of what an embed would look like; the ultimate embed script would be slightly more than this:
<div id="edo-donate-btn" />
<script src="https://assets.every.org/dist/donate-button/0.3/index.js" class="edo-donate-btn-js"></script>
<script>
(() => {
const edoScript = document.querySelector(".edo-donate-btn-js")
if (!edoScript) return;
edoScript.onload = () => {
everyDotOrgDonateButton.createButton({
selector: "#edo-donate-btn",
nonprofitSlug: "everydotorg",
crypto: true
});
})
)();
</script>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM! I think this is fine for getting something up and running quickly, but I also think we can learn from TikTok here is what they do
<blockquote
class="tiktok-embed"
cite="https://www.tiktok.com/@kyliejenner/video/6951976455400099077"
data-video-id="6951976455400099077"
style="max-width: 605px; min-width: 325px"
>
<section>
<a
target="_blank"
title="@kyliejenner"
href="https://www.tiktok.com/@kyliejenner"
>@kyliejenner</a
>
<p>time goes too fast 😥😥🤍</p>
<a
target="_blank"
title="♬ original sound - sam aldridge"
href="https://www.tiktok.com/music/original-sound-6750691377606216453"
>♬ original sound - sam aldridge</a
>
</section>
</blockquote>
<script async src="https://www.tiktok.com/embed.js"></script>
Several nice things about this:
- Script is async
- Without Javascript, instantly has multiple links for PageRank - the video, the person, the music. In our case, would be great to instantly have href to the nonprofit's main page (not their donate crypto page) for pagerank purposes.
- Devs instantly know how to adjust the width without reading any documentation
- Metadata included entirely via html, makes it look a bit cleaner and more obvious what to if you have multiple embeds
- If client does not have Javascript, at least they can still get to the persons profile. In our case, would be nice if they can still get to the /donate/crypto page (though admittedly that page would then fail, but perhaps someone would be willing to explicitly enable javascript for www.every.org and not less well-known domains)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah the way I wrote the code the script can be async, I just forgot. Re the richer content I'll change it to by default not take a selector for where to make the element but attach a handler directly to a donate crypto link. Don't think we can add a whole lot more metadata though since this is supposed to be a single button, not a whole tweet or Tiktok post or something.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I made it so that the embed can be done like this:
<div class="edo-donate-btn">
<a href="https://www.every.org/givedirectly/donate/crypto">Donate Crypto</a>
</div>
<script async src="https://assets.every.org/dist/donate-button/0.3/index.js" class="edo-donate-btn-js"></script>
<script>
document.querySelector(".edo-donate-btn-js").onload = function() {
everyDotOrgDonateButton.initButtons();
};
</script>
It can be copied into the page multiple times without causing issues. We can also make the text in the link to be replaced with the button be anything - so if we want it to be Donate Crypto for GiveDirectly
or something that works too (it will be replaced with the generic "Donate Crypto" as soon as the script runs; this behavior can be changed if we want)
This new initButtons()
function just looks for all elements with the class edo-donate-btn
, and then looks for an a
element inside it; parses the href
value to extract the options to throw into the createButton()
function from before, replacing the original contents of the div with the newly created button. In the future it can be made to not just read the href
field but also anything else like data-
attributes if we want to add more configuration in the future.
The explicit version above still works, though, for programmers who want more control.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can trim down the copy paste code to remove needing to explicitly call initButtons()
as well by automatically calling initButtons()
in the downloaded script - im not in love with the automatic side effects, but it is simplest. that said if people just copy-paste this it's not that bad as is, and gives people an idea how this library can be used more flexibly, not just a magic script.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
styling will not be as direct as just styling the underlying elemetns though, since they're in a Shadow DOM to provide encapsulation from the parent page's JS/CSS context - but it's not any worse than tik tok or twitter, who load their stuff in iframe
s, which prevent meddling even more. But we can allow for width styling by setting the width of the parent div, and the createButton()
function already allows for a great deal of customization, including changing the text and colors and border radius.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is the bundle size for someone who wants to embed donate button on their site?
</svg> | ||
)} | ||
<span css={verticalCenterTextCss}> | ||
{label ? label : `Donate${donateOptions.crypto ? ' Crypto' : ''}`} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What text will this use? Ideally we want our Basis Grotesque - I'm guessing much faster for users to give them a single "[swirl] Donate Crypto" image than to download the entire Basis Grotesque font
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This uses Basis Grotesque, and I just edited it so that the fallback fonts are used first before Basis is loaded, so users will see text immediately.
I'll check but it should be less than like 5-6 kb gzipped, preact is tiny and compiled CSS in JS compiles any runtime component out of the resulting bundle. |
I replaced Compiled CSS in JS with cxs because I figured that extracing separate CSS files at all adds complexity to the build system, proper usage of the library, and doesn't really provide much value so long as the button doesn't get crazy complicated style-wise (it shouldn't). |
After replacing with |
getting late for me so i'll wrap testing this up and making the embed code for the main every.org site tomorrow |
me refreshing with no cache, showing the font transition on webfont load Screen.Recording.2021-04-19.at.23.10.24.mov |
cc @martinbianchi that i've been doing this - we wanted to get a simple donate crypto button out, trying to leverage the existing infra we have for donate button and didn't want the crypto stuff to be separate from the rest of donate button codebase. I also wanted to tackle a number of tech debt issues while doing it - so switched out the CSS stuff to if this turns out to be not a great approach - we can always hop over this can serve as a base for the new designs for the donate button once we're ready to implement them. |
I've just seen this! Amazing work @osdiab. I'll start with the new widget from here. Thanks! |
Also implements compiled CSS in JS for styles to replace CSS modules + the style injector (#77) , and starts on #73 with a fresh options format that matches our terminology and is simpler. Also removes the
docs/dist/dist
folder, which i'm pretty certain is unused.