Files
rpg-static-site/content/episodes/search-transcripts.hbs
Anthony Correa 27eb1e634c feat: improve Markdown support and add transcript search functionality
- Add `.cache` to `.gitignore` for temporary build files.
- Introduce Markdown snippets for creating Season 1 and Season 5 show notes in `.vscode/markdown.code-snippets`.
- Update `.vscode/settings.json`:
  - Exclude `node_modules` directory.
  - Adjust quick suggestions to disable them for comments, strings, and others.
- Remove unnecessary `console.log` statements from `episodes.11tydata.js`.
- Add an image file `content/episodes/image.jpg`.
- Implement a transcript search feature:
  - Add `search-transcripts.hbs` to enable searching transcript cues with time markers.
  - Add `transcript-index.11ty.js` to generate a searchable transcript index.
- Update `search-index.11ty.js` to skip processing `<hr>` and `<img>` tags.
- Enhance episode layout with `startAt` query parameter to allow audio playback from a specific time.
- Add a new dependency:
  - `@11ty/eleventy-fetch` for fetching transcripts.
  - `media-captions` for parsing and handling transcript files.
- Update package-lock.json and package.json to include new dependencies.
2024-12-24 12:07:32 -06:00

60 lines
2.0 KiB
Handlebars

---
layout: base-with-heading
title: Search Transcripts
eleventyExcludeFromCollections: ["episode"]
override:tags: []
override:eleventyComputed: []
---
<script src="https://unpkg.com/lunr/lunr.js"></script>
<div>
<form id="search-form">
<input type="text" class="form-control mb-3" name="searchQuery" id="searchQuery">
<button class="btn btn-primary mb-3" type="submit">Search</button>
</form>
<div id="results">
<ol></ol>
</div>
</div>
<script type="module">
import {Duration} from 'https://cdn.jsdelivr.net/npm/luxon@3.5.0/+esm' ;
let idx, docs
let search_index_promise = fetch('../transcript-index')
.then((res)=>res.json())
.then((documents)=>{
docs = documents.map(({title, episode, season, url, cues})=>cues.map(({startTime, text})=>({title, episode, season, url, startTime, text}))).flat()
console.log(documents)
idx = lunr(function(){
this.ref('id')
this.field('text')
this.metadataWhitelist = ['position']
docs.forEach(function (doc, idx) {
doc.id = idx;
this.add(doc);
}, this)
})
})
function handleSubmit(evt) {
evt.preventDefault();
const formData = new FormData(evt.target)
const {searchQuery} = Object.fromEntries(formData)
const results = idx.search(searchQuery)
results.forEach(r => {
r.title = docs[r.ref].title,
r.url = docs[r.ref].url
})
console.log('Form submitted!', results)
const results_ol = document.getElementById("results").querySelector('ol')
results_ol.innerHTML = ""
results.forEach(r => {
const el = document.createElement('li')
const {url, title, text, season, episode, startTime} = docs[r.ref]
el.innerHTML = `<a href="${url}?startAt=${startTime}">${title} (Season ${season}, episode ${episode})</a><p>${Duration.fromObject({seconds:startTime}).toFormat("hh:mm:ss")}</p><p>${text}</p>`
results_ol.appendChild(el)
})
}
document.getElementById('search-form').addEventListener('submit', handleSubmit)
</script>