Skip to content

Commit

Permalink
Add spotify footer for docs
Browse files Browse the repository at this point in the history
  • Loading branch information
nusantara-self committed Feb 19, 2024
1 parent f70c888 commit 97cb340
Show file tree
Hide file tree
Showing 11 changed files with 254 additions and 0 deletions.
3 changes: 3 additions & 0 deletions docusaurus.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,9 @@ const config = {
darkTheme: darkCodeTheme,
},
metadata: [{ name: 'keywords', content: 'tech, cybersecurity, cloud, travel, fabien bloume, gcp, thehive, shuffle' }],
customFields: {
spotifyTrackUrl: 'https://open.spotify.com/embed/track/4GKSQD4lm08ORPorzi2wOb',
},
}),
};

Expand Down
40 changes: 40 additions & 0 deletions src/components/ConditionalSpotifyIframe.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import React from 'react';
import { useLocation } from '@docusaurus/router';
import { useThemeConfig } from '@docusaurus/theme-common';

const SpotifyIframe = ({ modifiedTrackUrl }) => (
<div>
<iframe
style={{ borderRadius: '14px', width: '33%', height: '80px' }}
src={modifiedTrackUrl}
frameBorder="0"
allowFullScreen=""
allow="autoplay; clipboard-write; encrypted-media; fullscreen; picture-in-picture"
loading="lazy"
></iframe>
</div>
);


const ConditionalSpotifyIframe = () => {
const location = useLocation();

const {customFields} = useThemeConfig();
if (!customFields) {
return null;
}
const trackUrl = customFields.spotifyTrackUrl;

// Append spotify theme & generator to the trackUrl
const modifiedTrackUrl = trackUrl + '?utm_source=generator&theme=0';

// Check if the current path starts with /docs
if (location.pathname.startsWith('/docs')) {
return <SpotifyIframe modifiedTrackUrl={modifiedTrackUrl}/>;
}

// Return null if not on a /docs page
return null;
};

export default ConditionalSpotifyIframe;
11 changes: 11 additions & 0 deletions src/theme/Footer/Copyright/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import React from 'react';
export default function FooterCopyright({copyright}) {
return (
<div
className="footer__copyright"
// Developer provided the HTML, so assume it's safe.
// eslint-disable-next-line react/no-danger
dangerouslySetInnerHTML={{__html: copyright}}
/>
);
}
29 changes: 29 additions & 0 deletions src/theme/Footer/Layout/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import React from 'react';
import clsx from 'clsx';
import ConditionalSpotifyIframe from '../../../components/ConditionalSpotifyIframe';


export default function FooterLayout({style, links, logo, copyright}) {
return (
<footer
className={clsx('footer', {
'footer--dark': style === 'dark',
})}>
<div className="footer__spotify-embed" style={{ textAlign: 'center', marginTop: '0'}}>
<ConditionalSpotifyIframe />
</div>
<div className="footer__bottom text--center">
{copyright}
</div>
{/* <div className="container container-fluid" >
{links}
{(logo || copyright) && (
<div className="footer__bottom text--center">
{logo && <div className="margin-bottom--sm">{logo}</div>}
{copyright}
</div>
)}
</div> */}
</footer>
);
}
25 changes: 25 additions & 0 deletions src/theme/Footer/LinkItem/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import React from 'react';
import Link from '@docusaurus/Link';
import useBaseUrl from '@docusaurus/useBaseUrl';
import isInternalUrl from '@docusaurus/isInternalUrl';
import IconExternalLink from '@theme/Icon/ExternalLink';
export default function FooterLinkItem({item}) {
const {to, href, label, prependBaseUrlToHref, ...props} = item;
const toUrl = useBaseUrl(to);
const normalizedHref = useBaseUrl(href, {forcePrependBaseUrl: true});
return (
<Link
className="footer__link-item"
{...(href
? {
href: prependBaseUrlToHref ? normalizedHref : href,
}
: {
to: toUrl,
})}
{...props}>
{label}
{href && !isInternalUrl(href) && <IconExternalLink />}
</Link>
);
}
37 changes: 37 additions & 0 deletions src/theme/Footer/Links/MultiColumn/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import React from 'react';
import LinkItem from '@theme/Footer/LinkItem';
function ColumnLinkItem({item}) {
return item.html ? (
<li
className="footer__item"
// Developer provided the HTML, so assume it's safe.
// eslint-disable-next-line react/no-danger
dangerouslySetInnerHTML={{__html: item.html}}
/>
) : (
<li key={item.href ?? item.to} className="footer__item">
<LinkItem item={item} />
</li>
);
}
function Column({column}) {
return (
<div className="col footer__col">
<div className="footer__title">{column.title}</div>
<ul className="footer__items clean-list">
{column.items.map((item, i) => (
<ColumnLinkItem key={i} item={item} />
))}
</ul>
</div>
);
}
export default function FooterLinksMultiColumn({columns}) {
return (
<div className="row footer__links">
{columns.map((column, i) => (
<Column key={i} column={column} />
))}
</div>
);
}
31 changes: 31 additions & 0 deletions src/theme/Footer/Links/Simple/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import React from 'react';
import LinkItem from '@theme/Footer/LinkItem';
function Separator() {
return <span className="footer__link-separator">·</span>;
}
function SimpleLinkItem({item}) {
return item.html ? (
<span
className="footer__link-item"
// Developer provided the HTML, so assume it's safe.
// eslint-disable-next-line react/no-danger
dangerouslySetInnerHTML={{__html: item.html}}
/>
) : (
<LinkItem item={item} />
);
}
export default function FooterLinksSimple({links}) {
return (
<div className="footer__links text--center">
<div className="footer__links">
{links.map((item, i) => (
<React.Fragment key={i}>
<SimpleLinkItem item={item} />
{links.length !== i + 1 && <Separator />}
</React.Fragment>
))}
</div>
</div>
);
}
11 changes: 11 additions & 0 deletions src/theme/Footer/Links/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import React from 'react';
import {isMultiColumnFooterLinks} from '@docusaurus/theme-common';
import FooterLinksMultiColumn from '@theme/Footer/Links/MultiColumn';
import FooterLinksSimple from '@theme/Footer/Links/Simple';
export default function FooterLinks({links}) {
return isMultiColumnFooterLinks(links) ? (
<FooterLinksMultiColumn columns={links} />
) : (
<FooterLinksSimple links={links} />
);
}
35 changes: 35 additions & 0 deletions src/theme/Footer/Logo/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import React from 'react';
import clsx from 'clsx';
import Link from '@docusaurus/Link';
import {useBaseUrlUtils} from '@docusaurus/useBaseUrl';
import ThemedImage from '@theme/ThemedImage';
import styles from './styles.module.css';
function LogoImage({logo}) {
const {withBaseUrl} = useBaseUrlUtils();
const sources = {
light: withBaseUrl(logo.src),
dark: withBaseUrl(logo.srcDark ?? logo.src),
};
return (
<ThemedImage
className={clsx('footer__logo', logo.className)}
alt={logo.alt}
sources={sources}
width={logo.width}
height={logo.height}
style={logo.style}
/>
);
}
export default function FooterLogo({logo}) {
return logo.href ? (
<Link
href={logo.href}
className={styles.footerLogoLink}
target={logo.target}>
<LogoImage logo={logo} />
</Link>
) : (
<LogoImage logo={logo} />
);
}
9 changes: 9 additions & 0 deletions src/theme/Footer/Logo/styles.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
.footerLogoLink {
opacity: 0.5;
transition: opacity var(--ifm-transition-fast)
var(--ifm-transition-timing-default);
}

.footerLogoLink:hover {
opacity: 1;
}
23 changes: 23 additions & 0 deletions src/theme/Footer/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import React from 'react';
import {useThemeConfig} from '@docusaurus/theme-common';
import FooterLinks from '@theme/Footer/Links';
import FooterLogo from '@theme/Footer/Logo';
import FooterCopyright from '@theme/Footer/Copyright';
import FooterLayout from '@theme/Footer/Layout';

function Footer() {
const {footer} = useThemeConfig();
if (!footer) {
return null;
}
const {copyright, links, logo, style} = footer;
return (
<FooterLayout
style={style}
links={links && links.length > 0 && <FooterLinks links={links} />}
logo={logo && <FooterLogo logo={logo} />}
copyright={copyright && <FooterCopyright copyright={copyright} />}
/>
);
}
export default React.memo(Footer);

0 comments on commit 97cb340

Please sign in to comment.