KawAnime/pages/index.vue

372 lines
10 KiB
Vue

<template xmlns:v-tooltip="http://www.w3.org/1999/xhtml" xmlns:v-bind="http://www.w3.org/1999/xhtml">
<v-container fluid class="container pa-0">
<transition name="fade" v-if="releases.length">
<v-layout row wrap style="margin: 0 1% 0 1%;">
<v-flex md4 sm4 xs12 class="time-container">
<span class="update-time">Updated {{ lastUpdateTime }}.</span>
</v-flex>
<v-flex md4 sm1 xs0></v-flex>
<v-flex md2 sm3 xs12>
<v-select
class="select"
v-bind:items="fansubList"
v-model="$store.state.releaseFansub"
label="Fansub"
dark
single-line
hint="Pick a fansub"
persistent-hint
/>
</v-flex>
<v-flex md1 sm2 xs12>
<v-select
class="select"
v-bind:items="qualityList"
v-model="$store.state.releaseQuality"
label="Quality"
dark
single-line
hint="Which quality ?"
persistent-hint
/>
</v-flex>
<v-flex md1 sm1 xs12 class="refresh-button-container">
<v-btn icon
class="refresh-button"
@click="refresh()">
<v-icon large>refresh</v-icon>
</v-btn>
</v-flex>
<template v-for="item in releases">
<v-flex xs12 sm6 md4
:key="item.name"
class="elem">
<v-card class="elem-content elevation-3" v-ripple="true">
<v-card-text class="elem-card">
<v-container fluid style="padding: 0;">
<v-layout row wrap>
<v-flex class="elem-title" xs9 v-tooltip:top="{ html: item.rawName }">
<h6 class="white--text">{{ item.rawName }}</h6>
</v-flex>
<v-flex v-tooltip:top="{ html: 'Episode ' + item.ep }"
class="elem-ep text-xs-right" xs3>
<h6 class="white--text">Ep {{ item.ep }}</h6>
</v-flex>
<v-flex class="elem-image"
xl6 lg4 md5 sm3 xs4>
<img v-bind:src="item.picture" height="200" class="picture"/>
</v-flex>
<v-flex xl6 lg8 md7 sm9 xs8>
<div class="elem-text-links">
<div class="synopsis">
{{ item.synopsis }}
</div>
<div class="links">
<a :href="item.magnetLink" class="download-button">
<v-btn dark flat
@click="print(item)"
class="btn--light-flat-pressed">
Download
</v-btn>
</a>
<v-menu open-on-hover
transition="slide-x-transition">
<v-btn flat dark slot="activator">
More
</v-btn>
<v-list>
<v-list-tile @click="openModal(item.rawName, item.fullSynopsis)">
<v-list-tile-action>
<v-icon>more</v-icon>
</v-list-tile-action>
<v-list-tile-title>
Check synopsis
</v-list-tile-title>
</v-list-tile>
<v-list-tile @click="downloadAll(item.rawName)">
<v-list-tile-action>
<v-icon>file_download</v-icon>
</v-list-tile-action>
<v-list-tile-title>
Download all episodes
</v-list-tile-title>
</v-list-tile>
<v-list-tile>
<v-list-tile-action>
<v-icon>info_outline</v-icon>
</v-list-tile-action>
<v-list-tile-title>Information</v-list-tile-title>
</v-list-tile>
<v-list-tile @click="showChoices(item.rawName)">
<v-list-tile-action>
<v-icon>add_box</v-icon>
</v-list-tile-action>
<v-list-tile-title>
Add to
</v-list-tile-title>
</v-list-tile>
</v-list>
</v-menu>
</div>
</div>
</v-flex>
</v-layout>
</v-container>
</v-card-text>
</v-card>
</v-flex>
</template>
</v-layout>
</transition>
<loader v-else></loader>
<div class="text-xs-center modal-container">
<v-dialog v-model="modal" width="70%">
<v-card class="white--text">
<v-card-text class="white--text">
<h2 class="white--text headline">{{ modalTitle }}</h2>
</v-card-text>
<v-card-text class="subheading white--text">
{{ modalText }}
</v-card-text>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn class="blue--text darken-1" flat
v-on:click.native="modal = false">Thanks!
</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
</div>
<choice-window :entry="choiceTitle"></choice-window>
</v-container>
</template>
<script>
import axios from 'axios'
export default {
head () {
return {
title: 'Releases',
meta: [
{hid: 'description', name: 'description', content: 'Latest downloadable anime releases'}
]
}
},
mounted () {
if (this.releases.length) {
this.updateTime(this.$store)
}
setInterval(() => {
if (this.releases.length) {
this.updateTime(this.$store)
}
}, 60 * 1000)
},
data () {
return {
choiceTitle: '',
modal: false,
modalTitle: '',
modalText: '',
fansubList: [
'HorribleSubs',
'PuyaSubs!',
'Fuyu',
'DurandalSubs',
'DefinitelyNotMe'
],
qualityList: ['480p', '720p', '1080p'],
lastUpdateTime: 'a few seconds ago'
}
},
computed: {
releases () {
return this.$store.state.releases
}
},
methods: {
openModal (title, text) {
console.log(`[${(new Date()).toLocaleTimeString()}]: Opening modal`)
this.modalTitle = title
this.modalText = text
this.modal = true
},
downloadAll (name) {
console.log(`[${(new Date()).toLocaleTimeString()}]: Sending a request to download all episodes of ${name}.`)
const quality = this.$store.state.releaseQuality
const fansub = this.$store.state.releaseFansub
axios.post('download', {
name: name,
quality: quality,
fromEp: 0,
untilEp: 20000,
fansub: fansub,
choice: 'si'
}).then(({data}) => {
console.log(`[${(new Date()).toLocaleTimeString()}]: Server responded!`)
data.forEach((link) => {
window.open(link)
})
}).catch((err) => {
console.log(`[${(new Date()).toLocaleTimeString()}]: An error occurred... ${err}`)
this.$store.commit('setInfoSnackbar', `An error occurred while getting ${name}.`)
})
},
async refresh () {
await this.$store.dispatch('refreshReleases')
this.updateTime()
},
print (item) {
console.log(`[${(new Date()).toLocaleTimeString()}]: Downloading ${item.name}.`)
},
showChoices (name) {
this.choiceTitle = name
this.$store.commit('setAddToChoice', true)
},
updateTime (store = this.$store) {
const updated = store.state.releasesUpdateTime
if (updated) {
this.lastUpdateTime = updated.fromNow()
}
}
}
}
</script>
<style scoped>
p
{
margin-bottom: 0;
}
div.input-group
{
padding-bottom: 5px !important;
padding-top: 8px !important;
}
/* ----- Refresh button ----- */
.refresh-button-container
{
display: inline-block;
text-align: center;
padding: 0;
align-self: center;
}
.time-container
{
height: 70px;
display: flex;
align-items: center;
}
.update-time
{
padding-left: 20px;
font-weight: 600;
font-size: 16px;
font-style: italic;
}
.elem
{
margin-bottom: 10px;
display: inline-block;
}
.elem-content
{
background-color: rgb(60, 60, 60);
cursor: default;
}
.elem-content:hover
{
transition: all 0.4s;
box-shadow: 0 5px 5px -3px rgba(0, 0, 0, 0.2),
0 8px 10px 1px rgba(0, 0, 0, 0.14),
0 3px 14px 2px rgba(0, 0, 0, 0.12) !important;
}
.elem-card
{
padding: 0 10px 0 0;
}
.elem-title h6
{
padding-left: 10px;
margin-top: 10px;
margin-bottom: 10px;
line-height: 26px;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
}
.elem-ep h6
{
margin-top: 10px;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
}
.elem-image
{
height: 200px;
}
.picture
{
max-width: 100%;
}
.elem-text-links
{
height: 100%;
position: relative;
}
.synopsis
{
text-align: justify;
display: block;
text-overflow: ellipsis;
word-wrap: break-word;
overflow: hidden;
max-height: 9em;
line-height: 1.5em;
}
.links
{
height: 25%;
position: absolute;
bottom: 5px;
right: -2px;
display: flex;
}
.download-button
{
text-decoration: none;
margin-right: 0;
}
.subheading
{
padding: 30px;
text-align: justify;
text-align-last: center;
}
</style>