You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
176 lines
5.6 KiB
176 lines
5.6 KiB
{% extends "base.html" %}
|
|
|
|
{% block header_script_files %}
|
|
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
|
|
{% endblock %}
|
|
|
|
{% block header %}
|
|
{{ emit_tep('search_page_header') }}
|
|
{% endblock %}
|
|
|
|
{% block content %}
|
|
|
|
<div id="app">
|
|
<volumes v-bind:volumes='volumes' ref="volumes" v-on:do-search="getSearchResults"></volumes>
|
|
<modals v-bind:volume='volume'></modals>
|
|
</div>
|
|
|
|
{% endblock %}
|
|
|
|
{% block modals %}
|
|
{{ emit_tep('search_page_modals') }}
|
|
{% endblock %}
|
|
|
|
{% block button_container %}
|
|
{{ emit_tep('search_page_button_container') }}
|
|
{% endblock %}
|
|
|
|
{% block script %}
|
|
|
|
Vue.component('modals', {
|
|
props: [
|
|
'volume'
|
|
],
|
|
template: `
|
|
<div>
|
|
<div class="modal" id="modalVolume" tabindex="-1" role="dialog" aria-labelledby="notesModal" aria-hidden="true">
|
|
<div class="modal-dialog modal-dialog-centered modal-dialog-scrollable" role="document">
|
|
<div class="modal-content">
|
|
<div class="modal-header">
|
|
<h5 class="modal-title" id="notesModalTitle">
|
|
[[ volume.name ]] ([[ volume.count_of_issues ]] Issues)
|
|
</h5>
|
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
|
</div>
|
|
<div class="modal-body">
|
|
<span v-html="volume.description"></span>
|
|
</div>
|
|
<div class="modal-footer">
|
|
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
|
|
<button id="subscribeButton" type="button" class="btn btn-success" data-bs-dismiss="modal" @click='subscribe'>Subscribe</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{{ emit_tep('search_page_volume_modals') }}
|
|
</div>
|
|
`,
|
|
methods: {
|
|
subscribe() {
|
|
app.$refs.volumes.$children.find(child => {return child.$vnode.key == this.volume.id }).subscribe()
|
|
},
|
|
},
|
|
delimiters: ["[[", "]]"]
|
|
})
|
|
|
|
Vue.component('volume-item', {
|
|
props: ['volume'],
|
|
template: `
|
|
<li class='stashr-item_container m-2'
|
|
@mouseover="hover = true"
|
|
@mouseleave="hover = false"
|
|
>
|
|
<div class="stashr-poster_container border border-dark rounded-3" data-bs-toggle="modal" data-bs-target="#modalVolume" :data-volume_id=volume.id v-on:click="this.changeModal">
|
|
<div class="stashr-poster_wrapper">
|
|
<img class="stashr-background w-100" loading="eager" src="/static/assets/cover.svg" />
|
|
<img class="stashr-poster w-100" loading="lazy" :src="volume.image.medium_url" />
|
|
</div>
|
|
<div class="stashr-overlay_bottom w-100 text-center shadow" v-if="hover">
|
|
[[ volume.name ]]
|
|
</div>
|
|
</div>
|
|
</li>
|
|
`,
|
|
methods: {
|
|
subscribe() {
|
|
stashrToast('Adding to Library', 'info')
|
|
axios.post('{{ url_for('api.api_post_single_volume', volume_id='VOLUMESTRING') }}'.replace('VOLUMESTRING', this.volume.id))
|
|
.then(res => {
|
|
console.log(res)
|
|
if (res.data.status_code == 200) {
|
|
stashrToast('Added to Library', 'success');
|
|
} else {
|
|
stashrToast(res.data.message, 'error')
|
|
}
|
|
})
|
|
.catch(err => console.log(err))
|
|
},
|
|
changeModal() {
|
|
app.changeModal(this.volume)
|
|
},
|
|
},
|
|
data() { return { hover: false }},
|
|
delimiters: ["[[","]]"]
|
|
})
|
|
|
|
Vue.component('volumes', {
|
|
props: ['volumes'],
|
|
template: `
|
|
<div>
|
|
<div class="d-grid w-100 bg-mine m-0 p-0 sticky-top shadow">
|
|
<div class="m-0 p-3 input-group">
|
|
<input type="text" v-model="search" class="form-control" placeholder="Search Volumes..." />
|
|
<div class="input-group-append">
|
|
<button class="btn btn-success" type="button" @click="$emit('do-search', search)">
|
|
Search
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<ul class="d-flex flex-wrap w-100 m-0 p-0 py-2 justify-content-center">
|
|
<volume-item
|
|
v-for="volume in filteredList"
|
|
v-bind:volume="volume"
|
|
v-bind:key="volume.id"
|
|
></volume-item>
|
|
</ul>
|
|
</div>
|
|
`,
|
|
data() { return { search: '' }},
|
|
computed: {
|
|
filteredList() {
|
|
return this.volumes.filter(volume => {
|
|
return volume.name.toLowerCase().includes(this.search.toLowerCase())
|
|
})
|
|
},
|
|
},
|
|
delimiters: ["[[","]]"]
|
|
})
|
|
|
|
var app = new Vue({
|
|
el: '#app',
|
|
data: {
|
|
volumes: [],
|
|
volume: []
|
|
},
|
|
methods: {
|
|
getSearchResults(query) {
|
|
console.log('SEARCHING: ' + query)
|
|
axios.get('{{ url_for('api.api_get_search') }}', {
|
|
params: {
|
|
query: query
|
|
}
|
|
})
|
|
.then(res => {
|
|
this.volumes = res.data.results
|
|
})
|
|
.catch(err => console.log(err))
|
|
},
|
|
changeModal(volume) {
|
|
console.log('changing modal');
|
|
this.volume = volume
|
|
},
|
|
},
|
|
computed: {
|
|
filteredList() {
|
|
return this.volumes.filter(volume => {
|
|
return volume.volume_name.toLowerCase().includes(this.search.toLowerCase())
|
|
})
|
|
},
|
|
},
|
|
delimiters: ["[[","]]"]
|
|
})
|
|
|
|
{{ emit_tep('search_page_script') }}
|
|
|
|
{% endblock %} |