feat: highlight search results #625

Merged
Kieran merged 2 commits from fernandoporazzi/snort:highlight-searched-word into main 2023-09-29 15:54:18 +00:00
Contributor

Solves #559

Check screenshot for UI result.

Solves #559 Check screenshot for UI result.
fernandoporazzi force-pushed highlight-searched-word from 7f859dc70f to 07bb3cca2f 2023-08-30 10:51:16 +00:00 Compare
fernandoporazzi requested review from Kieran 2023-08-30 10:58:12 +00:00
Contributor

Hey, thanks for working on this issue! Screenshot looks good. I wonder if you tested it with multiple words "snort social" for example as the search results appear to do an && search, so highlighting both "snort" and "social" would make sense.

Either way, for all those direct matches this would already be a great improvement.

Hey, thanks for working on this issue! Screenshot looks good. I wonder if you tested it with multiple words "snort social" for example as the search results appear to do an `&&` search, so highlighting both "snort" and "social" would make sense. Either way, for all those direct matches this would already be a great improvement.
Author
Contributor

Hey @Giszmo, it will work for multiple words. However the highlight is just being applied exactly on what was typed.

On the second image, I search for two words in isolation, however they are not highlighted because there is content between them.

Hey @Giszmo, it will work for multiple words. However the highlight is just being applied exactly on what was typed. On the second image, I search for two words in isolation, however they are not highlighted because there is content between them.
Author
Contributor

Hey @Giszmo, it will work for multiple words. However the highlight is just being applied exactly on what was typed.

On the second image, I search for two words in isolation, however they are not highlighted because there is content between them.

I guess I found a solution that will highlight words in isolation. Soon I'll push the changes

> Hey @Giszmo, it will work for multiple words. However the highlight is just being applied exactly on what was typed. > > On the second image, I search for two words in isolation, however they are not highlighted because there is content between them. I guess I found a solution that will highlight words in isolation. Soon I'll push the changes
fernandoporazzi force-pushed highlight-searched-word from 07bb3cca2f to 4a5e32d4d4 2023-08-30 14:06:50 +00:00 Compare
Author
Contributor

Hey @Giszmo, it will work for multiple words. However the highlight is just being applied exactly on what was typed.

On the second image, I search for two words in isolation, however they are not highlighted because there is content between them.

I guess I found a solution that will highlight words in isolation. Soon I'll push the changes

Done, now this is the result:

> > Hey @Giszmo, it will work for multiple words. However the highlight is just being applied exactly on what was typed. > > > > On the second image, I search for two words in isolation, however they are not highlighted because there is content between them. > > I guess I found a solution that will highlight words in isolation. Soon I'll push the changes Done, now this is the result:
Contributor

Elegant solution in the RegExp.

I thought only ${searchedValue.replace(' ', '|')} would be enough but if the highlighting changes to maybe yellow background, your solution is needed.

Elegant solution in the RegExp. I thought only `${searchedValue.replace(' ', '|')}` would be enough but if the highlighting changes to maybe yellow background, your solution is needed.
Contributor

LGTM

LGTM
Kieran requested changes 2023-08-30 15:33:43 +00:00
@ -17,9 +17,10 @@ export interface TextProps {
disableMedia?: boolean;
disableMediaSpotlight?: boolean;
depth?: number;
searchedValue?: string;
Owner

props name should be highlighText accepting the RegExp

props name should be `highlighText` accepting the `RegExp`
fernandoporazzi marked this conversation as resolved
@ -68,3 +69,3 @@
return <ProxyImg src={a.content} size={15} className="custom-emoji" />;
default:
return <div className="text-frag">{a.content}</div>;
return <div className="text-frag" dangerouslySetInnerHTML={{
Owner

This is an obvious XSS leak, dangerouslySetInnerHTML should NEVER be used

This is an obvious XSS leak, `dangerouslySetInnerHTML` should NEVER be used
Author
Contributor

What would you suggest as an alternative?

A lib like DOMPurify could get the job done here.

What would you suggest as an alternative? A lib like [DOMPurify](https://www.npmjs.com/package/dompurify) could get the job done here.
Owner

No, look at transformText and use a similar approach, maybe adding "style" or another attribute to the text frag entry, ofc you need to create multiple text fragments in that case with different styles

No, look at `transformText` and use a similar approach, maybe adding "style" or another attribute to the text frag entry, ofc you need to create multiple text fragments in that case with different styles
Author
Contributor

I implemented the changes using the transformText approach. Now there is a new type for the ParsedFragment interface.

I implemented the changes using the `transformText` approach. Now there is a new type for the `ParsedFragment` interface.
fernandoporazzi marked this conversation as resolved
fernandoporazzi force-pushed highlight-searched-word from 4a5e32d4d4 to a6d5aa9453 2023-08-31 10:25:37 +00:00 Compare
fernandoporazzi force-pushed highlight-searched-word from a6d5aa9453 to b318a102b6 2023-08-31 10:30:12 +00:00 Compare
fernandoporazzi force-pushed highlight-searched-word from b318a102b6 to 501f8694c5 2023-08-31 10:31:01 +00:00 Compare
Author
Contributor

New implementation submitted. Preview:

New implementation submitted. Preview:
Kieran requested changes 2023-08-31 11:16:51 +00:00
@ -25,3 +27,3 @@
const elements = useMemo(() => {
return transformText(content, tags);
return transformText(content, tags, highlighText);
Owner

Its better if you dont implement this in the system lib, i dont think its of any use to anybody else who might use the lib, you can just copy the function inside here in this useMemo

Its better if you dont implement this in the `system` lib, i dont think its of any use to anybody else who might use the lib, you can just copy the function inside here in this `useMemo`
Author
Contributor

I don't know if I fully agree about moving the logic of this specific fragment inside this useMemo. All fragment-related logic now lives in a single place and it's easy to reason. Eventually the project might have unit tests and it's easier to test pure functions outside hooks.

If the problem is that there is now a 3rd argument, we could convert content, tags and highlightText into a single object and make the highlightText an optional property.

I don't know if I fully agree about moving the logic of this specific fragment inside this `useMemo`. All fragment-related logic now lives in a single place and it's easy to reason. Eventually the project might have unit tests and it's easier to test pure functions outside hooks. If the problem is that there is now a 3rd argument, we could convert `content`, `tags` and `highlightText` into a single object and make the `highlightText` an optional property.
Owner

I just dont see highlightText as useful for other people if they wanted to use the lib, that is why i think it should be outside

I just dont see `highlightText` as useful for other people if they wanted to use the lib, that is why i think it should be outside
Author
Contributor

I tried to co-locate the function extractHighlightedText inside this useMemo, however all the content already has a type(hashtag, text, media and so on...) and it's quite tricky then.

So if we are to remove the highlightText from the transformText, we'd have to have the implementation on top of the type text fragment directly on the render. I don't know if it's clear what I mean 😅

Something like:

default:
  return (
    <div className="text-frag">
      {highlighText ? applyHighlight(a.content) : a.content}
    </div>
  );

That way we remove the highlightText param from the function and fully delegate this to the Text component.

Opinions?

I tried to co-locate the function `extractHighlightedText` inside this `useMemo`, however all the content already has a type(hashtag, text, media and so on...) and it's quite tricky then. So if we are to remove the `highlightText` from the `transformText`, we'd have to have the implementation on top of the type `text` fragment directly on the render. I don't know if it's clear what I mean 😅 Something like: ```tsx default: return ( <div className="text-frag"> {highlighText ? applyHighlight(a.content) : a.content} </div> ); ``` That way we remove the highlightText param from the function and fully delegate this to the Text component. Opinions?
Owner

Yea thats probably fine

Yea thats probably fine
Author
Contributor

Implemented and PR is updated!

Implemented and PR is updated!
fernandoporazzi force-pushed highlight-searched-word from 501f8694c5 to 4bdf94e444 2023-09-01 13:09:57 +00:00 Compare
fernandoporazzi force-pushed highlight-searched-word from 4bdf94e444 to b2d17eab25 2023-09-01 13:12:38 +00:00 Compare
fernandoporazzi force-pushed highlight-searched-word from b2d17eab25 to c223c89045 2023-09-01 13:14:04 +00:00 Compare
Kieran approved these changes 2023-09-01 19:08:34 +00:00
Owner

You need to fix merge conflicts

You need to fix merge conflicts
fernandoporazzi added 1 commit 2023-09-29 15:15:40 +00:00
continuous-integration/drone/pr Build is failing Details
a0824646eb
feat: solve conflicts
Author
Contributor

Sorry for the long time to fix the conflicts. It should be good to go now. Please, checkout the branch and do some more tests.

Sorry for the long time to fix the conflicts. It should be good to go now. Please, checkout the branch and do some more tests.
fernandoporazzi requested review from Kieran 2023-09-29 15:21:07 +00:00
Kieran merged commit 1d1e8889dc into main 2023-09-29 15:54:18 +00:00
Kieran deleted branch highlight-searched-word 2023-09-29 15:54:19 +00:00
Sign in to join this conversation.
No description provided.