From 7fb47a4866bc5fd73449f19beb7c1052c3ea2b47 Mon Sep 17 00:00:00 2001 From: Matt Panaro Date: Tue, 31 Dec 2024 22:29:19 -0500 Subject: [PATCH] refactor handleChange to extract context from URLs previously, the search box would only add new quickActions if raw `@` or `#` characters were found in the search string; but in the case of a drag and drop, or a copy-paste, of a URL into the search bar, no elements of the URL's path would be recognized for potential quickActions. This change enables identification of possible hashtags or user accounts in a (presumed) mastodon URL; augmenting id by special input characters. --- .../features/compose/components/search.tsx | 35 ++++++++++++++++--- 1 file changed, 30 insertions(+), 5 deletions(-) diff --git a/app/javascript/mastodon/features/compose/components/search.tsx b/app/javascript/mastodon/features/compose/components/search.tsx index c38939a2d6..3ff1691d82 100644 --- a/app/javascript/mastodon/features/compose/components/search.tsx +++ b/app/javascript/mastodon/features/compose/components/search.tsx @@ -360,22 +360,47 @@ export const Search: React.FC<{ const couldBeURL = trimmedValue.startsWith('https://') && !trimmedValue.includes(' '); + let mastoPath; if (couldBeURL) { newQuickActions.push(QuickActionGenerators.couldBeURL(trimmedValue)); + + // presume URL is from a mastodon server; not just some random web URL + mastoPath = new URL(trimmedValue).pathname.replace(/^\//, ''); + } else { + mastoPath = ''; } const couldBeHashtag = (trimmedValue.startsWith('#') && trimmedValue.length > 1) || - trimmedValue.match(HASHTAG_REGEX); + trimmedValue.match(HASHTAG_REGEX) || + (couldBeURL && mastoPath.startsWith('tags/')); if (couldBeHashtag) { - newQuickActions.push(QuickActionGenerators.couldBeHashtag(trimmedValue.replace(/^#/, ''))); + const hashtag = couldBeURL + ? mastoPath.replace(/^tags\//, '') + : trimmedValue.replace(/^#/, ''); + + newQuickActions.push(QuickActionGenerators.couldBeHashtag(hashtag)); } - const couldBeUsername = /^@?[a-z0-9_-]+(@[^\s]+)?$/i.exec(trimmedValue); - + const userRegexp = /^@?[a-z0-9_-]+(@[^\s]+)?$/i; + const couldBeUsername = + userRegexp.test(trimmedValue) || + (couldBeURL && userRegexp.test(mastoPath)); if (couldBeUsername) { - newQuickActions.push(QuickActionGenerators.couldBeUsername(trimmedValue.replace(/^@/, ''))); + const mastoUser = mastoPath.replace(/^@/, ''); + + const username = !couldBeURL + ? trimmedValue.replace(/^@/, '') + : // @ts-expect-error : mastoPath was tested against userRegexp above, meaning there must be at least one `@`: + // so match can't return null here + mastoPath.match(/@/g).length === 1 + ? // if there's only 1 `@` in mastoPath, obtain domain from URL's FQDN & append to mastoUser + `${mastoUser}@${new URL(trimmedValue).hostname}` + : // otherwise there were at least (hopefully, only) 2, and it's a full masto identifier + mastoUser; + + newQuickActions.push(QuickActionGenerators.couldBeUsername(username)); } const couldBeStatusSearch = searchEnabled;