From aa1ca65e7c9807c6d6020e39166536297fe1cdae Mon Sep 17 00:00:00 2001
From: Armand Philippot <git@armandphilippot.com>
Date: Sat, 15 Jan 2022 22:45:57 +0100
Subject: 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.
---
 src/components/Widgets/Sharing/Sharing.tsx | 113 +++++++++++++++++++++++++++++
 1 file changed, 113 insertions(+)
 create mode 100644 src/components/Widgets/Sharing/Sharing.tsx

(limited to 'src/components/Widgets/Sharing/Sharing.tsx')

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;
-- 
cgit v1.2.3

