1
0
Fork 0
mirror of https://github.com/Findus23/cr-search.git synced 2024-09-19 15:23:44 +02:00

add transcript page

This commit is contained in:
Lukas Winkler 2021-10-26 18:09:33 +02:00
parent a06301b8a9
commit 3a829d74f9
Signed by: lukas
GPG key ID: 54DE4D798D244853
7 changed files with 139 additions and 31 deletions

View file

@ -48,11 +48,13 @@ body {
border: 1px dashed $border-color;
transition: background-color .2s;
border-radius: 0;
&:focus, &:active {
background: transparent;
color: $body-color;
}
&:hover{
&:hover {
background: rgba(177, 148, 54, 0.11);
}
}
@ -70,18 +72,6 @@ body {
.entry {
.person {
font-weight: bold;
}
.line {
padding-left: 5px;
border-left: solid 5px $background-color;
&.note, &.meta {
font-style: italic;
}
}
.title {
font-size: .529cm;
@ -101,6 +91,24 @@ body {
}
}
.person {
font-weight: bold;
}
.line {
padding-left: 5px;
border-left: solid 5px $background-color;
&.note, &.meta {
font-style: italic;
}
&.highlighted {
border: solid 5px $primary;
}
}
p {
font-family: "Bookinsanity", serif;
}
@ -114,9 +122,11 @@ footer {
display: flex;
justify-content: space-between;
flex-wrap: wrap;
> * {
padding: .5rem;
}
button.btn-link {
padding: 0;
}

View file

@ -17,6 +17,11 @@ export interface SeriesData extends Series {
"length": number;
}
export interface TranscriptData {
episode: Episode;
lines: Line[];
}
export interface Episode {
"episode_number": number;
"id": number;

View file

@ -2,6 +2,7 @@ import Vue from "vue";
import App from "./App.vue";
import router from "./router";
import "./custom.scss";
import {VBTooltipPlugin} from "bootstrap-vue";
Vue.config.productionTip = false;
@ -10,3 +11,4 @@ new Vue({
render: (h) => h(App),
}).$mount("#app");
Vue.use(VBTooltipPlugin);

View file

@ -1,7 +1,7 @@
import Vue from "vue";
import Router from "vue-router";
import Home from "./views/Home.vue";
import Episodes from "@/views/Episodes.vue";
import Transcript from "@/views/Transcript.vue";
Vue.use(Router);
@ -12,11 +12,18 @@ export default new Router({
{
path: "/",
redirect: "/campaign2/10/",
name: "home"
},
{
path: "/episodes",
name: "episodes",
component: () => import(/* webpackChunkName: "episodes" */ "./views/Episodes.vue"),
component: () => import(/* webpackChunkName: "episodes" */ "./views/Episodes.vue"),
},
{
path: "/transcript/:series/:episodeNr",
name: "transcript",
component: Transcript,
props: true,
},
{
path: "/:something/",
@ -28,13 +35,5 @@ export default new Router({
component: Home,
// props: true,
},
// {
// path: "/about",
// name: "about",
// // route level code-splitting
// // this generates a separate chunk (about.[hash].js) for this route
// // which is lazy-loaded when the route is visited.
// component: () => import(/* webpackChunkName: "about" */ "./views/About.vue"),
// },
],
});

View file

@ -1,11 +1,6 @@
<template>
<div id="contentwrapper" class="text-page">
<h1>Episode Overview</h1>
<!-- <div v-for="series in series_data">-->
<!-- <a :href="seriesID(series.meta,true)">{{ series.meta.title }}</a>-->
<!-- </div>-->
<div v-for="series in series_data" :key="series.meta.id" class="episode-table">
<h2 :id="seriesID(series.meta)">{{ series.meta.title }}</h2>
<table>

View file

@ -59,10 +59,18 @@
<div class="title">
<div>{{ formatTimestamp(firstLine(result).starttime) }} {{ episodeName(firstLine(result)) }}</div>
<div class="buttons">
<button class="btn" @click="playVideo(result)" title="View video on YouTube">
<router-link :to="transcriptLink(result)" class="btn" target="_blank" v-b-tooltip
title="Open this line in Transcript">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor"
class="bi bi-blockquote-left" viewBox="0 0 16 16">
<path d="M2.5 3a.5.5 0 0 0 0 1h11a.5.5 0 0 0 0-1h-11zm5 3a.5.5 0 0 0 0 1h6a.5.5 0 0 0 0-1h-6zm0 3a.5.5 0 0 0 0 1h6a.5.5 0 0 0 0-1h-6zm-5 3a.5.5 0 0 0 0 1h11a.5.5 0 0 0 0-1h-11zm.79-5.373c.112-.078.26-.17.444-.275L3.524 6c-.122.074-.272.17-.452.287-.18.117-.35.26-.51.428a2.425 2.425 0 0 0-.398.562c-.11.207-.164.438-.164.692 0 .36.072.65.217.873.144.219.385.328.72.328.215 0 .383-.07.504-.211a.697.697 0 0 0 .188-.463c0-.23-.07-.404-.211-.521-.137-.121-.326-.182-.568-.182h-.282c.024-.203.065-.37.123-.498a1.38 1.38 0 0 1 .252-.37 1.94 1.94 0 0 1 .346-.298zm2.167 0c.113-.078.262-.17.445-.275L5.692 6c-.122.074-.272.17-.452.287-.18.117-.35.26-.51.428a2.425 2.425 0 0 0-.398.562c-.11.207-.164.438-.164.692 0 .36.072.65.217.873.144.219.385.328.72.328.215 0 .383-.07.504-.211a.697.697 0 0 0 .188-.463c0-.23-.07-.404-.211-.521-.137-.121-.326-.182-.568-.182h-.282a1.75 1.75 0 0 1 .118-.492c.058-.13.144-.254.257-.375a1.94 1.94 0 0 1 .346-.3z"/>
</svg>
</router-link>
<button class="btn" @click="playVideo(result)" title="Watch line on YouTube" v-b-tooltip>
<b-icon-play-fill></b-icon-play-fill>
</button>
<button class="btn" v-if="result.offset<10" @click="expand(result)" title="Load more context">
<button class="btn" v-if="result.offset<10" @click="expand(result)" title="Load more context"
v-b-tooltip>
+
</button>
</div>
@ -98,7 +106,7 @@ import {BAlert, BIcon, BIconPlayFill} from "bootstrap-vue";
// @ts-ignore
import VueYoutube from "vue-youtube";
import debounce from "lodash-es/debounce";
import {Location} from "vue-router";
import {baseURL} from "@/utils";
import SeriesSelector from "@/components/SeriesSelector.vue";
import Intro from "@/components/Intro.vue";
@ -344,6 +352,18 @@ export default Vue.extend({
this.placeholderText = this.placeholderText.slice(0, -1);
const offset = Math.random() * 40 - 20;
this.placeholderTimeout = setTimeout(this.untype, 35 + offset);
},
transcriptLink(result: Result): Location {
const firstline = this.firstLine(result);
const episode = firstline.episode;
return {
name: "transcript",
params: {
episodeNr: episode.episode_number.toString(),
series: episode.series.slug
},
hash: "#" + firstline.starttime
};
}
},
computed: {

View file

@ -0,0 +1,77 @@
<template>
<div id="contentwrapper" class="text-page">
<h1>{{ episode.pretty_title }}</h1>
<p>
<router-link :to="{name:'home'}">Back to the Homepage</router-link>
</p>
<blockquote>
<strong>Note:</strong> This transcript-view is a work in progress and currently only shows very basic data.
One day it might allow to jump to the position of a line in the Youtube video like on the main page.
</blockquote>
<p :class="{line:true,note:line.isnote,meta:line.ismeta,highlighted:$route.hash.slice(1)===line.starttime.toString()}"
:style="{borderLeftColor:getColor(line)}"
v-for="line in lines" :key="line.id" :id="line.starttime">
<span v-if="line.person" class="person">{{ line.person.name }}: </span><span
v-html="line.text"></span>
</p>
</div>
</template>
<script lang="ts">
import Vue from "vue";
import {Episode, Line, TranscriptData} from "@/interfaces";
import {baseURL} from "@/utils";
import CheckMark from "@/components/CheckMark.vue";
export default Vue.extend({
name: "Transcript",
props: {
episodeNr: String,
series: String
},
components: {
CheckMark
},
data() {
return {
lines: [] as Line[],
episode: {} as Episode,
loaded: false
};
},
mounted() {
console.log(this.episodeNr);
fetch(baseURL + "transcript?episode=" + this.episodeNr + "&series=" + this.series)
.then((response) => response.json())
.then((data: TranscriptData) => {
this.episode = data.episode;
this.lines = data.lines;
this.loaded = true;
const hash = this.$route.hash;
if (hash) {
Vue.nextTick(function() {
document.getElementById(hash.slice(1))?.scrollIntoView({
behavior: "smooth",
});
});
}
});
},
methods: {
getColor(line: Line): string {
if (line.ismeta) {
return "pink";
} else if (line.isnote) {
return "purple";
}
if (line.person) {
return line.person.color;
}
return "white";
},
}
});
</script>