Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Transcript Search Functionality #497

Merged
merged 27 commits into from
May 20, 2024

Conversation

patrick-lienau
Copy link
Collaborator

As promised in #464, here is a PR for the addition of search functionality to transcripts.

Based on the list of checkboxes in #464, I think we're largely in alignment with what such an implementation should look like in terms of UI/UX.

UI Previews

State before any search term entered

image

Previous/Next button, "Result X of Y", and result match highlighting

image

Search Results as markers on progress bar

image

Mobile View

image

I've tried to limit the scope of the changes necessary to achieve this as much as possible. That being said, in order to allow for highlighting matches in transcript lines (ie: making the search terms bold/underlined) and to enable the prev/next button to scroll the transcript viewer, some significant changes had to be made to <Transcript />. However, upon review, I think you'll agree that the changes will result in a more maintainable component.

Customization

I know there was some interest of connecting this search functionality to some IIIF search API. Since we already have the full text of the transcript in-browser I'm not sure how much benefit that would add in practice.. However, I did take that into account. The <Transcript /> component can be given a custom "matcherFactory":

const CustomTranscript = ({ transcripts }) => { 
  const matcherFactory = useMemo(() => ( // useMemo is for referential stability
    (transcriptItems) => {
      return async (query, abortController) => {
        try {
          const res = await fetch('https://my-api.com/search?q='+query, {
            signal: abortController.signal
          });
          const json = await res.json();
          return res.results;
        } catch (e) {
          console.error(e);
          return [];
        }
      }
    }	
  ));
  return (
    <Transcript
      playerID="player-id"
      transcripts={transcripts}
      search={{
        matcherFactory
      }}
    />
  );
};

It supports both async results AND gives an AbortController which can be passed to fetch. So If there is a api request in progress with the query hello wo and the user types, updating the query to hello wor, the previous fetch is canceled by the browser. This should make it possible to wire up to an external API or integrate with some fuzzy search library of your preference. By default, it behaves like your browser's "Find in Page" (CTRL+F) search and seems to work quite well.

Next Steps

I know there are use cases for RAMP that I'm not really aware of. I'm really just going off the demo page so I'm not sure how this all interacts with thing like Playlists, and whatever the Markers tab does. Hopefully once you've had a chance to review, we can discuss where I might be able to find some examples of those so I can test their interaction.

I've written several tests, but have held off on going for more complete coverage, updating the documentation, extensively annotating code, etc until your team has had a chance to take a look at it. Once the implementation has undergone any requested changes, I'll go through, finish writing tests, annotate code, update the docs, etc.

Anyway, I'd love any feedback anyone has. Thanks.

demo/app.js Outdated Show resolved Hide resolved
Copy link
Collaborator

@Dananji Dananji left a comment

Choose a reason for hiding this comment

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

This looks really good. Thanks for contributing your work upstream.

I just have a couple of questions about the code.

@patrick-lienau patrick-lienau force-pushed the feat/transcript-search branch from 9d48c2d to 75f156d Compare May 20, 2024 15:44
@Dananji
Copy link
Collaborator

Dananji commented May 20, 2024

Thanks for making the changes and answering my questions.

I have one more question on the functionality of the search markers in the progress bar;
When you click on a search hit marker on the progress bar it doesn't scroll the transcript component to that respective transcript line, it feels like this is broken, am I right?

@patrick-lienau
Copy link
Collaborator Author

patrick-lienau commented May 20, 2024

That's some functionality I had thought about but never implemented. It would require being able to pass a selectedMarkerId (or something like that) from the <MediaPlayer /> component into to the <TranscriptList /> component.

Markers were a request from our client but I wasn't even sure how your team would feel about the markers because I don't believe they were mentioned when we spoke before. I didn't want to build that out when it could have been requested that they be removed from the PR.

Perhaps this could be a future addition?

I'm picturing updating selectedMarkerId via a dispatch from the MarkerPlugin's click handler and then a useEffect inside <TranscriptList/> which watches PlayerStateContext and calls goToItem when it changes

Copy link
Collaborator

@Dananji Dananji left a comment

Choose a reason for hiding this comment

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

Looks great! 👍

It'd be great if you could squash and merge to keep Git history clean and concise. Thanks!

@Dananji
Copy link
Collaborator

Dananji commented May 20, 2024

Related issues: avalonmediasystem/avalon#5753, #464

@patrick-lienau
Copy link
Collaborator Author

patrick-lienau commented May 20, 2024

and merge to keep Git history clean and concise. Thanks!

image

Alas, I don't have the permissions to perform the actual merge ↑↑

@Dananji
Copy link
Collaborator

Dananji commented May 20, 2024

@patrick-lienau I sent an invitation adding you as a collaborator with write permissions. Now you should be able to merge 🎉

@patrick-lienau patrick-lienau merged commit f18afc3 into samvera-labs:main May 20, 2024
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.

2 participants