Sort Links (#48)

* feat(Sort): Added BUTTON_ORDER, a list of buttons to boost

* feat(Sort): Added examples and docs

* fix(README): Updated service name
This commit is contained in:
Techno Tim 2021-10-17 21:38:08 -05:00 committed by GitHub
parent c10a020ec2
commit 3bf4af85e8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 379 additions and 301 deletions

View File

@ -25,3 +25,4 @@ RAZZLE_FOOTER=Thanks for stopping by!
RAZZLE_GA_TRACKING_ID=G-XXXXXXXXXX RAZZLE_GA_TRACKING_ID=G-XXXXXXXXXX
RAZZLE_UMAMI_WEBSITE_ID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx RAZZLE_UMAMI_WEBSITE_ID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
RAZZLE_UMAMI_APP_URL=https://your-umami-app.com RAZZLE_UMAMI_APP_URL=https://your-umami-app.com
RAZZLE_BUTTON_ORDER=YOUTUBE,TWITCH,TWITTER,GITHUB,INSTAGRAM,DISCORD,FACEBOOK,TIKTOK,KIT,PATREON

View File

@ -51,7 +51,7 @@ This container image is published on both [GitHub Container Registry](https://gi
--- ---
version: "3.0" version: "3.0"
services: services:
little-link: littlelink-server:
image: ghcr.io/techno-tim/littlelink-server:latest image: ghcr.io/techno-tim/littlelink-server:latest
# dockerhub is also supported timothystewart6/littlelink-server # dockerhub is also supported timothystewart6/littlelink-server
#image: timothystewart6/littlelink-server:latest #image: timothystewart6/littlelink-server:latest
@ -112,6 +112,7 @@ services:
- DEVTO=https://dev.to/ - DEVTO=https://dev.to/
- UMAMI_WEBSITE_ID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx - UMAMI_WEBSITE_ID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
- UMAMI_APP_URL=https://your-umami-app.com - UMAMI_APP_URL=https://your-umami-app.com
- BUTTON_ORDER=YOUTUBE,TWITCH,TWITTER,GITHUB,INSTAGRAM,DISCORD,FACEBOOK,TIKTOK,KIT,PATREON # use ENV variable names for order
ports: ports:
- 8080:3000 - 8080:3000
restart: unless-stopped restart: unless-stopped

View File

@ -65,6 +65,7 @@ services:
- DEVTO=https://dev.to/ - DEVTO=https://dev.to/
- UMAMI_WEBSITE_ID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx - UMAMI_WEBSITE_ID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
- UMAMI_APP_URL=https://your-umami-app.com - UMAMI_APP_URL=https://your-umami-app.com
- BUTTON_ORDER=YOUTUBE,TWITCH,TWITTER,GITHUB,INSTAGRAM,DISCORD,FACEBOOK,TIKTOK,KIT,PATREON
ports: ports:
- 8080:3000 - 8080:3000

View File

@ -105,7 +105,7 @@ button:hover,
} }
/* Facebook Messenger */ /* Facebook Messenger */
.button.button-messenger { .button.button-facebookmessenger {
color: #ffffff; color: #ffffff;
background-image: linear-gradient( background-image: linear-gradient(
25deg, 25deg,
@ -117,8 +117,8 @@ button:hover,
#ff7061 #ff7061
); );
} }
.button.button-messenger:hover, .button.button-facebookmessenger:hover,
.button.button-messenger:focus { .button.button-facebookmessenger:focus {
filter: brightness(90%); filter: brightness(90%);
} }

View File

@ -1,5 +1,5 @@
import React, { memo } from 'react'; import React, { memo } from 'react';
import { string } from 'prop-types'; import { string, number } from 'prop-types';
import { trackGoogleEvent } from '../../analytics/google'; import { trackGoogleEvent } from '../../analytics/google';
import { runtimeConfig } from '../../config'; import { runtimeConfig } from '../../config';
import { trackUmamiEvent } from '../../analytics/umami'; import { trackUmamiEvent } from '../../analytics/umami';
@ -45,4 +45,5 @@ Button.propType = {
alt: string.isRequired, alt: string.isRequired,
href: string, href: string,
name: string, name: string,
order: number,
}; };

View File

@ -39,8 +39,18 @@ import buyMeACoffeeLogo from '../../icons/buymeacoffee.svg';
import gitlabLogo from '../../icons/gitlab.svg'; import gitlabLogo from '../../icons/gitlab.svg';
import patreonLogo from '../../icons/patreon.svg'; import patreonLogo from '../../icons/patreon.svg';
import devtoLogo from '../../icons/devto.svg'; import devtoLogo from '../../icons/devto.svg';
import Sort from '../Sort/Sort';
function Home(props) { function Home(props) {
let order = [];
if (runtimeConfig?.BUTTON_ORDER) {
order = runtimeConfig.BUTTON_ORDER.split(',').reverse();
}
const buttonOrder = button => {
return order.indexOf(button);
};
return ( return (
<> <>
<div className="container"> <div className="container">
@ -53,309 +63,348 @@ function Home(props) {
/> />
<h1>{`${runtimeConfig.NAME}`}</h1> <h1>{`${runtimeConfig.NAME}`}</h1>
<p>{runtimeConfig.BIO}</p> <p>{runtimeConfig.BIO}</p>
{runtimeConfig.YOUTUBE && ( <Sort>
<Button {runtimeConfig.YOUTUBE && (
name="youtube" <Button
href={runtimeConfig.YOUTUBE} name="youtube"
displayName="YouTube" href={runtimeConfig.YOUTUBE}
logo={youtubeLogo} displayName="YouTube"
/> logo={youtubeLogo}
)} order={buttonOrder('YOUTUBE')}
{runtimeConfig.TWITCH && ( />
<Button )}
name="twitch" {runtimeConfig.TWITCH && (
href={runtimeConfig.TWITCH} <Button
displayName="Twitch" name="twitch"
logo={twitchLogo} href={runtimeConfig.TWITCH}
/> displayName="Twitch"
)} logo={twitchLogo}
{runtimeConfig.TWITTER && ( order={buttonOrder('TWITCH')}
<Button />
name="twitter" )}
href={runtimeConfig.TWITTER} {runtimeConfig.TWITTER && (
displayName="Twitter" <Button
logo={twitterLogo} name="twitter"
/> href={runtimeConfig.TWITTER}
)} displayName="Twitter"
{runtimeConfig.INSTAGRAM && ( logo={twitterLogo}
<Button order={buttonOrder('TWITTER')}
name="instagram" />
href={runtimeConfig.INSTAGRAM} )}
displayName="Instagram" {runtimeConfig.INSTAGRAM && (
logo={instagramLogo} <Button
/> name="instagram"
)} href={runtimeConfig.INSTAGRAM}
{runtimeConfig.GITHUB && ( displayName="Instagram"
<Button logo={instagramLogo}
name="github" order={buttonOrder('INSTAGRAM')}
href={runtimeConfig.GITHUB} />
displayName="GitHub" )}
logo={githubLogo} {runtimeConfig.GITHUB && (
/> <Button
)} name="github"
href={runtimeConfig.GITHUB}
displayName="GitHub"
logo={githubLogo}
order={buttonOrder('GITHUB')}
/>
)}
{runtimeConfig.DISCORD && ( {runtimeConfig.DISCORD && (
<Button <Button
name="discord" name="discord"
href={runtimeConfig.DISCORD} href={runtimeConfig.DISCORD}
displayName="Discord" displayName="Discord"
logo={discordLogo} logo={discordLogo}
/> order={buttonOrder('DISCORD')}
)} />
)}
{runtimeConfig.TIKTOK && ( {runtimeConfig.TIKTOK && (
<Button <Button
name="tiktok" name="tiktok"
href={runtimeConfig.TIKTOK} href={runtimeConfig.TIKTOK}
displayName="TikTok" displayName="TikTok"
logo={tiktokLogo} logo={tiktokLogo}
/> order={buttonOrder('TIKTOK')}
)} />
{runtimeConfig.FACEBOOK && ( )}
<Button {runtimeConfig.FACEBOOK && (
name="facebook" <Button
href={runtimeConfig.FACEBOOK} name="facebook"
displayName="Facebook" href={runtimeConfig.FACEBOOK}
logo={facebookLogo} displayName="Facebook"
/> logo={facebookLogo}
)} order={buttonOrder('FACEBOOK')}
{runtimeConfig.FACEBOOK_MESSENGER && ( />
<Button )}
name="messenger" {runtimeConfig.FACEBOOK_MESSENGER && (
href={runtimeConfig.FACEBOOK_MESSENGER} <Button
displayName="Messenger" name="facebookmessenger"
logo={messengerLogo} href={runtimeConfig.FACEBOOK_MESSENGER}
/> displayName="Messenger"
)} logo={messengerLogo}
{runtimeConfig.LINKED_IN && ( order={buttonOrder('FACEBOOK_MESSENGER')}
<Button />
name="linkedin" )}
href={runtimeConfig.LINKED_IN} {runtimeConfig.LINKED_IN && (
displayName="LinkedIn" <Button
logo={linkedinLogo} name="linkedin"
/> href={runtimeConfig.LINKED_IN}
)} displayName="LinkedIn"
{runtimeConfig.PRODUCT_HUNT && ( logo={linkedinLogo}
<Button order={buttonOrder('LINKED_IN')}
name="producthunt" />
href={runtimeConfig.PRODUCT_HUNT} )}
displayName="Product Hunt" {runtimeConfig.PRODUCT_HUNT && (
logo={producthuntLogo} <Button
/> name="producthunt"
)} href={runtimeConfig.PRODUCT_HUNT}
{runtimeConfig.SNAPCHAT && ( displayName="Product Hunt"
<Button logo={producthuntLogo}
name="snapchat" order={buttonOrder('PRODUCT_HUNT')}
href={runtimeConfig.SNAPCHAT} />
displayName="SnapChat" )}
logo={snapchatLogo} {runtimeConfig.SNAPCHAT && (
/> <Button
)} name="snapchat"
{runtimeConfig.SPOTIFY && ( href={runtimeConfig.SNAPCHAT}
<Button displayName="SnapChat"
name="spotify" logo={snapchatLogo}
href={runtimeConfig.SPOTIFY} order={buttonOrder('SNAPCHAT')}
displayName="Spotify" />
logo={spotifyLogo} )}
/> {runtimeConfig.SPOTIFY && (
)} <Button
{runtimeConfig.REDDIT && ( name="spotify"
<Button href={runtimeConfig.SPOTIFY}
name="reddit" displayName="Spotify"
href={runtimeConfig.REDDIT} logo={spotifyLogo}
displayName="Reddit" order={buttonOrder('SPOTIFY')}
logo={redditLogo} />
/> )}
)} {runtimeConfig.REDDIT && (
{runtimeConfig.MEDIUM && ( <Button
<Button name="reddit"
name="medium" href={runtimeConfig.REDDIT}
href={runtimeConfig.MEDIUM} displayName="Reddit"
displayName="Medium" logo={redditLogo}
logo={mediumLogo} order={buttonOrder('REDDIT')}
/> />
)} )}
{runtimeConfig.PINTEREST && ( {runtimeConfig.MEDIUM && (
<Button <Button
name="pinterest" name="medium"
href={runtimeConfig.PINTEREST} href={runtimeConfig.MEDIUM}
displayName="Pinterest" displayName="Medium"
logo={pinterestLogo} logo={mediumLogo}
/> order={buttonOrder('MEDIUM')}
)} />
{runtimeConfig.EMAIL && ( )}
<Button {runtimeConfig.PINTEREST && (
name="default" <Button
href={`mailto:${runtimeConfig.EMAIL}`} name="pinterest"
displayName={runtimeConfig.EMAIL_TEXT} href={runtimeConfig.PINTEREST}
logo={emailLogo} displayName="Pinterest"
/> logo={pinterestLogo}
)} order={buttonOrder('PINTEREST')}
/>
)}
{runtimeConfig.EMAIL && (
<Button
name="default"
href={`mailto:${runtimeConfig.EMAIL}`}
displayName={runtimeConfig.EMAIL_TEXT}
logo={emailLogo}
order={buttonOrder('EMAIL')}
/>
)}
{runtimeConfig.EMAIL_ALT && ( {runtimeConfig.EMAIL_ALT && (
<Button <Button
name="default" name="default"
href={`mailto:${runtimeConfig.EMAIL_ALT}`} href={`mailto:${runtimeConfig.EMAIL_ALT}`}
displayName={runtimeConfig.EMAIL_ALT_TEXT} displayName={runtimeConfig.EMAIL_ALT_TEXT}
logo={emailAltLogo} logo={emailAltLogo}
/> order={buttonOrder('EMAIL_ALT')}
)} />
)}
{runtimeConfig.SOUND_CLOUD && ( {runtimeConfig.SOUND_CLOUD && (
<Button <Button
name="soundcloud" name="soundcloud"
href={runtimeConfig.SOUND_CLOUD} href={runtimeConfig.SOUND_CLOUD}
displayName="SoundCloud" displayName="SoundCloud"
logo={soundcloudLogo} logo={soundcloudLogo}
/> order={buttonOrder('SOUND_CLOUD')}
)} />
{runtimeConfig.FIGMA && ( )}
<Button {runtimeConfig.FIGMA && (
name="figma" <Button
href={runtimeConfig.FIGMA} name="figma"
displayName="Figma" href={runtimeConfig.FIGMA}
logo={figmaLogo} displayName="Figma"
/> logo={figmaLogo}
)} order={buttonOrder('FIGMA')}
/>
)}
{runtimeConfig.TELEGRAM && ( {runtimeConfig.TELEGRAM && (
<Button <Button
name="telegram" name="telegram"
href={runtimeConfig.TELEGRAM} href={runtimeConfig.TELEGRAM}
displayName="Telegram" displayName="Telegram"
logo={telegramLogo} logo={telegramLogo}
/> order={buttonOrder('TELEGRAM')}
)} />
)}
{runtimeConfig.TUMBLR && ( {runtimeConfig.TUMBLR && (
<Button <Button
name="tumblr" name="tumblr"
href={runtimeConfig.TUMBLR} href={runtimeConfig.TUMBLR}
displayName="Tumblr" displayName="Tumblr"
logo={tumblrLogo} logo={tumblrLogo}
/> order={buttonOrder('TUMBLR')}
)} />
{runtimeConfig.STEAM && ( )}
<Button {runtimeConfig.STEAM && (
name="steam" <Button
href={runtimeConfig.STEAM} name="steam"
displayName="Steam" href={runtimeConfig.STEAM}
logo={steamLogo} displayName="Steam"
/> logo={steamLogo}
)} order={buttonOrder('STEAM')}
/>
)}
{runtimeConfig.VIMEO && ( {runtimeConfig.VIMEO && (
<Button <Button
name="vimeo" name="vimeo"
href={runtimeConfig.VIMEO} href={runtimeConfig.VIMEO}
displayName="Vimeo" displayName="Vimeo"
logo={vimeoLogo} logo={vimeoLogo}
/> order={buttonOrder('VIMEO')}
)} />
{runtimeConfig.WORDPRESS && ( )}
<Button {runtimeConfig.WORDPRESS && (
name="wordpress" <Button
href={runtimeConfig.WORDPRESS} name="wordpress"
displayName="Wordpress" href={runtimeConfig.WORDPRESS}
logo={wordpressLogo} displayName="Wordpress"
/> logo={wordpressLogo}
)} order={buttonOrder('WORDPRESS')}
{runtimeConfig.GOODREADS && ( />
<Button )}
name="goodreads" {runtimeConfig.GOODREADS && (
href={runtimeConfig.GOODREADS} <Button
displayName="Goodreads" name="goodreads"
logo={goodreadsLogo} href={runtimeConfig.GOODREADS}
/> displayName="Goodreads"
)} logo={goodreadsLogo}
{runtimeConfig.SKOOB && ( order={buttonOrder('GOODREADS')}
<Button />
name="skoob" )}
href={runtimeConfig.SKOOB} {runtimeConfig.SKOOB && (
displayName="Skoob" <Button
logo={skoobLogo} name="skoob"
/> href={runtimeConfig.SKOOB}
)} displayName="Skoob"
{runtimeConfig.LETTERBOXD && ( logo={skoobLogo}
<Button order={buttonOrder('SKOOB')}
name="letterboxd" />
href={runtimeConfig.LETTERBOXD} )}
displayName="LetterBoxd" {runtimeConfig.LETTERBOXD && (
logo={letterboxdLogo} <Button
/> name="letterboxd"
)} href={runtimeConfig.LETTERBOXD}
{runtimeConfig.MASTODON && ( displayName="LetterBoxd"
<Button logo={letterboxdLogo}
name="mastodon" order={buttonOrder('LETTERBOXD')}
href={runtimeConfig.MASTODON} />
displayName="Mastodon" )}
logo={mastodonLogo} {runtimeConfig.MASTODON && (
/> <Button
)} name="mastodon"
{runtimeConfig.MICRO_BLOG && ( href={runtimeConfig.MASTODON}
<Button displayName="Mastodon"
name="microblog" logo={mastodonLogo}
href={runtimeConfig.MICRO_BLOG} order={buttonOrder('MASTODON')}
displayName="Microblog" />
logo={microblogLogo} )}
/> {runtimeConfig.MICRO_BLOG && (
)} <Button
{runtimeConfig.WHATSAPP && ( name="microblog"
<Button href={runtimeConfig.MICRO_BLOG}
name="whatsapp" displayName="Microblog"
href={runtimeConfig.WHATSAPP} logo={microblogLogo}
displayName="WhatsApp" order={buttonOrder('MICRO_BLOG')}
logo={whatsappLogo} />
/> )}
)} {runtimeConfig.WHATSAPP && (
{runtimeConfig.KIT && ( <Button
<Button name="whatsapp"
name="kit" href={runtimeConfig.WHATSAPP}
href={runtimeConfig.KIT} displayName="WhatsApp"
displayName="Kit" logo={whatsappLogo}
logo={kitLogo} order={buttonOrder('WHATSAPP')}
/> />
)} )}
{runtimeConfig.STRAVA && ( {runtimeConfig.KIT && (
<Button <Button
name="strava" name="kit"
href={runtimeConfig.STRAVA} href={runtimeConfig.KIT}
displayName="Strava" displayName="Kit"
logo={stravaLogo} logo={kitLogo}
/> order={buttonOrder('KIT')}
)} />
{runtimeConfig.BUYMEACOFFEE && ( )}
<Button {runtimeConfig.STRAVA && (
name="buymeacoffee" <Button
href={runtimeConfig.BUYMEACOFFEE} name="strava"
displayName="Buy Me a Coffee" href={runtimeConfig.STRAVA}
logo={buyMeACoffeeLogo} displayName="Strava"
/> logo={stravaLogo}
)} order={buttonOrder('STRAVA')}
{runtimeConfig.GITLAB && ( />
<Button )}
name="gitlab" {runtimeConfig.BUYMEACOFFEE && (
href={runtimeConfig.GITLAB} <Button
displayName="GitLab" name="buymeacoffee"
logo={gitlabLogo} href={runtimeConfig.BUYMEACOFFEE}
/> displayName="Buy Me a Coffee"
)} logo={buyMeACoffeeLogo}
{runtimeConfig.PATREON && ( order={buttonOrder('BUYMEACOFFEE')}
<Button />
name="patreon" )}
href={runtimeConfig.PATREON} {runtimeConfig.GITLAB && (
displayName="Patreon" <Button
logo={patreonLogo} name="gitlab"
/> href={runtimeConfig.GITLAB}
)} displayName="GitLab"
{runtimeConfig.DEVTO && ( logo={gitlabLogo}
<Button order={buttonOrder('GITLAB')}
name="devto" />
href={runtimeConfig.DEVTO} )}
displayName="Dev.to" {runtimeConfig.PATREON && (
logo={devtoLogo} <Button
/> name="patreon"
)} href={runtimeConfig.PATREON}
displayName="Patreon"
logo={patreonLogo}
order={buttonOrder('PATREON')}
/>
)}
{runtimeConfig.DEVTO && (
<Button
name="devto"
href={runtimeConfig.DEVTO}
displayName="Dev.to"
logo={devtoLogo}
order={buttonOrder('DEVTO')}
/>
)}
</Sort>
<div> <div>
<p className="footer">{runtimeConfig.FOOTER}</p> <p className="footer">{runtimeConfig.FOOTER}</p>
</div> </div>

View File

@ -0,0 +1,11 @@
import React from 'react';
const Sort = ({ children }) => {
const sorted = React.Children.toArray(children).sort((a, b) => {
return b.props.order - a.props.order;
});
return sorted;
};
export default Sort;

View File

@ -0,0 +1,10 @@
import Sort from './Sort';
import React from 'react';
import ReactDOM from 'react-dom';
describe('<Sort />', () => {
test('renders without exploding', () => {
const div = document.createElement('div');
ReactDOM.render(<Sort />, div);
});
});

View File

@ -59,6 +59,7 @@ export const runtimeConfig =
DEVTO: window?.env?.DEVTO, DEVTO: window?.env?.DEVTO,
UMAMI_WEBSITE_ID: window?.env?.UMAMI_WEBSITE_ID, UMAMI_WEBSITE_ID: window?.env?.UMAMI_WEBSITE_ID,
UMAMI_APP_URL: window?.env?.UMAMI_APP_URL, UMAMI_APP_URL: window?.env?.UMAMI_APP_URL,
BUTTON_ORDER: window?.env?.BUTTON_ORDER,
} }
: { : {
// server // server
@ -205,4 +206,7 @@ export const runtimeConfig =
UMAMI_APP_URL: nodeIsProduction UMAMI_APP_URL: nodeIsProduction
? process.env.UMAMI_APP_URL ? process.env.UMAMI_APP_URL
: process.env.RAZZLE_UMAMI_APP_URL, : process.env.RAZZLE_UMAMI_APP_URL,
BUTTON_ORDER: nodeIsProduction
? process.env.BUTTON_ORDER
: process.env.BUTTON_ORDER,
}; };