Add support for parsing links in description/location

This commit is contained in:
Luke Vella 2022-04-14 18:17:59 +01:00
parent 1e466718fc
commit 12e2c11ede
6 changed files with 81 additions and 12 deletions

View file

@ -0,0 +1,30 @@
import * as React from "react";
import Tooltip from "../tooltip";
export const truncatedLink = (href: string, text: string, key: number) => {
const textWithoutProtocol = text.replace(/^https?:\/\//i, "");
const beginningOfPath = textWithoutProtocol.indexOf("/");
let finalText = textWithoutProtocol;
if (beginningOfPath !== -1) {
finalText = textWithoutProtocol.substring(0, beginningOfPath + 30);
}
if (finalText.length === textWithoutProtocol.length) {
return (
<a key={key} href={href}>
{finalText}
</a>
);
} else {
finalText += "…";
return (
<Tooltip
key={key}
content={
<div className="text-xs font-mono max-w-md break-all">{href}</div>
}
>
<a href={href}>{finalText}</a>
</Tooltip>
);
}
};

View file

@ -99,7 +99,7 @@ const Tooltip: React.VoidFunctionComponent<TooltipProps> = ({
{...attributes.popper}
>
<Transition
className="tooltip"
className="px-3 py-2 rounded-md pointer-events-none bg-slate-700 text-slate-200 shadow-md"
as={"div"}
show={debouncedValue}
enter="transition transform duration-100"
@ -108,7 +108,7 @@ const Tooltip: React.VoidFunctionComponent<TooltipProps> = ({
>
<div
ref={setArrowElement}
className="tooltip-arrow"
className="tooltip-arrow w-3 h-3 border-transparent border-[6px]"
style={styles.arrow}
data-popper-arrow
></div>

View file

@ -43,6 +43,7 @@
"react-hook-form": "^7.27.0",
"react-hot-toast": "^2.2.0",
"react-i18next": "^11.15.4",
"react-linkify": "^1.0.0-alpha",
"react-popper": "^2.2.5",
"react-query": "^3.34.12",
"react-use": "^17.3.2",
@ -59,6 +60,7 @@
"@types/react": "^17.0.5",
"@types/react-big-calendar": "^0.31.0",
"@types/react-dom": "^17.0.13",
"@types/react-linkify": "^1.0.1",
"@types/smoothscroll-polyfill": "^0.3.1",
"@typescript-eslint/eslint-plugin": "^4.23.0",
"@typescript-eslint/parser": "^4.23.0",

View file

@ -30,6 +30,8 @@ import { preventWidows } from "utils/prevent-widows";
import { GetPollResponse } from "../api-client/get-poll";
import { getBrowserTimeZone } from "../utils/date-time-utils";
import Custom404 from "./404";
import Linkify from "react-linkify";
import { truncatedLink } from "@/components/poll/truncated-link";
const Discussion = React.lazy(() => import("@/components/discussion"));
@ -259,14 +261,23 @@ const PollPage: NextPage = () => {
</div>
</div>
{poll.description ? (
<div className="text-lg max-w-2xl mb-4 whitespace-pre-line w-fit shadow-sm bg-white text-slate-600 rounded-xl px-4 py-3">
{preventWidows(poll.description)}
<div className="text-lg leading-relaxed max-w-2xl mb-4 whitespace-pre-line w-fit shadow-sm bg-white text-slate-600 rounded-xl px-4 py-3">
<Linkify componentDecorator={truncatedLink}>
{preventWidows(poll.description)}
</Linkify>
</div>
) : null}
{poll.location ? (
<div className="flex items-center mb-4">
<LocationMarker width={20} className="text-slate-400 mr-2" />
{poll.location}
<div>
<LocationMarker
width={20}
className="text-slate-400 mr-2"
/>
</div>
<Linkify componentDecorator={truncatedLink}>
{poll.location}
</Linkify>
</div>
) : null}
</div>

View file

@ -125,12 +125,6 @@
@apply cursor-not-allowed;
}
.tooltip {
@apply px-3 py-2 rounded-md pointer-events-none bg-slate-700 text-slate-200 shadow-md;
}
.tooltip-arrow {
@apply w-3 h-3 border-transparent border-[6px];
}
[data-popper-placement="bottom"] .tooltip-arrow {
@apply bottom-full border-b-slate-700;
}

View file

@ -1729,6 +1729,13 @@
dependencies:
"@types/react" "*"
"@types/react-linkify@^1.0.1":
version "1.0.1"
resolved "https://registry.yarnpkg.com/@types/react-linkify/-/react-linkify-1.0.1.tgz#4ece351faef22bfde1280b6d9ace5e88683a74d4"
integrity sha512-qPxYwjB41ezoKdLXs0MrQ1FnhF3apyyxf3J7WVQQCBu/GyZQAW7Y3TY4317jdh0450QJ4fLqj0rnhIJvFZOamQ==
dependencies:
"@types/react" "*"
"@types/react@*", "@types/react@>=16.9.11", "@types/react@^17.0.5":
version "17.0.5"
resolved "https://registry.npmjs.org/@types/react/-/react-17.0.5.tgz"
@ -4040,6 +4047,13 @@ lines-and-columns@^1.1.6:
resolved "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz"
integrity sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=
linkify-it@^2.0.3:
version "2.2.0"
resolved "https://registry.yarnpkg.com/linkify-it/-/linkify-it-2.2.0.tgz#e3b54697e78bf915c70a38acd78fd09e0058b1cf"
integrity sha512-GnAl/knGn+i1U/wjBz3akz2stz+HrHLsxMwHQGofCDfPvlf+gDKN58UtfmUquTY4/MXeE2x7k19KQmeoZi94Iw==
dependencies:
uc.micro "^1.0.1"
load-json-file@^2.0.0:
version "2.0.0"
resolved "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz"
@ -4919,6 +4933,14 @@ react-lifecycles-compat@^3.0.4:
resolved "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz"
integrity sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==
react-linkify@^1.0.0-alpha:
version "1.0.0-alpha"
resolved "https://registry.yarnpkg.com/react-linkify/-/react-linkify-1.0.0-alpha.tgz#b391c7b88e3443752fafe76a95ca4434e82e70d5"
integrity sha512-7gcIUvJkAXXttt1fmBK9cwn+1jTa4hbKLGCZ9J1U6EOkyb2/+LKL1Z28d9rtDLMnpvImlNlLPdTPooorl5cpmg==
dependencies:
linkify-it "^2.0.3"
tlds "^1.199.0"
react-overlays@^4.1.1:
version "4.1.1"
resolved "https://registry.npmjs.org/react-overlays/-/react-overlays-4.1.1.tgz"
@ -5643,6 +5665,11 @@ timezone-soft@^1.3.1:
resolved "https://registry.yarnpkg.com/timezone-soft/-/timezone-soft-1.3.1.tgz#0e994067cbccc76a9c16b71fd8f2f94394be5b0d"
integrity sha512-mphMogFJzQy6UIpl/UgKLSNbhmLtdgbz866TnqJ/CnWnc+7dsNyAe8nPwVdOW3Mf8nT0lA32MW/gYhAl4/RkVg==
tlds@^1.199.0:
version "1.231.0"
resolved "https://registry.yarnpkg.com/tlds/-/tlds-1.231.0.tgz#93880175cd0a06fdf7b5b5b9bcadff9d94813e39"
integrity sha512-L7UQwueHSkGxZHQBXHVmXW64oi+uqNtzFt2x6Ssk7NVnpIbw16CRs4eb/jmKOZ9t2JnqZ/b3Cfvo97lnXqKrhw==
to-fast-properties@^2.0.0:
version "2.0.0"
resolved "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz"
@ -5741,6 +5768,11 @@ typescript@^4.5.2:
resolved "https://registry.npmjs.org/typescript/-/typescript-4.5.2.tgz"
integrity sha512-5BlMof9H1yGt0P8/WF+wPNw6GfctgGjXp5hkblpyT+8rkASSmkUKMXrxR0Xg8ThVCi/JnHQiKXeBaEwCeQwMFw==
uc.micro@^1.0.1:
version "1.0.6"
resolved "https://registry.yarnpkg.com/uc.micro/-/uc.micro-1.0.6.tgz#9c411a802a409a91fc6cf74081baba34b24499ac"
integrity sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==
unbox-primitive@^1.0.0, unbox-primitive@^1.0.1:
version "1.0.1"
resolved "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz"