diff options
| author | Armand Philippot <git@armandphilippot.com> | 2022-01-15 22:45:57 +0100 |
|---|---|---|
| committer | Armand Philippot <git@armandphilippot.com> | 2022-01-15 22:51:30 +0100 |
| commit | aa1ca65e7c9807c6d6020e39166536297fe1cdae (patch) | |
| tree | 2648da350fec3b71ab7f575d63e4c63ba08248b1 /src/components/Widgets/Sharing/Sharing.tsx | |
| parent | 16dbb4742264edac82fa6bb8e461259d097f4437 (diff) | |
chore: update sidebar and widgets styles
I'm now using a widget that can be expanded/collapsed. It also allows
me to handle more effectively widgets overflow and to avoid styles
repetitions.
However, with stylelint rule "no-descending-specificity", I'm not sure
if the stylesheets are really logical... Maybe I should deactivate this
rule.
Diffstat (limited to 'src/components/Widgets/Sharing/Sharing.tsx')
| -rw-r--r-- | src/components/Widgets/Sharing/Sharing.tsx | 113 |
1 files changed, 113 insertions, 0 deletions
diff --git a/src/components/Widgets/Sharing/Sharing.tsx b/src/components/Widgets/Sharing/Sharing.tsx new file mode 100644 index 0000000..bc52f9b --- /dev/null +++ b/src/components/Widgets/Sharing/Sharing.tsx @@ -0,0 +1,113 @@ +import { ExpandableWidget } from '@components/WidgetParts'; +import sharingMedia from '@config/sharing'; +import { t } from '@lingui/macro'; +import { useRouter } from 'next/router'; +import { useEffect, useState } from 'react'; +import styles from './Sharing.module.scss'; + +type Parameters = { + content: string; + image: string; + title: string; + url: string; +}; + +type Website = { + id: string; + name: string; + parameters: Parameters; + url: string; +}; + +const Sharing = ({ excerpt, title }: { excerpt: string; title: string }) => { + const [pageExcerpt, setPageExcerpt] = useState(''); + const [pageUrl, setPageUrl] = useState(''); + const [domainName, setDomainName] = useState(''); + const router = useRouter(); + + useEffect(() => { + const divEl = document.createElement('div'); + divEl.innerHTML = excerpt; + const cleanExcerpt = divEl.textContent!; + setPageExcerpt(cleanExcerpt); + }, [excerpt]); + + useEffect(() => { + const { protocol, hostname, port } = window.location; + const currentPort = port ? `:${port}` : ''; + const fullUrl = `${protocol}//${hostname}${currentPort}${router.asPath}`; + + setDomainName(hostname); + setPageUrl(fullUrl); + }, [router.asPath]); + + const getSharingUrl = (website: Website): string => { + const { id, parameters, url } = website; + let sharingUrl = `${url}?`; + let count = 0; + + for (const [key, value] of Object.entries(parameters)) { + if (!value) continue; + + sharingUrl += count > 0 ? `&${value}=` : `${value}=`; + + switch (key) { + case 'content': + if (id === 'email') { + const intro = t`Introduction:`; + const readMore = t`Read more here:`; + const body = `${intro}\n\n"${pageExcerpt}"\n\n${readMore} ${pageUrl}`; + sharingUrl += encodeURI(body); + } else { + sharingUrl += encodeURI(pageExcerpt); + } + break; + case 'title': + const prefix = id === 'email' ? t`Seen on ${domainName}:` : ''; + sharingUrl += encodeURI(`${prefix} ${title}`); + break; + case 'url': + sharingUrl += encodeURI(pageUrl); + break; + default: + break; + } + + count++; + } + + return sharingUrl; + }; + + const getItems = () => { + const websites: Website[] = sharingMedia; + + return websites.map((website) => { + const { id, name } = website; + const sharingUrl = getSharingUrl(website); + const linkModifier = `link--${id}`; + + return ( + <li key={id}> + <a + href={sharingUrl} + title={name} + className={`${styles.link} ${styles[linkModifier]}`} + > + <span className="screen-reader-text">{name}</span> + </a> + </li> + ); + }); + }; + + return ( + <ExpandableWidget title={t`Share`} expand={true}> + <ul className={`${styles.list} ${styles['list--sharing']}`}> + {getItems()} + </ul> + </ExpandableWidget> + ); +}; + +export default Sharing; |
