From 847ca50d07a625da1fce97dea44a3e3f7c05f74b Mon Sep 17 00:00:00 2001 From: Jacob Pihl Date: Mon, 9 Dec 2024 16:53:09 +0100 Subject: [PATCH 1/8] Added new translation strings to material entry --- src/apps/material/material.entry.tsx | 2 ++ src/apps/material/material.stories.tsx | 12 +++++++++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/src/apps/material/material.entry.tsx b/src/apps/material/material.entry.tsx index 52171f0410..e68dd2a311 100644 --- a/src/apps/material/material.entry.tsx +++ b/src/apps/material/material.entry.tsx @@ -167,6 +167,8 @@ interface MaterialEntryTextProps { shiftText: string; subjectNumberText: string; tryAginButtonText: string; + shareOnFacebookText: string; + copyLinkText: string; } interface MaterialEntryConfigProps { diff --git a/src/apps/material/material.stories.tsx b/src/apps/material/material.stories.tsx index 899ca6cb36..23a0ec188c 100644 --- a/src/apps/material/material.stories.tsx +++ b/src/apps/material/material.stories.tsx @@ -686,6 +686,14 @@ const meta: Meta = { openOrderErrorMissingPincodeText: { description: "Open order error missing pincode text", control: { type: "text" } + }, + shareOnFacebookText: { + description: "Share on Facebook", + control: { type: "text" } + }, + copyLinkText: { + description: "Copy link", + control: { type: "text" } } }, args: { @@ -901,7 +909,9 @@ const meta: Meta = { openOrderUnknownErrorText: "An unknown error occurred", openOrderUnknownPickupagencyText: "Specified pickup agency not found", openOrderUnknownUserText: "User not found", - openOrderErrorMissingPincodeText: "Missing pincode" + openOrderErrorMissingPincodeText: "Missing pincode", + shareOnFacebookText: "Share on Facebook", + copyLinkText: "Copy link" } }; From 99c4f9fb5860f32b702e0459cffaf6e6412a27ce Mon Sep 17 00:00:00 2001 From: Jacob Pihl Date: Mon, 9 Dec 2024 16:59:39 +0100 Subject: [PATCH 2/8] Added svg icons MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit To leverage the advantages of ´svg´ in the DOM and to change the color on hover, we need to have it as a component. This would not be possible with an `img` tag --- src/components/button-share/facebook-icon.tsx | 22 ++++++++++++++++++ src/components/button-share/link-icon.tsx | 23 +++++++++++++++++++ 2 files changed, 45 insertions(+) create mode 100644 src/components/button-share/facebook-icon.tsx create mode 100644 src/components/button-share/link-icon.tsx diff --git a/src/components/button-share/facebook-icon.tsx b/src/components/button-share/facebook-icon.tsx new file mode 100644 index 0000000000..089076d746 --- /dev/null +++ b/src/components/button-share/facebook-icon.tsx @@ -0,0 +1,22 @@ +import React from "react"; + +const FacebookIcon = () => { + return ( + + + + + + ); +}; + +export default FacebookIcon; diff --git a/src/components/button-share/link-icon.tsx b/src/components/button-share/link-icon.tsx new file mode 100644 index 0000000000..7d029074cc --- /dev/null +++ b/src/components/button-share/link-icon.tsx @@ -0,0 +1,23 @@ +import React from "react"; + +const LinkIcon = () => { + return ( + + + + ); +}; + +export default LinkIcon; From 3424a228f0a91cc9131d001e38770ceb4fe86f80 Mon Sep 17 00:00:00 2001 From: Jacob Pihl Date: Mon, 9 Dec 2024 17:02:28 +0100 Subject: [PATCH 3/8] Added new share buttons with link to Facebook sharer and copy to clipboard --- src/components/button-share/button-share.tsx | 95 ++++++++++++++++++++ 1 file changed, 95 insertions(+) create mode 100644 src/components/button-share/button-share.tsx diff --git a/src/components/button-share/button-share.tsx b/src/components/button-share/button-share.tsx new file mode 100644 index 0000000000..bb3ef53fa7 --- /dev/null +++ b/src/components/button-share/button-share.tsx @@ -0,0 +1,95 @@ +import React, { useEffect, useRef, useState } from "react"; +import clsx from "clsx"; +import FacebookIcon from "./facebook-icon"; +import LinkIcon from "./link-icon"; +import { useText } from "../../core/utils/text"; + +type ButtonShareProps = { + className?: string; +}; + +const ButtonShare: React.FC = ({ className }) => { + const t = useText(); + const { href } = window.location; + const facebookShareUrl = "https://www.facebook.com/sharer/sharer.php"; + const shareUrl = `${facebookShareUrl}?u=${href}`; + + const shareButtonAreaLabel = "Share this page on Facebook"; + const copyButtonAreaLabel = "Copy this page to clipboard"; + + const [showFixedButtons, setShowFixedButtons] = useState(true); + const shareButton = useRef(null); + + const onShareButtonClick = () => { + navigator.clipboard.writeText(href); + }; + + useEffect(() => { + const observer = new IntersectionObserver( + (entries) => { + entries.forEach((entry) => { + if (entry.isIntersecting) { + setShowFixedButtons(false); + } else { + setShowFixedButtons(true); + } + }); + }, + { threshold: 1 } + ); + + if (shareButton.current) { + observer.observe(shareButton.current); + } + + return () => { + if (shareButton.current) { + observer.unobserve(shareButton.current); + } + }; + }, []); + + return ( +
+ {showFixedButtons && ( +
+ + + + +
+ )} + + + {t("shareOnFacebookText")} + + +
+ ); +}; + +export default ButtonShare; From cc76471ea7f27186076062cc393828bc7162ca35 Mon Sep 17 00:00:00 2001 From: Jacob Pihl Date: Mon, 9 Dec 2024 17:02:41 +0100 Subject: [PATCH 4/8] Added share buttons to material description --- src/components/material/MaterialDescription.tsx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/components/material/MaterialDescription.tsx b/src/components/material/MaterialDescription.tsx index 90dca843e1..e378839e80 100644 --- a/src/components/material/MaterialDescription.tsx +++ b/src/components/material/MaterialDescription.tsx @@ -15,6 +15,7 @@ import { useUrls } from "../../core/utils/url"; import HorizontalTermLine from "../horizontal-term-line/HorizontalTermLine"; import { materialIsFiction } from "../../core/utils/helpers/general"; import SeriesList from "../card-item-list/card-list-item/series-list"; +import ButtonShare from "../button-share/button-share"; export interface MaterialDescriptionProps { pid: Pid; @@ -120,6 +121,7 @@ const MaterialDescription: React.FC = ({ work }) => { dataCy="material-description-film-adaptations" /> + )} From 4df5e1fe93c5c04dc6925e9f280c139fe0be816c Mon Sep 17 00:00:00 2001 From: Jacob Pihl Date: Tue, 10 Dec 2024 13:55:50 +0100 Subject: [PATCH 5/8] Move sharebutton ref into constant --- src/components/button-share/button-share.tsx | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/components/button-share/button-share.tsx b/src/components/button-share/button-share.tsx index bb3ef53fa7..ef3dd5b342 100644 --- a/src/components/button-share/button-share.tsx +++ b/src/components/button-share/button-share.tsx @@ -18,7 +18,7 @@ const ButtonShare: React.FC = ({ className }) => { const copyButtonAreaLabel = "Copy this page to clipboard"; const [showFixedButtons, setShowFixedButtons] = useState(true); - const shareButton = useRef(null); + const shareButtonRef = useRef(null); const onShareButtonClick = () => { navigator.clipboard.writeText(href); @@ -38,13 +38,15 @@ const ButtonShare: React.FC = ({ className }) => { { threshold: 1 } ); - if (shareButton.current) { - observer.observe(shareButton.current); + const shareButton = shareButtonRef.current; + + if (shareButton) { + observer.observe(shareButton); } return () => { - if (shareButton.current) { - observer.unobserve(shareButton.current); + if (shareButton) { + observer.unobserve(shareButton); } }; }, []); @@ -71,7 +73,7 @@ const ButtonShare: React.FC = ({ className }) => { )} Date: Wed, 11 Dec 2024 13:29:20 +0100 Subject: [PATCH 6/8] Open Facebook sharer in a new tab --- src/components/button-share/button-share.tsx | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/components/button-share/button-share.tsx b/src/components/button-share/button-share.tsx index ef3dd5b342..fc458af2b6 100644 --- a/src/components/button-share/button-share.tsx +++ b/src/components/button-share/button-share.tsx @@ -57,6 +57,8 @@ const ButtonShare: React.FC = ({ className }) => {
@@ -75,6 +77,8 @@ const ButtonShare: React.FC = ({ className }) => { From 0a39ad7b2e3a395e88a5a11f3dc4d1e8c3cfe6e3 Mon Sep 17 00:00:00 2001 From: Jacob Pihl Date: Wed, 11 Dec 2024 16:17:37 +0100 Subject: [PATCH 7/8] Added translations for aria labels --- src/apps/material/material.entry.tsx | 2 ++ src/apps/material/material.stories.tsx | 12 +++++++++++- src/components/button-share/button-share.tsx | 4 ++-- 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/src/apps/material/material.entry.tsx b/src/apps/material/material.entry.tsx index e68dd2a311..a3e2e29097 100644 --- a/src/apps/material/material.entry.tsx +++ b/src/apps/material/material.entry.tsx @@ -168,7 +168,9 @@ interface MaterialEntryTextProps { subjectNumberText: string; tryAginButtonText: string; shareOnFacebookText: string; + shareOnFacebookAriaLabelText: string; copyLinkText: string; + copyLinkAriaLabelText: string; } interface MaterialEntryConfigProps { diff --git a/src/apps/material/material.stories.tsx b/src/apps/material/material.stories.tsx index 23a0ec188c..e665075aed 100644 --- a/src/apps/material/material.stories.tsx +++ b/src/apps/material/material.stories.tsx @@ -691,9 +691,17 @@ const meta: Meta = { description: "Share on Facebook", control: { type: "text" } }, + shareOnFacebookAriaLabelText: { + description: "Share this page on Facebook", + control: { type: "text" } + }, copyLinkText: { description: "Copy link", control: { type: "text" } + }, + copyLinkAriaLabelText: { + description: "Copy this page URL to clipboard", + control: { type: "text" } } }, args: { @@ -911,7 +919,9 @@ const meta: Meta = { openOrderUnknownUserText: "User not found", openOrderErrorMissingPincodeText: "Missing pincode", shareOnFacebookText: "Share on Facebook", - copyLinkText: "Copy link" + shareOnFacebookAriaLabelText: "Share this page on Facebook", + copyLinkText: "Copy link", + copyLinkAriaLabelText: "Copy this page URL to clipboard" } }; diff --git a/src/components/button-share/button-share.tsx b/src/components/button-share/button-share.tsx index fc458af2b6..9965d4c7f9 100644 --- a/src/components/button-share/button-share.tsx +++ b/src/components/button-share/button-share.tsx @@ -14,8 +14,8 @@ const ButtonShare: React.FC = ({ className }) => { const facebookShareUrl = "https://www.facebook.com/sharer/sharer.php"; const shareUrl = `${facebookShareUrl}?u=${href}`; - const shareButtonAreaLabel = "Share this page on Facebook"; - const copyButtonAreaLabel = "Copy this page to clipboard"; + const shareButtonAreaLabel = t("shareOnFacebookAriaLabelText"); + const copyButtonAreaLabel = t("copyLinkAriaLabelText"); const [showFixedButtons, setShowFixedButtons] = useState(true); const shareButtonRef = useRef(null); From 230f95d6ea377d4ea82b024d4d198c46e23bead6 Mon Sep 17 00:00:00 2001 From: Jacob Pihl Date: Thu, 12 Dec 2024 16:35:08 +0100 Subject: [PATCH 8/8] Extended intersection observer to also hide the fixed share buttons when the user has scrolled past the share buttons. This is because we don't want to show the fixed share buttons in the footer --- src/components/button-share/button-share.tsx | 26 ++++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/components/button-share/button-share.tsx b/src/components/button-share/button-share.tsx index 9965d4c7f9..83b0aa1d96 100644 --- a/src/components/button-share/button-share.tsx +++ b/src/components/button-share/button-share.tsx @@ -24,31 +24,31 @@ const ButtonShare: React.FC = ({ className }) => { navigator.clipboard.writeText(href); }; + // Hide fixed buttons when share button is in view or above viewport useEffect(() => { + const shareButton = shareButtonRef.current; const observer = new IntersectionObserver( (entries) => { - entries.forEach((entry) => { - if (entry.isIntersecting) { - setShowFixedButtons(false); - } else { - setShowFixedButtons(true); - } + const isIntersecting = entries.some((entry) => entry.isIntersecting); + const isAboveViewport = entries.some((entry) => { + // return true if the share button is above the viewport + return entry.boundingClientRect.top < 0; }); + setShowFixedButtons(!isIntersecting && !isAboveViewport); }, { threshold: 1 } ); - const shareButton = shareButtonRef.current; - if (shareButton) { observer.observe(shareButton); + + return () => { + // Clean up observer on unmount + observer.disconnect(); + }; } - return () => { - if (shareButton) { - observer.unobserve(shareButton); - } - }; + return () => {}; }, []); return (