Skip to content

Conversation

@dan-foley
Copy link
Contributor

Description

Added an anchor tag around the events location link making it clickable.

Type of change

Please select everything applicable. Please, do not delete any lines.

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • This change requires a documentation update
  • This change requires an update to testing

Issue

  • Is this related to a specific issue? If so, please specify:

Checklist:

  • This PR is up to date with the main branch, and merge conflicts have been resolved
  • I have executed npm run test and npm run test:e2e and all tests have passed successfully or I have included details within my PR on the failure.
  • I have executed npm run lint and resolved any outstanding errors. Most issues can be solved by executing npm run format
  • My code follows the style guidelines of this project
  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • My changes generate no new warnings

@DevinCLane
Copy link
Collaborator

looks good on first glance

also in #621 we did specify that events should be clickable in the event description as well. you are welcome to add it to this PR, or if you'd like to split it out into a different PR that's fine too

@dan-foley dan-foley closed this Aug 26, 2025
@dan-foley dan-foley reopened this Aug 26, 2025
@dan-foley
Copy link
Contributor Author

Accidentally closed the request lol. I'll try to get links in the description working on this PR too.

@dan-foley
Copy link
Contributor Author

dan-foley commented Aug 26, 2025

@DevinCLane

It seems like it might be a good idea to use a library called react-linkify

https://www.npmjs.com/package/react-linkify

Is there anything special I need to consider when adding a new library?

@DevinCLane
Copy link
Collaborator

can you mention in the Discord to see if others have opinions? seems fine for me, but ideally we get 1-2 other sign offs before moving forward

@dan-foley dan-foley force-pushed the Events-display-links-properly branch from 12d53a9 to 0efc32c Compare August 28, 2025 18:17
@dan-foley
Copy link
Contributor Author

Links are now working int he event description as well! Thanks to @indifferentghost for the help!

if (URLRegex.test(res)) {
// Prepend http:// if it starts with www. to make a valid href
const href = res.startsWith("www.")
? `http://${res}`
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
? `http://${res}`
? `https://${res}`

i'm thinking we would want to add https instead of just http?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch, I'll try to have this done tomorrow.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We 100% want to always send to https.

rel="noopener noreferrer"
className="text-blue-600 underline hover:text-blue-800"
>
{res}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it'd be best to show the punycode representation here since unicode can be misleading

Consider the following case. It looks awfully similar to apple.com, but it's not really

new URL("https://аррlе.com") 
URL { href: "https://xn--l-7sbq6ba.com/", origin: "https://xn--l-7sbq6ba.com", protocol: "https:", username: "", password: "", host: "xn--l-7sbq6ba.com", hostname: "xn--l-7sbq6ba.com", port: "", pathname: "/", search: "" }

Copy link

@indifferentghost indifferentghost left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I may have overstepped my suggestions, here's why I think this improves the code:

  • It makes the second URL check more useful by helping us format values
  • Parsing a URL through the URL handler ensures data integrity. We are sending a url and not an http:// prepended string.

Here's the cons of this approach:

  • We're losing the www. from the URL.
  • The more regex used the harder it is to follow
  • Named capturing groups are relatively new, anyone using a non-standard or 7+ year old browser may have problems viewing this content.

import { useAuthContext } from "../../contexts/AuthContext";
import { useEventsContext } from "../../contexts/EventsContext";

const URLRegex = /(https?:\/\/[^\s]+|www\.[^\s]+)/g;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm wondering if we can use capturing groups to better effect:

We can start by setting up capturing groups

const URLRegex = /(https?:\/\/|www\.)([^\s]+)/g;

This attempts to isolate the scheme and www subdomain from the rest of the url. The first capturing group grabs either the protocol https:// or the www. subdomain, but lacks the ability to grab both.

We can add an additional capturing group and make it optional ?.

const URLRegex = /(https?:\/\/(www.)?|www\.)([^\s]+)/g;

Our capturing groups are now a mess, so you can use a non-capturing group to clean things up.

const URLRegex = /(?:https?:\/\/(?:www.)?|www\.)([^\s]+)/g;

But even better might be giving some implicit documentation so we know what we're doing. Named capturing groups also exist.

Suggested change
const URLRegex = /(https?:\/\/[^\s]+|www\.[^\s]+)/g;
const URLRegex = /(https?:\/\/(www.)?|www\.)(?<host>[^\s]+)/g;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is actually hard to grok just from looking at the regex. It might be worthwhile to throw some jsdoc here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I'm a total regex noob so I wasn't sure I was going to do it right lol. I'll try to add some jsdoc once I can understand what is going on myself.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When I add the new regex line the link no longer works. Did you test it yourself?

Copy link

@indifferentghost indifferentghost Sep 3, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

image I'm curious what browser you're running. The [browser compatability](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Regular_expressions/Named_capturing_group#browser_compatibility) shows it works on modern browsers

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Weird, I'm using the latest version of Chrome. I sent you a message on Discord. If you want we can set up a time to meet on there and I can show you the problem I am having.

const separated = children.split(URLRegex);

return separated.map((res, index) => {
if (URLRegex.test(res)) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With a named capturing group we can better use our methods to get a predictable result. (I prefer ending early over gate control.

Suggested change
if (URLRegex.test(res)) {
const parsedUrl = URLRegex.exec(res);
if (parsedUrl === null) {
return res;
}

Comment on lines 23 to 25
const href = res.startsWith("www.")
? `http://${res}`
: new URL(res).toString();

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Finally we add back the schema and parse it. host may not be the correct group name. domain may be more descriptive.

There is some consideration that our www subdomain is removed, but I think that's fine.

Suggested change
const href = res.startsWith("www.")
? `http://${res}`
: new URL(res).toString();
const formattedUrl = `https://${parsedUrl.groups.host}`;
if (!URL.canParse(formattedUrl)) {
throw new Error(`Unable to parse ${res}`);
}
const href = new URL(formattedUrl).toString();

if (URLRegex.test(res)) {
// Prepend http:// if it starts with www. to make a valid href
const href = res.startsWith("www.")
? `http://${res}`

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We 100% want to always send to https.

Comment on lines +141 to +175
<span>
Location:{" "}
<a
href={modal.activeEvent.location}
target="_blank"
rel="noopener noreferrer"
className="text-blue-600 underline hover:text-blue-800"
>
{modal.activeEvent.location}
</a>
</span>

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this different from the LinkText component we built?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I did that part first but wasn't able to do the same thing for the event description links. Thats where you came in and recommended the LinkText component.

<div className="description break-words w-auto min-h-20 mb-2 p-2 border-solid border-black border-2 font-semibold rounded-xl bg-neutral-200/50">
<p>{modal.activeEvent.description}</p>
<p>
<LinkText>{modal.activeEvent.description}</LinkText>

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the LinkText isn't for user inserted content, we may have over-engineered, but it's okay.

{res}
</a>
);
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since our check returns res early we don't need this closing bracket.

Suggested change
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here's the early returning check #641 (comment)

rel="noopener noreferrer"
className="text-blue-600 underline hover:text-blue-800"
>
{res}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should reference the href as display links can be deliberately misleading.

Suggested change
{res}
{href}

@dan-foley
Copy link
Contributor Author

@indifferentghost honestly most of that went over my head, if anyone else can weight in and let me know if those changes all make sense I'll try to implement them.

@DevinCLane
Copy link
Collaborator

i like these changes and can moderately follow this. seems like it makes sense to implement then continue the review

@dan-foley
Copy link
Contributor Author

I have gone through and made changes, making the regex also handle something like example.com as well as www.example.com and https://www.example.com. I also tried to do the punycode thing @20jasper mentioned and replaced http with https on line 24. Let me know what you think!

Comment on lines 30 to 34
res.startsWith("http://") || res.startsWith("https://")
? res
: res.startsWith("www.")
? `https://${res}`
: `https://${res}`; // bare domains like google.com
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i'm not sure i understand this part, could you walk me through what's happening here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It checks if res has a protocol of either http or https, if not it checks if it starts with www. Then if it doesn't have any of that it assumes it is a bare domain like if someone just typed google.com. This way the link will always be prepended with https.

Copy link
Contributor Author

@dan-foley dan-foley Sep 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just changed this to an if-then statement for better readability.

key={index}
href={href}
target="_blank"
rel="noopener noreferrer"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I removed noopener but kept noreferrer

@dan-foley dan-foley force-pushed the Events-display-links-properly branch from f0dbe8d to ea6d2c7 Compare September 17, 2025 14:19

return (
<a
key={index}
Copy link
Collaborator

@DevinCLane DevinCLane Sep 30, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let's instead use the key={${res}-${index}} as the key value instead of the index

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just updated it!

@dan-foley dan-foley force-pushed the Events-display-links-properly branch from ea6d2c7 to cddbd0b Compare October 1, 2025 17:50
@dan-foley dan-foley requested a review from moses-codes as a code owner October 1, 2025 17:50
@DevinCLane
Copy link
Collaborator

ok i'll see if i can review this in the next week!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants