Skip to content

Commit

Permalink
Show search result context in modal box #19
Browse files Browse the repository at this point in the history
  • Loading branch information
dcabo committed Oct 21, 2019
1 parent aad7ab5 commit e94bd3b
Show file tree
Hide file tree
Showing 6 changed files with 81 additions and 48 deletions.
51 changes: 39 additions & 12 deletions api/src/captions.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,22 +66,26 @@ export default class Captions {
return obj
}

mapResult(d) {
return {
id: d._id,
link: d._source.url,
content: d._source.text,
time_start: Math.floor(d._source.start),
time_end: Math.ceil(d._source.end),
programme: {
id: d._source.programme_id,
title: d._source.programme_title,
date: d._source.programme_date
}
}
}

parseResults(results, page) {
const data = {
page,
length: results.hits.total.value,
results: results.hits.hits.map(d => ({
id: d._id,
link: d._source.url,
content: d._source.text,
time_start: Math.floor(d._source.start),
time_end: Math.ceil(d._source.end),
programme: {
id: d._source.programme_id,
title: d._source.programme_title,
date: d._source.programme_date
}
}))
results: results.hits.hits.map(this.mapResult)
}
if (results.aggregations) {
data.aggregations = results.aggregations.matches_over_time.buckets.map(
Expand Down Expand Up @@ -116,4 +120,27 @@ export default class Captions {
})
return this.parseResults(results, page)
}

async fetchContext(
programme_id,
start_time,
range
) {
const query = {
query: {
bool: {
filter: [
{ term: { programme_id: programme_id } },
{ range: { start: { gte: parseInt(start_time)-range/2, lte: parseInt(start_time)+range/2 }} }
]
}
},
sort: { start: { order: 'asc' }}
}
const results = await this.client.search({
index: 'captions',
body: query
})
return results.hits.hits.map(this.mapResult)
}
}
9 changes: 9 additions & 0 deletions api/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,5 +34,14 @@ app.get('/search', cors(), async (request, response) => {
}
})

app.get('/fetchContext', cors(), async (request, response) => {
const results = await captions.fetchContext(
request.query.programme_id,
request.query.start_time,
request.query.range
)
response.json(results)
})

// Register express routes & serve
app.listen(PORT, () => console.log(`Server running on port ${PORT}`))
6 changes: 3 additions & 3 deletions web/src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -19,23 +19,23 @@
</div>
</div>
</div>
<VideoModal/>
<ResultContext/>
</div>
</template>

<script>
import Results from './components/Results.vue'
import Search from './components/Search.vue'
import SearchFilters from './components/SearchFilters.vue'
import VideoModal from './components/VideoModal.vue'
import ResultContext from './components/ResultContext.vue'
export default {
name: 'app',
components: {
Results,
Search,
SearchFilters,
VideoModal
ResultContext
}
}
</script>
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,10 @@
</button>
</div>
<div class="modal-body">
<div class="video-responsive">
<iframe frameborder="0" :src="videoUrl" scrolling="no" allowfullscreen></iframe>
<div v-if="resultContext">
<p v-for="(items, key) in resultContext" :key="key">
{{ items.time_start | formatTime }}: {{ items.content }}
</p>
</div>
</div>
</div>
Expand All @@ -24,9 +26,12 @@ import moment from 'moment'
import { mapActions, mapState } from 'vuex'
export default {
name: 'VideoModal',
name: 'ResultContext',
computed: {
...mapState(['currentResult']),
...mapState([
'currentResult',
'resultContext'
]),
title: function() {
const date = this.currentResult.programme.date
return `<strong>${moment(date).format(
Expand All @@ -37,13 +42,6 @@ export default {
)}h <small>(${this.$options.filters.formatTime(
this.currentResult.time_start
)})</small>`
},
videoUrl: function() {
// XXX: We try embedding from a given time, but it doesn't work, see #27
const parts = this.currentResult.link.split('/')
return `https://secure-embed.rtve.es/drmn/embed/video/${
parts[parts.length - 1]
}`
}
},
watch: {
Expand Down Expand Up @@ -88,17 +86,4 @@ export default {
z-index: 1;
cursor: pointer;
}
.video-responsive {
position: relative;
height: 0;
padding-bottom: 56.25%;
iframe {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
}
</style>
12 changes: 3 additions & 9 deletions web/src/components/Results.vue
Original file line number Diff line number Diff line change
Expand Up @@ -41,14 +41,8 @@
></path>
</svg>
</span>
<span class="badge badge-secondary video-link" @click="onPlayVideoBtnClick(item)">
Play Video
<svg class="icon-play" width="14" height="14" viewBox="0 0 24 24">
<path d="M0 0h24v24H0z" fill="none"></path>
<path
d="M10 16.5l6-4.5-6-4.5v9zM12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8z"
></path>
</svg>
<span class="badge badge-secondary video-link" @click="onShowContextBtnClick(item)">
Show context
</span>
<p class="item-content" v-html="highlight(item.content)"></p>
</div>
Expand Down Expand Up @@ -129,7 +123,7 @@ export default {
onGoToVideoBtnClick(result) {
window.open(result.link, '_blank')
},
onPlayVideoBtnClick(result) {
onShowContextBtnClick(result) {
this.setCurrentResult(result)
},
getAggregationObject(d) {
Expand Down
18 changes: 18 additions & 0 deletions web/src/store.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ Vue.use(Vuex)
export default new Vuex.Store({
state: {
currentResult: null,
resultContext: null,
loading: false,
query: '',
queryDate: null, // date.from - date.to
Expand All @@ -24,6 +25,7 @@ export default new Vuex.Store({
},
setCurrentResult({ commit }, payload) {
commit('setCurrentResult', payload)
commit('fetchResultContext', payload)
},
setQueryDate({ commit, state }, payload) {
commit('setQueryDate', payload)
Expand Down Expand Up @@ -64,6 +66,22 @@ export default new Vuex.Store({
setCurrentResult(state, payload) {
state.currentResult = payload
},
fetchResultContext(state, payload) {
if (state.currentResult === null) {
state.resultContext = null
} else {
const params = {
programme_id: state.currentResult.programme.id,
start_time: state.currentResult.time_start,
range: 60 // 1 minute context
}
axios
.get(process.env.VUE_APP_API_URL + 'fetchContext', { params })
.then(response => {
state.resultContext = response.data
})
}
},
setQuery(state, payload) {
state.loading = true
state.query = payload.trim() // store query
Expand Down

0 comments on commit e94bd3b

Please sign in to comment.