|
| 1 | +import { EnvelopeIcon, ExportIcon, IconButton, LinkIcon, Menu, Popover, Position, ShareIcon, toaster } from "evergreen-ui" |
| 2 | +import { option } from "fp-ts"; |
| 3 | +import { pipe } from "fp-ts/lib/function"; |
| 4 | +import { useEffect, useState } from "react"; |
| 5 | +import { Package } from "../api/domain"; |
| 6 | + |
| 7 | +type Props = { |
| 8 | + package: Package |
| 9 | +} |
| 10 | + |
| 11 | +const FEATURE_FLAG_EMAIL_LINK = false; |
| 12 | + |
| 13 | +export const ShareButton = (props: Props) => { |
| 14 | + const [url, setUrl] = useState<string | undefined>(undefined); |
| 15 | + const [canShare, setCanShare] = useState<boolean | undefined>(undefined); |
| 16 | + |
| 17 | + const onClick = () => pipe( |
| 18 | + url, |
| 19 | + option.fromNullable, |
| 20 | + option.fold( |
| 21 | + () => toaster.warning("Unable to share package", {id: "toaster-share-unable"}), |
| 22 | + u => navigator.share({ |
| 23 | + title: props.package.title, |
| 24 | + text: props.package.description, |
| 25 | + url: u |
| 26 | + }) |
| 27 | + ) |
| 28 | + ); |
| 29 | + |
| 30 | + const onCopyLink = () => pipe( |
| 31 | + url, |
| 32 | + option.fromNullable, |
| 33 | + option.fold( |
| 34 | + () => toaster.warning("Unable to copy link to the clipboard", {id: "toaster-link-copy-unable"}), |
| 35 | + u => navigator.clipboard |
| 36 | + .writeText(u) |
| 37 | + .then(() => toaster.success("Link copied to the clipboard!", { |
| 38 | + id: "toaster-link-copy-success" |
| 39 | + })) |
| 40 | + ) |
| 41 | + ) |
| 42 | + |
| 43 | + const onEmailLink = () => pipe( |
| 44 | + url, |
| 45 | + option.fromNullable, |
| 46 | + option.fold( |
| 47 | + () => toaster.warning("Unable to share link via email", {id: "toaster-link-email-unable"}), |
| 48 | + u => { |
| 49 | + const subject = `Check out Espanso's ${props.package.title} package!` |
| 50 | + const body = `Hello, |
| 51 | +I just found out "${props.package.title}", an Espanso package you might be interested into. |
| 52 | +
|
| 53 | +Check it out at ${u} |
| 54 | +`; |
| 55 | + document.location = encodeURI(`mailto:?subject=${subject}&body=${body}`); |
| 56 | + }, |
| 57 | + ) |
| 58 | + ) |
| 59 | + |
| 60 | + useEffect(() => { |
| 61 | + setCanShare(typeof navigator.share === "function"); |
| 62 | + setUrl(`${window.location.hostname}${window.location.pathname}${window.location.search}`); |
| 63 | + }, []); |
| 64 | + |
| 65 | + const linkShareLayout = <Popover |
| 66 | + position={Position.BOTTOM_RIGHT} |
| 67 | + content={ |
| 68 | + <Menu> |
| 69 | + <Menu.Group> |
| 70 | + <Menu.Item |
| 71 | + icon={LinkIcon} |
| 72 | + onSelect={onCopyLink}> |
| 73 | + Copy Link |
| 74 | + </Menu.Item> |
| 75 | + {FEATURE_FLAG_EMAIL_LINK ?? <Menu.Item |
| 76 | + icon={EnvelopeIcon} |
| 77 | + onSelect={onEmailLink}> |
| 78 | + Email Link |
| 79 | + </Menu.Item>} |
| 80 | + </Menu.Group> |
| 81 | + </Menu>}> |
| 82 | + <IconButton icon={ExportIcon} appearance="minimal"/> |
| 83 | + </Popover> |
| 84 | + |
| 85 | + const webShareAPILayout = <IconButton |
| 86 | + icon={ShareIcon} |
| 87 | + appearance="minimal" |
| 88 | + onClick={onClick}/> |
| 89 | + |
| 90 | + return canShare ? webShareAPILayout : linkShareLayout; |
| 91 | +} |
0 commit comments