aboutsummaryrefslogtreecommitdiffstats
path: root/src/components/Widgets/Sharing/Sharing.tsx
diff options
context:
space:
mode:
authorArmand Philippot <git@armandphilippot.com>2022-01-15 22:45:57 +0100
committerArmand Philippot <git@armandphilippot.com>2022-01-15 22:51:30 +0100
commitaa1ca65e7c9807c6d6020e39166536297fe1cdae (patch)
tree2648da350fec3b71ab7f575d63e4c63ba08248b1 /src/components/Widgets/Sharing/Sharing.tsx
parent16dbb4742264edac82fa6bb8e461259d097f4437 (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.tsx113
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;