194 lines
5.3 KiB
Vue
194 lines
5.3 KiB
Vue
<template>
|
|
<div class="ui stackable grid">
|
|
<div class="three wide column">
|
|
<h5 class="ui header">
|
|
{{ metadata.position }}. {{ metadata.recording.title }}
|
|
<div class="sub header">
|
|
{{ time.parse(parseInt(metadata.length) / 1000) }}
|
|
</div>
|
|
</h5>
|
|
<div class="ui toggle checkbox">
|
|
<input type="checkbox" v-model="enabled" />
|
|
<label>Import this track</label>
|
|
</div>
|
|
</div>
|
|
<div class="three wide column" v-if="enabled">
|
|
<form class="ui mini form" @submit.prevent="">
|
|
<div class="field">
|
|
<label>Source</label>
|
|
<select v-model="currentBackendId">
|
|
<option v-for="backend in backends" :value="backend.id">
|
|
{{ backend.label }}
|
|
</option>
|
|
</select>
|
|
</div>
|
|
</form>
|
|
<div class="ui hidden divider"></div>
|
|
<template v-if="currentResult">
|
|
<button @click="currentResultIndex -= 1" class="ui basic tiny icon button" :disabled="currentResultIndex === 0">
|
|
<i class="left arrow icon"></i>
|
|
</button>
|
|
Result {{ currentResultIndex + 1 }}/{{ results.length }}
|
|
<button @click="currentResultIndex += 1" class="ui basic tiny icon button" :disabled="currentResultIndex + 1 === results.length">
|
|
<i class="right arrow icon"></i>
|
|
</button>
|
|
</template>
|
|
</div>
|
|
<div class="four wide column" v-if="enabled">
|
|
<form class="ui mini form" @submit.prevent="">
|
|
<div class="field">
|
|
<label>Search query</label>
|
|
<input type="text" v-model="query" />
|
|
<label>Imported URL</label>
|
|
<input type="text" v-model="importedUrl" />
|
|
</div>
|
|
</form>
|
|
</div>
|
|
<div class="six wide column" v-if="enabled">
|
|
<div v-if="isLoading" class="ui vertical segment">
|
|
<div :class="['ui', 'centered', 'active', 'inline', 'loader']"></div>
|
|
</div>
|
|
<div v-if="!isLoading && currentResult" class="ui items">
|
|
<div class="item">
|
|
<div class="ui small image">
|
|
<img :src="currentResult.cover" />
|
|
</div>
|
|
<div class="content">
|
|
<a
|
|
:href="currentResult.url"
|
|
target="_blank"
|
|
class="description"
|
|
v-html="$options.filters.highlight(currentResult.title, warnings)"></a>
|
|
<div v-if="currentResult.channelTitle" class="meta">
|
|
{{ currentResult.channelTitle}}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script>
|
|
import Vue from 'vue'
|
|
import time from '@/utils/time'
|
|
import config from '@/config'
|
|
import logger from '@/logging'
|
|
import ImportMixin from './ImportMixin'
|
|
|
|
import $ from 'jquery'
|
|
|
|
Vue.filter('highlight', function (words, query) {
|
|
query.forEach(w => {
|
|
let re = new RegExp('(' + w + ')', 'gi')
|
|
words = words.replace(re, '<span class=\'highlight\'>$1</span>')
|
|
})
|
|
return words
|
|
})
|
|
|
|
export default Vue.extend({
|
|
mixins: [ImportMixin],
|
|
props: {
|
|
releaseMetadata: {type: Object, required: true}
|
|
},
|
|
data () {
|
|
return {
|
|
isLoading: false,
|
|
results: [],
|
|
currentResultIndex: 0,
|
|
importedUrl: '',
|
|
warnings: [
|
|
'live',
|
|
'full',
|
|
'cover'
|
|
],
|
|
time
|
|
}
|
|
},
|
|
created () {
|
|
if (this.enabled) {
|
|
this.search()
|
|
}
|
|
},
|
|
mounted () {
|
|
$('.ui.checkbox').checkbox()
|
|
},
|
|
methods: {
|
|
search () {
|
|
let self = this
|
|
this.isLoading = true
|
|
let url = config.API_URL + 'providers/' + this.currentBackendId + '/search/'
|
|
let resource = Vue.resource(url)
|
|
|
|
resource.get({query: this.query}).then((response) => {
|
|
logger.default.debug('searching', self.query, 'on', self.currentBackendId)
|
|
self.results = response.data
|
|
self.isLoading = false
|
|
}, (response) => {
|
|
logger.default.error('error while searching', self.query, 'on', self.currentBackendId)
|
|
self.isLoading = false
|
|
})
|
|
}
|
|
},
|
|
computed: {
|
|
type () {
|
|
return 'track'
|
|
},
|
|
currentResult () {
|
|
if (this.results) {
|
|
return this.results[this.currentResultIndex]
|
|
}
|
|
},
|
|
importData () {
|
|
return {
|
|
count: 1,
|
|
mbid: this.metadata.recording.id,
|
|
source: this.importedUrl
|
|
}
|
|
},
|
|
query () {
|
|
let queryMapping = [
|
|
['artist', this.releaseMetadata['artist-credit'][0]['artist']['name']],
|
|
['album', this.releaseMetadata['title']],
|
|
['title', this.metadata['recording']['title']]
|
|
]
|
|
let query = this.customQueryTemplate
|
|
queryMapping.forEach(e => {
|
|
query = query.split('$' + e[0]).join(e[1])
|
|
})
|
|
return query
|
|
}
|
|
},
|
|
watch: {
|
|
query () {
|
|
this.search()
|
|
},
|
|
currentResult (newValue) {
|
|
if (newValue) {
|
|
this.importedUrl = newValue.url
|
|
}
|
|
},
|
|
importedUrl (newValue) {
|
|
this.$emit('url-changed', this.importData, this.importedUrl)
|
|
},
|
|
enabled (newValue) {
|
|
if (newValue && this.results.length === 0) {
|
|
this.search()
|
|
}
|
|
}
|
|
}
|
|
})
|
|
</script>
|
|
|
|
<!-- Add "scoped" attribute to limit CSS to this component only -->
|
|
<style scoped lang="scss">
|
|
.ui.card {
|
|
width: 100% !important;
|
|
}
|
|
</style>
|
|
<style lang="scss">
|
|
.highlight {
|
|
font-weight: bold !important;
|
|
background-color: yellow !important;
|
|
}
|
|
</style>
|