From bc810912434878768c11d521c5bf2bbcac6d3642 Mon Sep 17 00:00:00 2001 From: Austin Chen Date: Sat, 18 Dec 2021 04:06:59 -0800 Subject: [PATCH] Implement #hashtag grouping of markets --- web/components/contract-overview.tsx | 46 ++++++++++++++++++++++++++-- web/components/contracts-list.tsx | 2 +- web/pages/tag/[tag].tsx | 29 ++++++++++++++++++ 3 files changed, 73 insertions(+), 4 deletions(-) create mode 100644 web/pages/tag/[tag].tsx diff --git a/web/components/contract-overview.tsx b/web/components/contract-overview.tsx index 824d364d..64604bc7 100644 --- a/web/components/contract-overview.tsx +++ b/web/components/contract-overview.tsx @@ -1,4 +1,4 @@ -import React, { useState } from 'react' +import { Fragment, useState } from 'react' import { compute, Contract, @@ -13,7 +13,7 @@ import router from 'next/router' import { useUser } from '../hooks/use-user' import { Row } from './layout/row' import dayjs from 'dayjs' -import { Title } from './title' +import Link from 'next/link' function ContractDescription(props: { contract: Contract @@ -33,9 +33,49 @@ function ContractDescription(props: { setDescription(editStatement()) } + // Return a JSX span, linkifying @username, #hashtags, and https://... + function Linkify(props: { text: string }) { + const { text } = props + const regex = /(?:^|\s)(?:[@#][a-z0-9_]+|https?:\/\/\S+)/gi + const matches = text.match(regex) || [] + const links = matches.map((match) => { + // Matches are in the form: " @username" or "https://example.com" + const whitespace = match.match(/^\s/) + const symbol = match.trim().substring(0, 1) + const tag = match.trim().substring(1) + const href = + { + '@': `/${tag}`, + '#': `/tag/${tag}`, + }[symbol] ?? match + + return ( + <> + {whitespace} + + + {symbol} + {tag} + + + + ) + }) + return ( + + {text.split(regex).map((part, i) => ( + + {part} + {links[i]} + + ))} + + ) + } + return (
- {contract.description} +
{isCreator && !contract.resolution && diff --git a/web/components/contracts-list.tsx b/web/components/contracts-list.tsx index 6514f098..2ecc460a 100644 --- a/web/components/contracts-list.tsx +++ b/web/components/contracts-list.tsx @@ -146,7 +146,7 @@ export function SearchableGrid(props: { return (
{/* Show a search input next to a sort dropdown */} -
+
+ contract.description.toLowerCase().includes(`#${tag.toLowerCase()}`) + ) + } + + return ( +
+
+
+ + <SearchableGrid contracts={contracts === 'loading' ? [] : contracts} /> + </div> + </div> + ) +}