From e94bd3b7d8d5145507c61fca6e93e57bfbd29d97 Mon Sep 17 00:00:00 2001 From: David Cabo Date: Mon, 21 Oct 2019 18:36:09 +0200 Subject: [PATCH] Show search result context in modal box #19 --- api/src/captions.js | 51 ++++++++++++++----- api/src/index.js | 9 ++++ web/src/App.vue | 6 +-- .../{VideoModal.vue => ResultContext.vue} | 33 ++++-------- web/src/components/Results.vue | 12 ++--- web/src/store.js | 18 +++++++ 6 files changed, 81 insertions(+), 48 deletions(-) rename web/src/components/{VideoModal.vue => ResultContext.vue} (72%) diff --git a/api/src/captions.js b/api/src/captions.js index 3195793..ce4f207 100644 --- a/api/src/captions.js +++ b/api/src/captions.js @@ -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( @@ -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) + } } diff --git a/api/src/index.js b/api/src/index.js index 7e5a5f6..0ed5752 100644 --- a/api/src/index.js +++ b/api/src/index.js @@ -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}`)) diff --git a/web/src/App.vue b/web/src/App.vue index 3fa2a20..8595903 100644 --- a/web/src/App.vue +++ b/web/src/App.vue @@ -19,7 +19,7 @@ - + @@ -27,7 +27,7 @@ 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', @@ -35,7 +35,7 @@ export default { Results, Search, SearchFilters, - VideoModal + ResultContext } } diff --git a/web/src/components/VideoModal.vue b/web/src/components/ResultContext.vue similarity index 72% rename from web/src/components/VideoModal.vue rename to web/src/components/ResultContext.vue index e41468b..8d184db 100644 --- a/web/src/components/VideoModal.vue +++ b/web/src/components/ResultContext.vue @@ -9,8 +9,10 @@ @@ -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 `${moment(date).format( @@ -37,13 +42,6 @@ export default { )}h (${this.$options.filters.formatTime( this.currentResult.time_start )})` - }, - 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: { @@ -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%; - } -} diff --git a/web/src/components/Results.vue b/web/src/components/Results.vue index acbd8a2..1c7ca2b 100644 --- a/web/src/components/Results.vue +++ b/web/src/components/Results.vue @@ -41,14 +41,8 @@ > - - Play Video - - - - + + Show context

@@ -129,7 +123,7 @@ export default { onGoToVideoBtnClick(result) { window.open(result.link, '_blank') }, - onPlayVideoBtnClick(result) { + onShowContextBtnClick(result) { this.setCurrentResult(result) }, getAggregationObject(d) { diff --git a/web/src/store.js b/web/src/store.js index ca032f0..4cc01e2 100644 --- a/web/src/store.js +++ b/web/src/store.js @@ -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 @@ -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) @@ -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