mirror of
https://github.com/cuiocean/ZY-Player.git
synced 2026-05-09 15:52:40 +08:00
😂 安装依赖, 移植 demo 代码
This commit is contained in:
@@ -0,0 +1,118 @@
|
||||
<template>
|
||||
<div class="aside">
|
||||
<span :class="[view === 'Film' ? 'active ': ''] + 'film'" @click="changeView('Film')">
|
||||
<svg role="img" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" aria-labelledby="apertureIconTitle">
|
||||
<title id="apertureIconTitle">{{$t('view')}}</title>
|
||||
<path d="M12 22C17.5228 22 22 17.5228 22 12C22 6.47715 17.5228 2 12 2C6.47715 2 2 6.47715 2 12C2 17.5228 6.47715 22 12 22Z"></path>
|
||||
<g stroke-linecap="round">
|
||||
<path d="M3 16H14.3164"></path>
|
||||
<path d="M4.03589 6.20575L9.68257 15.9861"></path>
|
||||
<path d="M13.0359 2.20575L7.37891 12.004"></path>
|
||||
<path d="M10.9641 21.7942L16.6146 12.0074"></path>
|
||||
<path d="M19.9641 17.7942L14.3086 7.99866"></path>
|
||||
<path d="M21 7.98721H9.71844"></path>
|
||||
</g>
|
||||
</svg>
|
||||
</span>
|
||||
<span :class="[view === 'Play' ? 'active ': ''] + 'play'" @click="changeView('Play')">
|
||||
<svg role="img" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" aria-labelledby="playIconTitle">
|
||||
<title id="playIconTitle">播放</title>
|
||||
<path d="M20 12L5 21V3z"></path>
|
||||
</svg>
|
||||
</span>
|
||||
<span :class="[view === 'Star' ? 'active ': ''] + 'star'" @click="changeView('Star')">
|
||||
<svg role="img" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" aria-labelledby="favouriteIconTitle">
|
||||
<title id="favouriteIconTitle">收藏</title>
|
||||
<path d="M12,21 L10.55,19.7051771 C5.4,15.1242507 2,12.1029973 2,8.39509537 C2,5.37384196 4.42,3 7.5,3 C9.24,3 10.91,3.79455041 12,5.05013624 C13.09,3.79455041 14.76,3 16.5,3 C19.58,3 22,5.37384196 22,8.39509537 C22,12.1029973 18.6,15.1242507 13.45,19.7149864 L12,21 Z"></path>
|
||||
</svg>
|
||||
</span>
|
||||
<span :class="[view === 'Setting' ? 'active ': ''] + 'setting'" @click="changeView('Setting')">
|
||||
<svg role="img" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" aria-labelledby="settingsIconTitle">
|
||||
<title id="settingsIconTitle">设置</title>
|
||||
<path d="M5.03506429,12.7050339 C5.01187484,12.4731696 5,12.2379716 5,12 C5,11.7620284 5.01187484,11.5268304 5.03506429,11.2949661 L3.20577137,9.23205081 L5.20577137,5.76794919 L7.9069713,6.32070904 C8.28729123,6.0461342 8.69629298,5.80882212 9.12862533,5.61412402 L10,3 L14,3 L14.8713747,5.61412402 C15.303707,5.80882212 15.7127088,6.0461342 16.0930287,6.32070904 L18.7942286,5.76794919 L20.7942286,9.23205081 L18.9649357,11.2949661 C18.9881252,11.5268304 19,11.7620284 19,12 C19,12.2379716 18.9881252,12.4731696 18.9649357,12.7050339 L20.7942286,14.7679492 L18.7942286,18.2320508 L16.0930287,17.679291 C15.7127088,17.9538658 15.303707,18.1911779 14.8713747,18.385876 L14,21 L10,21 L9.12862533,18.385876 C8.69629298,18.1911779 8.28729123,17.9538658 7.9069713,17.679291 L5.20577137,18.2320508 L3.20577137,14.7679492 L5.03506429,12.7050339 Z"></path>
|
||||
<circle cx="12" cy="12" r="1"></circle>
|
||||
</svg>
|
||||
</span>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import { mapMutations } from 'vuex'
|
||||
export default {
|
||||
name: 'Aside',
|
||||
computed: {
|
||||
view: {
|
||||
get () {
|
||||
return this.$store.getters.getView
|
||||
},
|
||||
set (val) {
|
||||
this.SET_VIEW(val)
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
...mapMutations(['SET_VIEW']),
|
||||
changeView (e) {
|
||||
this.view = e
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
svg{
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
stroke: #823aa099;
|
||||
stroke-width: 1;
|
||||
stroke-linecap: round;
|
||||
stroke-linejoin: round;
|
||||
fill: none;
|
||||
}
|
||||
.aside{
|
||||
width: 60px;
|
||||
height: 100%;
|
||||
user-select: none;
|
||||
-webkit-app-region: drag;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
border-right: 1px solid #00000010;
|
||||
span{
|
||||
-webkit-app-region: no-drag;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
writing-mode: tb-rl;
|
||||
color: #823aa055;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
cursor: pointer;
|
||||
overflow: hidden;
|
||||
&:hover{
|
||||
animation: SHAni 0.8s ease both;
|
||||
@keyframes SHAni {
|
||||
to{
|
||||
background-color: #823aa011;
|
||||
}
|
||||
}
|
||||
svg{
|
||||
animation: SHSAni 0.8s ease both;
|
||||
@keyframes SHSAni {
|
||||
to{
|
||||
stroke: #823aa0ee;
|
||||
stroke-width: 1.5;
|
||||
fill: #823aa022;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
&.active{
|
||||
svg{
|
||||
stroke: #823aa0;
|
||||
stroke-width: 2;
|
||||
fill: #823aa033;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -0,0 +1,383 @@
|
||||
<template>
|
||||
<div class="detail">
|
||||
<div class="detail-content">
|
||||
<div class="detail-header">
|
||||
<span class="detail-title">详情</span>
|
||||
<span class="detail-close" @click="closeDetail">
|
||||
<svg role="img" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" aria-labelledby="closeIconTitle">
|
||||
<title id="closeIconTitle">关闭</title>
|
||||
<path d="M6.34314575 6.34314575L17.6568542 17.6568542M6.34314575 17.6568542L17.6568542 6.34314575"></path>
|
||||
</svg>
|
||||
</span>
|
||||
</div>
|
||||
<div class="detail-body" v-show="!loading" :style="{overflowY:scroll? 'auto' : 'hidden',paddingRight: scroll ? '0': '5px' }" @mouseenter="scroll = true" @mouseleave="scroll = false">
|
||||
<div class="info" v-html="vDetail.info"></div>
|
||||
<div class="desc" v-html="vDetail.desc" v-if="show.desc"></div>
|
||||
<div class="m3u8_urls">
|
||||
<div class="title">播放:</div>
|
||||
<div class="box">
|
||||
<span v-for="(i, j) in vDetail.m3u8_urls" :key="j" @click="playEvent(i)">{{i | ftName}}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mp4_urls" v-if="show.download">
|
||||
<div class="title">下载链接:</div>
|
||||
<div class="box">
|
||||
<span v-for="(i, j) in vDetail.mp4_urls" :key="j" @click="download(i)">{{i | ftName}}</span>
|
||||
<span @click="allDownload" v-show="vDetail.mp4_urls.length > 1">全集下载</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="detail-mask" v-show="loading">
|
||||
<div class="loader"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import { mapMutations } from 'vuex'
|
||||
import tools from '../lib/site/tools'
|
||||
// const { clipboard } = require('electron')
|
||||
export default {
|
||||
name: 'detail',
|
||||
data () {
|
||||
return {
|
||||
scroll: false,
|
||||
loading: true,
|
||||
vDetail: {},
|
||||
show: {
|
||||
desc: false,
|
||||
download: false
|
||||
}
|
||||
}
|
||||
},
|
||||
filters: {
|
||||
ftName (e) {
|
||||
const name = e.split('$')[0]
|
||||
return name
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
view: {
|
||||
get () {
|
||||
return this.$store.getters.getView
|
||||
},
|
||||
set (val) {
|
||||
this.SET_VIEW(val)
|
||||
}
|
||||
},
|
||||
video: {
|
||||
get () {
|
||||
return this.$store.getters.getVideo
|
||||
},
|
||||
set (val) {
|
||||
this.SET_VIDEO(val)
|
||||
}
|
||||
},
|
||||
detail: {
|
||||
get () {
|
||||
return this.$store.getters.getDetail
|
||||
},
|
||||
set (val) {
|
||||
this.SET_DETAIL(val)
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
...mapMutations(['SET_VIEW', 'SET_VIDEO', 'SET_DETAIL']),
|
||||
closeDetail () {
|
||||
this.detail.show = false
|
||||
},
|
||||
getDetail () {
|
||||
tools.detail_get(this.detail.v.site, this.detail.v.detail).then(res => {
|
||||
this.vDetail = res
|
||||
if (res.desc.length > 0) {
|
||||
this.show.desc = true
|
||||
}
|
||||
if (res.mp4_urls.length > 0) {
|
||||
this.show.download = true
|
||||
}
|
||||
this.$nextTick(() => {
|
||||
this.loading = false
|
||||
})
|
||||
})
|
||||
},
|
||||
playEvent (e) {
|
||||
this.video = this.detail.v
|
||||
this.detail.show = false
|
||||
this.view = 'Play'
|
||||
}
|
||||
// download (e) {
|
||||
// const name = e.split('$')[0]
|
||||
// const txt = encodeURI(e.split('$')[1])
|
||||
// clipboard.writeText(txt)
|
||||
// this.$message.success(`已复制 ${name} 下载链接, 快去下载吧!`)
|
||||
// },
|
||||
// allDownload () {
|
||||
// const urls = [...this.vDetail.mp4_urls]
|
||||
// let txt = ''
|
||||
// for (const i of urls) {
|
||||
// const url = encodeURI(i.split('$')[1])
|
||||
// txt += (url + '\n')
|
||||
// }
|
||||
// clipboard.writeText(txt)
|
||||
// this.$message.success('已复制全集下载链接, 快去下载吧!')
|
||||
// }
|
||||
},
|
||||
created () {
|
||||
this.getDetail()
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss">
|
||||
.detail{
|
||||
position: absolute;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
height: 680px;
|
||||
background-color: #fff;
|
||||
box-shadow:0 -4px 12px 0 #8e8da21f;
|
||||
padding: 10px;
|
||||
color: #808695;
|
||||
z-index: 999;
|
||||
.detail-content{
|
||||
height: 660px;
|
||||
padding: 10px 40px;
|
||||
position: relative;
|
||||
.detail-header{
|
||||
width: 100%;
|
||||
height: 40px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 0 -40px;
|
||||
.detail-title{
|
||||
font-size: 16px;
|
||||
}
|
||||
.detail-close{
|
||||
margin-right: 5px;
|
||||
svg{
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
stroke: #823aa099;
|
||||
stroke-width: 1;
|
||||
stroke-linecap: round;
|
||||
stroke-linejoin: round;
|
||||
fill: none;
|
||||
&:hover{
|
||||
stroke-width: 2px;
|
||||
stroke: #823aa0aa;
|
||||
}
|
||||
}
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
.detail-body{
|
||||
height: 600px;
|
||||
overflow-y: auto;
|
||||
&::-webkit-scrollbar{
|
||||
width: 5px;
|
||||
height: 1px;
|
||||
}
|
||||
&::-webkit-scrollbar-thumb {
|
||||
border-radius: 10px;
|
||||
box-shadow: inset 0 0 5px #823aa005;
|
||||
background: #823aa055;
|
||||
position: absolute;
|
||||
}
|
||||
&::-webkit-scrollbar-track {
|
||||
box-shadow: inset 0 0 5px #823aa005;
|
||||
border-radius: 10px;
|
||||
background: #EDEDED;
|
||||
position: absolute;
|
||||
}
|
||||
.info{
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
align-items: flex-start;
|
||||
flex-wrap: wrap;
|
||||
width: 970px;
|
||||
padding: 10px;
|
||||
border: 1px solid #823aa022;
|
||||
border-radius: 2px;
|
||||
margin-bottom: 10px;
|
||||
.vodImg{
|
||||
width: 200px;
|
||||
img{
|
||||
width: 100%;
|
||||
height: auto;
|
||||
}
|
||||
}
|
||||
.vodAd{
|
||||
display: none;
|
||||
}
|
||||
.vodInfo{
|
||||
flex: 1;
|
||||
margin-left: 20px;
|
||||
overflow: hidden;
|
||||
.vodh{
|
||||
margin-bottom: 6px;
|
||||
h2{
|
||||
display: inline-block;
|
||||
margin: 0;
|
||||
}
|
||||
span{
|
||||
font-size: 12px;
|
||||
margin-left: 10px;
|
||||
}
|
||||
label{
|
||||
font-size: 20px;
|
||||
font-weight: bold;
|
||||
margin-left: 20px;
|
||||
}
|
||||
}
|
||||
.cont, .tags{
|
||||
display: none;
|
||||
}
|
||||
ul{
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
a{
|
||||
display: none;
|
||||
pointer-events: none;
|
||||
}
|
||||
li{
|
||||
list-style: none;
|
||||
font-size: 14px;
|
||||
line-height: 18px;
|
||||
height: 18px;
|
||||
overflow: hidden;
|
||||
span{
|
||||
word-wrap: nowrap;
|
||||
}
|
||||
}
|
||||
}
|
||||
.whitetitle{
|
||||
width: 100%;
|
||||
font-size: 22px;
|
||||
font-weight: bold;
|
||||
margin: 4px 0;
|
||||
}
|
||||
.people{
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
align-items: flex-start;
|
||||
flex-wrap: wrap;
|
||||
.left{
|
||||
width: 200px;
|
||||
img{
|
||||
width: 100%;
|
||||
height: auto;
|
||||
}
|
||||
}
|
||||
.right{
|
||||
flex: 1;
|
||||
margin-left: 20px;
|
||||
overflow: hidden;
|
||||
p{
|
||||
font-size: 14px;
|
||||
}
|
||||
a{
|
||||
pointer-events: none;
|
||||
color: #808695;
|
||||
text-decoration: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.desc{
|
||||
border: 1px solid #823aa033;
|
||||
padding: 10px;
|
||||
width: 970px;
|
||||
margin-bottom: 10px;
|
||||
border-radius: 2px;
|
||||
font-size: 14px;
|
||||
line-height: 20px;
|
||||
}
|
||||
.m3u8_urls, .mp4_urls{
|
||||
border: 1px solid #823aa033;
|
||||
padding: 10px;
|
||||
width: 970px;
|
||||
margin-bottom: 10px;
|
||||
border-radius: 2px;
|
||||
.title{
|
||||
font-size: 16px;
|
||||
}
|
||||
.box{
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
flex-wrap: wrap;
|
||||
span{
|
||||
font-size: 12px;
|
||||
border: 1px solid #823aa055;
|
||||
border-radius: 2px;
|
||||
cursor: pointer;
|
||||
margin: 6px 10px 0px 0px;
|
||||
padding: 8px 22px;
|
||||
&:hover{
|
||||
color: #6e7380;
|
||||
background-color: #823aa011;
|
||||
}
|
||||
}
|
||||
&::after {
|
||||
content: '';
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
.mp4_urls{
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
}
|
||||
.detail-mask{
|
||||
width: 980px;
|
||||
height: 600px;
|
||||
position: absolute;
|
||||
top: 50px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
.loader {
|
||||
color: #823aa055;
|
||||
font-size: 8px;
|
||||
width: 1em;
|
||||
height: 1em;
|
||||
border-radius: 50%;
|
||||
position: relative;
|
||||
text-indent: -9999em;
|
||||
animation: load4 1.3s infinite linear;
|
||||
transform: translateZ(0);
|
||||
}
|
||||
@keyframes load4 {
|
||||
0%,
|
||||
100% {
|
||||
box-shadow: 0 -3em 0 0.2em, 2em -2em 0 0em, 3em 0 0 -1em, 2em 2em 0 -1em, 0 3em 0 -1em, -2em 2em 0 -1em, -3em 0 0 -1em, -2em -2em 0 0;
|
||||
}
|
||||
12.5% {
|
||||
box-shadow: 0 -3em 0 0, 2em -2em 0 0.2em, 3em 0 0 0, 2em 2em 0 -1em, 0 3em 0 -1em, -2em 2em 0 -1em, -3em 0 0 -1em, -2em -2em 0 -1em;
|
||||
}
|
||||
25% {
|
||||
box-shadow: 0 -3em 0 -0.5em, 2em -2em 0 0, 3em 0 0 0.2em, 2em 2em 0 0, 0 3em 0 -1em, -2em 2em 0 -1em, -3em 0 0 -1em, -2em -2em 0 -1em;
|
||||
}
|
||||
37.5% {
|
||||
box-shadow: 0 -3em 0 -1em, 2em -2em 0 -1em, 3em 0em 0 0, 2em 2em 0 0.2em, 0 3em 0 0em, -2em 2em 0 -1em, -3em 0em 0 -1em, -2em -2em 0 -1em;
|
||||
}
|
||||
50% {
|
||||
box-shadow: 0 -3em 0 -1em, 2em -2em 0 -1em, 3em 0 0 -1em, 2em 2em 0 0em, 0 3em 0 0.2em, -2em 2em 0 0, -3em 0em 0 -1em, -2em -2em 0 -1em;
|
||||
}
|
||||
62.5% {
|
||||
box-shadow: 0 -3em 0 -1em, 2em -2em 0 -1em, 3em 0 0 -1em, 2em 2em 0 -1em, 0 3em 0 0, -2em 2em 0 0.2em, -3em 0 0 0, -2em -2em 0 -1em;
|
||||
}
|
||||
75% {
|
||||
box-shadow: 0em -3em 0 -1em, 2em -2em 0 -1em, 3em 0em 0 -1em, 2em 2em 0 -1em, 0 3em 0 -1em, -2em 2em 0 0, -3em 0em 0 0.2em, -2em -2em 0 0;
|
||||
}
|
||||
87.5% {
|
||||
box-shadow: 0em -3em 0 0, 2em -2em 0 -1em, 3em 0 0 -1em, 2em 2em 0 -1em, 0 3em 0 -1em, -2em 2em 0 0, -3em 0em 0 0, -2em -2em 0 0.2em;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -0,0 +1,344 @@
|
||||
<template>
|
||||
<div class="film">
|
||||
<div class="top" v-if="top">
|
||||
<!-- site -->
|
||||
<div class="vue-select" @mouseleave="show.site = false">
|
||||
<div class="vs-placeholder" @click="show.site = true">{{site.name}}</div>
|
||||
<div class="vs-options" v-show="show.site">
|
||||
<ul>
|
||||
<li :class="site === j ? 'active' : ''" v-for="(i, j) in sites" :key="j" @click="siteClick(i)">{{ i.name }}</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<!-- tags -->
|
||||
<div class="vue-select" @mouseleave="show.tags = false" v-if="site.tags.length > 0">
|
||||
<div class="vs-placeholder" @click="show.tags = true">{{site.tags[tag].title}}</div>
|
||||
<div class="vs-options" v-show="show.tags">
|
||||
<ul>
|
||||
<li :class="tag === j ? 'active' : ''" v-for="(i, j) in site.tags" :key="j" @click="tagClick(i, j)">{{ i.title }}</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<!-- type -->
|
||||
<div class="vue-select" @mouseleave="show.type = false" v-if="site.tags[tag].children.length > 0">
|
||||
<div class="vs-placeholder" @click="show.type = true">{{site.tags[tag].children[type].title}}</div>
|
||||
<div class="vs-options" v-show="show.type">
|
||||
<ul>
|
||||
<li :class="type === j ? 'active' : ''" v-for="(i, j) in site.tags[tag].children" :key="j" @click="typeClick(i, j)">{{ i.title }}</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div :class="[inputFocus ? 'active ': ''] + 'search'" @mouseover="inputFocus = true" @mouseleave="inputFocus = false">
|
||||
<div class="search-icon">
|
||||
<svg role="img" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" aria-labelledby="searchIconTitle">
|
||||
<title id="searchIconTitle">Search</title>
|
||||
<path d="M14.4121122,14.4121122 L20,20"></path>
|
||||
<circle cx="10" cy="10" r="6"></circle>
|
||||
</svg>
|
||||
</div>
|
||||
<input type="text" class="search-box" v-model="keywords" @keypress.enter="searchEvent">
|
||||
</div>
|
||||
</div>
|
||||
<div class="middle">
|
||||
<div class="vue-table">
|
||||
<div class="tHead">
|
||||
<span class="name">影片名称</span>
|
||||
<span class="type">类型</span>
|
||||
<span class="time">时间</span>
|
||||
<span class="operate">操作</span>
|
||||
</div>
|
||||
<div class="tBody">
|
||||
<ul v-show="!tb.loading">
|
||||
<li v-for="(i, j) in tb.list" :key="j" @click="detailEvent(i)">
|
||||
<span class="name">{{i.name}}</span>
|
||||
<span class="type">{{i.type}}</span>
|
||||
<span class="time">{{i.time}}</span>
|
||||
<span class="operate">
|
||||
<span class="btn" @click.stop="playEvent(i)">播放</span>
|
||||
<span class="btn" @click.stop="starEvent(i)">收藏</span>
|
||||
<span class="btn" @click.stop="shareEvent(i)">分享</span>
|
||||
</span>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="tBody-mask" v-show="tb.loading">
|
||||
<div class="loader"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="tFooter">
|
||||
<span class="tFooter-span">今日更新: {{ tb.update }} 条</span>
|
||||
<el-pagination small :page-size="tb.size" :total="tb.total" :current-page="tb.page" @current-change="tbPageChange" layout="total, prev, pager, next, jumper"></el-pagination>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import { mapMutations } from 'vuex'
|
||||
import { sites, getSite } from '../lib/site/sites'
|
||||
import tools from '../lib/site/tools'
|
||||
import video from '../lib/dexie/video'
|
||||
import setting from '../lib/dexie/setting'
|
||||
export default {
|
||||
name: 'film',
|
||||
data () {
|
||||
return {
|
||||
sites: sites,
|
||||
site: {},
|
||||
top: false,
|
||||
tag: 0,
|
||||
type: 0,
|
||||
keywords: '',
|
||||
id: '',
|
||||
show: {
|
||||
site: false,
|
||||
tags: false,
|
||||
type: false
|
||||
},
|
||||
inputFocus: false,
|
||||
tb: {
|
||||
list: [],
|
||||
page: 1,
|
||||
size: 50,
|
||||
total: 0,
|
||||
update: 0,
|
||||
loading: true
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
view: {
|
||||
get () {
|
||||
return this.$store.getters.getView
|
||||
},
|
||||
set (val) {
|
||||
this.SET_VIEW(val)
|
||||
}
|
||||
},
|
||||
gSite: {
|
||||
get () {
|
||||
return this.$store.getters.getSite
|
||||
},
|
||||
set (val) {
|
||||
this.SET_SITE(val)
|
||||
}
|
||||
},
|
||||
detail: {
|
||||
get () {
|
||||
return this.$store.getters.getDetail
|
||||
},
|
||||
set (val) {
|
||||
this.SET_DETAIL(val)
|
||||
}
|
||||
},
|
||||
video: {
|
||||
get () {
|
||||
return this.$store.getters.getVideo
|
||||
},
|
||||
set (val) {
|
||||
this.SET_VIDEO(val)
|
||||
}
|
||||
},
|
||||
share: {
|
||||
get () {
|
||||
return this.$store.getters.getShare
|
||||
},
|
||||
set (val) {
|
||||
this.SET_SHARE(val)
|
||||
}
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
gSite (n, o) {
|
||||
const s = getSite(n)
|
||||
this.siteClick(s)
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
...mapMutations(['SET_VIEW', 'SET_SITE', 'SET_DETAIL', 'SET_VIDEO', 'SET_SHARE']),
|
||||
init () {
|
||||
setting.find().then(res => {
|
||||
this.site = getSite(res.site)
|
||||
this.top = true
|
||||
tools.film_get(res.site).then(tRes => {
|
||||
this.tb.list = tRes.list
|
||||
this.tb.total = tRes.total
|
||||
this.tb.update = tRes.update
|
||||
this.tb.loading = false
|
||||
})
|
||||
})
|
||||
},
|
||||
siteClick (e) {
|
||||
this.site = e
|
||||
this.tb.update = 0
|
||||
this.tb.total = 0
|
||||
this.tag = 0
|
||||
this.id = e.tags[0].id
|
||||
this.tb.loading = true
|
||||
this.show.site = false
|
||||
tools.film_get(e.key, this.id).then(res => {
|
||||
this.tb.list = res.list
|
||||
this.tb.total = res.total
|
||||
this.tb.update = res.update
|
||||
this.tb.loading = false
|
||||
})
|
||||
},
|
||||
tagClick (e, n) {
|
||||
this.tb.update = 0
|
||||
this.tb.total = 0
|
||||
this.tag = n
|
||||
this.type = 0
|
||||
if (e.children.length === 0) {
|
||||
this.id = e.id
|
||||
} else {
|
||||
this.id = e.children[this.type].id
|
||||
}
|
||||
this.tb.loading = true
|
||||
this.show.tags = false
|
||||
tools.film_get(this.site.key, this.id).then(res => {
|
||||
this.tb.list = res.list
|
||||
this.tb.total = res.total
|
||||
this.tb.update = res.update
|
||||
this.tb.loading = false
|
||||
})
|
||||
},
|
||||
typeClick (e, n) {
|
||||
this.tb.update = 0
|
||||
this.tb.total = 0
|
||||
this.type = n
|
||||
this.id = e.id
|
||||
this.tb.loading = true
|
||||
this.show.type = false
|
||||
tools.film_get(this.site.key, this.id).then(res => {
|
||||
this.tb.list = res.list
|
||||
this.tb.total = res.total
|
||||
this.tb.update = res.update
|
||||
this.tb.loading = false
|
||||
})
|
||||
},
|
||||
searchEvent () {
|
||||
const flag = this.site.search
|
||||
if (flag === '') {
|
||||
this.$message.warning('该视频源不支持搜索')
|
||||
return false
|
||||
}
|
||||
this.tb.loading = true
|
||||
this.tb.update = 0
|
||||
this.tb.total = 0
|
||||
tools.search_get(this.site.key, this.keywords).then(res => {
|
||||
this.tb.list = res.list
|
||||
this.tb.total = res.total
|
||||
this.tb.loading = false
|
||||
})
|
||||
},
|
||||
detailEvent (e) {
|
||||
this.detail = {
|
||||
show: true,
|
||||
v: e
|
||||
}
|
||||
},
|
||||
playEvent (e) {
|
||||
this.video = e
|
||||
this.view = 'Play'
|
||||
},
|
||||
starEvent (e) {
|
||||
video.find({ detail: e.detail }).then(res => {
|
||||
if (res) {
|
||||
this.$message.warning('已存在')
|
||||
} else {
|
||||
video.add(e).then(res => {
|
||||
this.$message.success('收藏成功')
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
shareEvent (e) {
|
||||
this.share = {
|
||||
show: true,
|
||||
v: e
|
||||
}
|
||||
},
|
||||
tbPageChange (e) {
|
||||
this.tb.loading = true
|
||||
this.tb.page = e
|
||||
tools.film_get(this.site.key, this.id, this.tb.page).then(res => {
|
||||
this.tb.list = res.list
|
||||
this.tb.loading = false
|
||||
})
|
||||
}
|
||||
},
|
||||
created () {
|
||||
this.init()
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.film{
|
||||
height: 670px;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
animation: viewFadeIn 1s ease-in both;
|
||||
.top{
|
||||
width: 100%;
|
||||
height: 30px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
.search{
|
||||
width: 200px;
|
||||
height: 30px;
|
||||
display: flex;
|
||||
background-color: #fff;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
border-radius: 15px;
|
||||
box-shadow: 0 3px 1px -2px #8e8da233, 0 2px 2px 0 #8e8da224, 0 1px 5px 0 #8e8da21f;
|
||||
svg{
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
stroke: #823aa099;
|
||||
stroke-width: 1;
|
||||
stroke-linecap: round;
|
||||
stroke-linejoin: round;
|
||||
fill: none;
|
||||
}
|
||||
.search-icon{
|
||||
width: 40px;
|
||||
height: 30px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
.search-box{
|
||||
width: 160px;
|
||||
height: 30px;
|
||||
border-radius: 20px;
|
||||
border: none;
|
||||
background-color: #00000000;
|
||||
text-indent: 2px;
|
||||
font-size: 14px;
|
||||
&:focus{
|
||||
outline: none;
|
||||
border: none;
|
||||
}
|
||||
}
|
||||
&.active{
|
||||
box-shadow: 0 14px 26px -12px #8e8da26b, 0 4px 23px 0 #8e8da21f, 0 8px 10px -5px #8e8da233;
|
||||
svg{
|
||||
stroke-width: 1.5;
|
||||
fill: #823aa022;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.middle{
|
||||
height: 620px;
|
||||
width: 100%;
|
||||
margin-top: 10px;
|
||||
padding-bottom:0px;
|
||||
background-color: #fff;
|
||||
border-radius: 5px;
|
||||
box-shadow: 0 3px 1px -2px #8e8da233, 0 2px 2px 0 #8e8da224, 0 1px 5px 0 #8e8da21f;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
<template>
|
||||
<div class="frame">
|
||||
<span class="min" @click="frameClickEvent('min')"></span>
|
||||
<span class="close" @click="frameClickEvent('close')"></span>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
// const ipc = require('electron').ipcRenderer
|
||||
export default {
|
||||
name: 'frame',
|
||||
methods: {
|
||||
// frameClickEvent (e) {
|
||||
// ipc.send(e)
|
||||
// }
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.frame{
|
||||
width: 100%;
|
||||
height: 40px;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
align-items: center;
|
||||
user-select: none;
|
||||
-webkit-app-region: drag;
|
||||
span{
|
||||
-webkit-app-region: no-drag;
|
||||
display: inline-block;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
border-radius: 50%;
|
||||
margin-left: 10px;
|
||||
cursor: pointer;
|
||||
opacity: 0.5;
|
||||
&.min{
|
||||
background-color: #ffbe2a;
|
||||
}
|
||||
&.close{
|
||||
background-color: #ff5f56;
|
||||
}
|
||||
&:hover{
|
||||
animation: heartbeat 3s ease-in-out infinite both;
|
||||
}
|
||||
@keyframes heartbeat {
|
||||
from {
|
||||
transform: scale(1);
|
||||
transform-origin: center center;
|
||||
animation-timing-function: ease-out;
|
||||
}
|
||||
10% {
|
||||
opacity: 1;
|
||||
transform: scale(0.91);
|
||||
animation-timing-function: ease-in;
|
||||
}
|
||||
17% {
|
||||
transform: scale(0.98);
|
||||
animation-timing-function: ease-out;
|
||||
}
|
||||
33% {
|
||||
transform: scale(0.87);
|
||||
animation-timing-function: ease-in;
|
||||
}
|
||||
45% {
|
||||
transform: scale(1);
|
||||
animation-timing-function: ease-out;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,60 +0,0 @@
|
||||
<template>
|
||||
<div class="hello">
|
||||
<h1>{{ msg }}</h1>
|
||||
<p>
|
||||
For a guide and recipes on how to configure / customize this project,<br>
|
||||
check out the
|
||||
<a href="https://cli.vuejs.org" target="_blank" rel="noopener">vue-cli documentation</a>.
|
||||
</p>
|
||||
<h3>Installed CLI Plugins</h3>
|
||||
<ul>
|
||||
<li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-babel" target="_blank" rel="noopener">babel</a></li>
|
||||
<li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-router" target="_blank" rel="noopener">router</a></li>
|
||||
<li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-vuex" target="_blank" rel="noopener">vuex</a></li>
|
||||
<li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-eslint" target="_blank" rel="noopener">eslint</a></li>
|
||||
</ul>
|
||||
<h3>Essential Links</h3>
|
||||
<ul>
|
||||
<li><a href="https://vuejs.org" target="_blank" rel="noopener">Core Docs</a></li>
|
||||
<li><a href="https://forum.vuejs.org" target="_blank" rel="noopener">Forum</a></li>
|
||||
<li><a href="https://chat.vuejs.org" target="_blank" rel="noopener">Community Chat</a></li>
|
||||
<li><a href="https://twitter.com/vuejs" target="_blank" rel="noopener">Twitter</a></li>
|
||||
<li><a href="https://news.vuejs.org" target="_blank" rel="noopener">News</a></li>
|
||||
</ul>
|
||||
<h3>Ecosystem</h3>
|
||||
<ul>
|
||||
<li><a href="https://router.vuejs.org" target="_blank" rel="noopener">vue-router</a></li>
|
||||
<li><a href="https://vuex.vuejs.org" target="_blank" rel="noopener">vuex</a></li>
|
||||
<li><a href="https://github.com/vuejs/vue-devtools#vue-devtools" target="_blank" rel="noopener">vue-devtools</a></li>
|
||||
<li><a href="https://vue-loader.vuejs.org" target="_blank" rel="noopener">vue-loader</a></li>
|
||||
<li><a href="https://github.com/vuejs/awesome-vue" target="_blank" rel="noopener">awesome-vue</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'HelloWorld',
|
||||
props: {
|
||||
msg: String
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<!-- Add "scoped" attribute to limit CSS to this component only -->
|
||||
<style scoped lang="scss">
|
||||
h3 {
|
||||
margin: 40px 0 0;
|
||||
}
|
||||
ul {
|
||||
list-style-type: none;
|
||||
padding: 0;
|
||||
}
|
||||
li {
|
||||
display: inline-block;
|
||||
margin: 0 10px;
|
||||
}
|
||||
a {
|
||||
color: #42b983;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,548 @@
|
||||
<template>
|
||||
<div class="play">
|
||||
<div class="box">
|
||||
<div class="title">{{name}}</div>
|
||||
<div id="xg"></div>
|
||||
<div class="more" v-show="more">
|
||||
<span @click="nextEvent" v-show="showNext">
|
||||
<svg role="img" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" aria-labelledby="forwardIconTitle">
|
||||
<title id="forwardIconTitle">下一集</title>
|
||||
<path d="M10 14.74L3 19V5l7 4.26V5l12 7-12 7v-4.26z"></path>
|
||||
</svg>
|
||||
</span>
|
||||
<span @click="listEvent" :class="right.type === 'list' ? 'active' : ''" v-show="right.listData.length > 0">
|
||||
<svg role="img" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" aria-labelledby="dashboardIconTitle">
|
||||
<title id="dashboardIconTitle">播放列表</title>
|
||||
<rect width="20" height="20" x="2" y="2"></rect>
|
||||
<path d="M11 7L17 7M11 12L17 12M11 17L17 17"></path>
|
||||
<line x1="7" y1="7" x2="7" y2="7"></line>
|
||||
<line x1="7" y1="12" x2="7" y2="12"></line>
|
||||
<line x1="7" y1="17" x2="7" y2="17"></line>
|
||||
</svg>
|
||||
</span>
|
||||
<span @click="historyEvent" :class="right.type === 'history' ? 'active' : ''">
|
||||
<svg role="img" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" aria-labelledby="timeIconTitle">
|
||||
<title id="timeIconTitle">历史记录</title>
|
||||
<circle cx="12" cy="12" r="10"></circle>
|
||||
<polyline points="12 5 12 12 16 16"></polyline>
|
||||
</svg>
|
||||
</span>
|
||||
<span @click="starEvent" :class="isStar ? 'active' : ''" v-show="right.listData.length > 0">
|
||||
<svg role="img" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" aria-labelledby="favouriteIconTitle">
|
||||
<title id="favouriteIconTitle">收藏</title>
|
||||
<path d="M12,21 L10.55,19.7051771 C5.4,15.1242507 2,12.1029973 2,8.39509537 C2,5.37384196 4.42,3 7.5,3 C9.24,3 10.91,3.79455041 12,5.05013624 C13.09,3.79455041 14.76,3 16.5,3 C19.58,3 22,5.37384196 22,8.39509537 C22,12.1029973 18.6,15.1242507 13.45,19.7149864 L12,21 Z"></path>
|
||||
</svg>
|
||||
</span>
|
||||
<span @click="topEvent" :class="isTop ? 'active' : ''" v-show="right.listData.length > 0">
|
||||
<svg role="img" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" aria-labelledby="arrowUpIconTitle">
|
||||
<title id="arrowUpIconTitle">置顶</title>
|
||||
<path d="M9 10.5l3-3 3 3"></path>
|
||||
<path d="M12 16.5V9"></path>
|
||||
<path stroke-linecap="round" d="M12 7.5V9"></path>
|
||||
<circle cx="12" cy="12" r="10"></circle>
|
||||
</svg>
|
||||
</span>
|
||||
<span @click="detailEvent" v-show="right.listData.length > 0">
|
||||
<svg role="img" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" aria-labelledby="feedIconTitle">
|
||||
<title id="feedIconTitle">详情</title>
|
||||
<circle cx="7.5" cy="7.5" r="2.5"></circle>
|
||||
<path d="M22 13H2"></path>
|
||||
<path d="M18 6h-5m5 3h-5"></path>
|
||||
<path d="M5 2h14a3 3 0 0 1 3 3v17H2V5a3 3 0 0 1 3-3z"></path>
|
||||
</svg>
|
||||
</span>
|
||||
<!-- <span @click="smallEvent" v-show="right.listData.length > 0">
|
||||
<svg role="img" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" aria-labelledby="tvIconTitle">
|
||||
<title id="tvIconTitle">精简模式</title>
|
||||
<polygon points="20 8 20 20 4 20 4 8"></polygon>
|
||||
<polyline stroke-linejoin="round" points="8 4 12 7.917 16 4"></polyline>
|
||||
</svg>
|
||||
</span> -->
|
||||
<span @click="shareEvent" v-show="right.listData.length > 0">
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" aria-labelledby="qrIconTitle">
|
||||
<title id="qrIconTitle">分享</title>
|
||||
<rect x="10" y="3" width="7" height="7" transform="rotate(90 10 3)"></rect>
|
||||
<rect width="1" height="1" transform="matrix(-1 0 0 1 7 6)"></rect>
|
||||
<rect x="10" y="14" width="7" height="7" transform="rotate(90 10 14)"></rect>
|
||||
<rect x="6" y="17" width="1" height="1"></rect>
|
||||
<rect x="14" y="20" width="1" height="1"></rect>
|
||||
<rect x="17" y="17" width="1" height="1"></rect>
|
||||
<rect x="14" y="14" width="1" height="1"></rect>
|
||||
<rect x="20" y="17" width="1" height="1"></rect>
|
||||
<rect x="20" y="14" width="1" height="1"></rect>
|
||||
<rect x="20" y="20" width="1" height="1"></rect>
|
||||
<rect x="21" y="3" width="7" height="7" transform="rotate(90 21 3)"></rect>
|
||||
<rect x="17" y="6" width="1" height="1"></rect>
|
||||
</svg>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<transition name="slideX">
|
||||
<div v-if="right.show" class="list">
|
||||
<div class="list-top">
|
||||
<span class="list-top-title">{{ right.type === 'list' ? '播放列表' : '历史记录' }}</span>
|
||||
<span class="list-top-close" @click="closeEvent">
|
||||
<svg role="img" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" aria-labelledby="closeIconTitle">
|
||||
<title id="closeIconTitle">关闭</title>
|
||||
<path d="M6.34314575 6.34314575L17.6568542 17.6568542M6.34314575 17.6568542L17.6568542 6.34314575"></path>
|
||||
</svg>
|
||||
</span>
|
||||
</div>
|
||||
<div class="list-body" :style="{overflowY:scroll? 'auto' : 'hidden',paddingRight: scroll ? '0': '5px' }" @mouseenter="scroll = true" @mouseleave="scroll = false">
|
||||
<ul v-show="right.type === 'list'">
|
||||
<li v-show="right.listData.length === 0">无数据</li>
|
||||
<li @click="listItemEvent(j)" :class="video.index === j ? 'active' : ''" v-for="(i, j) in right.listData" :key="j">{{i | ftName}}</li>
|
||||
</ul>
|
||||
<ul v-show="right.type === 'history'">
|
||||
<li v-show="right.historyData.length > 1" @click="clearAll">清空数据</li>
|
||||
<li v-show="right.historyData.length === 0">无数据</li>
|
||||
<li @click="historyItemEvent(m)" v-for="(m, n) in right.historyData" :key="n"><span class="title">{{m.name}}</span><span @click.stop="removeItem(m)" class="delete">删除</span></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</transition>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import { mapMutations } from 'vuex'
|
||||
import tools from '../lib/site/tools'
|
||||
import history from '../lib/dexie/history'
|
||||
import video from '../lib/dexie/video'
|
||||
import 'xgplayer'
|
||||
import Hls from 'xgplayer-hls.js'
|
||||
// const { ipcRenderer: ipc } = require('electron')
|
||||
export default {
|
||||
name: 'play',
|
||||
data () {
|
||||
return {
|
||||
xg: null,
|
||||
right: {
|
||||
show: false,
|
||||
type: '',
|
||||
listData: [],
|
||||
historyData: []
|
||||
},
|
||||
config: {
|
||||
id: 'xg',
|
||||
lang: 'zh-cn',
|
||||
url: '',
|
||||
fluid: true,
|
||||
autoplay: false,
|
||||
videoInit: true,
|
||||
screenShot: true,
|
||||
keyShortcut: 'on',
|
||||
crossOrigin: true,
|
||||
defaultPlaybackRate: 1,
|
||||
playbackRate: [0.25, 0.5, 0.75, 1, 1.25, 1.5, 1.75, 2, 3, 4, 5]
|
||||
},
|
||||
name: '',
|
||||
timer: null,
|
||||
scroll: false,
|
||||
more: true,
|
||||
showNext: false,
|
||||
isStar: false,
|
||||
isTop: false
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
view: {
|
||||
get () {
|
||||
return this.$store.getters.getView
|
||||
},
|
||||
set (val) {
|
||||
this.SET_VIEW(val)
|
||||
}
|
||||
},
|
||||
video: {
|
||||
get () {
|
||||
return this.$store.getters.getVideo
|
||||
},
|
||||
set (val) {
|
||||
this.SET_VIDEO(val)
|
||||
}
|
||||
},
|
||||
detail: {
|
||||
get () {
|
||||
return this.$store.getters.getDetail
|
||||
},
|
||||
set (val) {
|
||||
this.SET_DETAIL(val)
|
||||
}
|
||||
},
|
||||
share: {
|
||||
get () {
|
||||
return this.$store.getters.getShare
|
||||
},
|
||||
set (val) {
|
||||
this.SET_SHARE(val)
|
||||
}
|
||||
}
|
||||
},
|
||||
filters: {
|
||||
ftName (e) {
|
||||
return e.split('$')[0]
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
view () {
|
||||
this.right.show = false
|
||||
this.right.type = ''
|
||||
},
|
||||
video: {
|
||||
handler () {
|
||||
this.getUrls()
|
||||
},
|
||||
deep: true
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
...mapMutations(['SET_VIEW', 'SET_DETAIL', 'SET_VIDEO', 'SET_SHARE']),
|
||||
getUrls () {
|
||||
if (this.timer !== null) {
|
||||
clearInterval(this.timer)
|
||||
this.timer = null
|
||||
}
|
||||
if (this.xg) {
|
||||
this.xg.pause()
|
||||
this.xg.off('play', () => {
|
||||
console.log('play off')
|
||||
})
|
||||
}
|
||||
this.changeVideo()
|
||||
tools.detail_get(this.video.site, this.video.detail).then(res => {
|
||||
this.name = this.video.name
|
||||
this.right.listData = res.m3u8_urls
|
||||
if (res.m3u8_urls.length > 1) {
|
||||
const m3 = res.m3u8_urls
|
||||
const arr = []
|
||||
for (const i of m3) {
|
||||
arr.push(i.split('$')[1])
|
||||
}
|
||||
this.xg.src = arr[this.video.index]
|
||||
this.showNext = true
|
||||
} else {
|
||||
const link = res.m3u8_urls[this.video.index]
|
||||
const src = link.split('$')[1]
|
||||
this.xg.src = src
|
||||
this.showNext = false
|
||||
}
|
||||
const currentTime = this.video.currentTime
|
||||
if (currentTime !== '') {
|
||||
this.xg.play()
|
||||
this.xg.once('playing', () => {
|
||||
this.xg.currentTime = currentTime
|
||||
})
|
||||
} else {
|
||||
this.xg.play()
|
||||
}
|
||||
this.onPlayVideo()
|
||||
})
|
||||
},
|
||||
changeVideo () {
|
||||
this.checkStar()
|
||||
this.checkTop()
|
||||
this.name = ''
|
||||
},
|
||||
checkStar () {
|
||||
video.find({ detail: this.video.detail }).then(res => {
|
||||
if (res) {
|
||||
this.isStar = true
|
||||
} else {
|
||||
this.isStar = false
|
||||
}
|
||||
})
|
||||
},
|
||||
// checkTop () {
|
||||
// ipc.send('checkTop')
|
||||
// ipc.on('isTop', (e, flag) => {
|
||||
// this.isTop = flag
|
||||
// })
|
||||
// },
|
||||
onPlayVideo () {
|
||||
this.more = true
|
||||
const h = { ...this.video }
|
||||
history.find({ detail: h.detail }).then(res => {
|
||||
if (res) {
|
||||
history.update(res.id, h)
|
||||
} else {
|
||||
h.currentTime = ''
|
||||
delete h.id
|
||||
history.add(h)
|
||||
}
|
||||
})
|
||||
this.timerEvent(h.detail)
|
||||
},
|
||||
timerEvent (d) {
|
||||
this.timer = setInterval(() => {
|
||||
history.find({ detail: d }).then(res => {
|
||||
if (res) {
|
||||
const h = { ...this.video }
|
||||
h.currentTime = this.xg.currentTime
|
||||
delete h.id
|
||||
history.update(res.id, h)
|
||||
}
|
||||
})
|
||||
}, 10000)
|
||||
},
|
||||
closeEvent () {
|
||||
this.right.show = false
|
||||
this.right.type = ''
|
||||
},
|
||||
nextEvent () {
|
||||
const v = { ...this.video }
|
||||
const i = v.index + 1
|
||||
if (i < this.right.listData.length) {
|
||||
this.video.index++
|
||||
} else {
|
||||
this.$message.warning('这是最后一集了.')
|
||||
}
|
||||
},
|
||||
listEvent () {
|
||||
if (this.right.type === 'list') {
|
||||
this.right.show = false
|
||||
this.right.type = ''
|
||||
} else {
|
||||
this.right.show = true
|
||||
this.right.type = 'list'
|
||||
}
|
||||
},
|
||||
historyEvent () {
|
||||
if (this.right.type === 'history') {
|
||||
this.right.show = false
|
||||
this.right.type = ''
|
||||
} else {
|
||||
this.right.show = true
|
||||
this.right.type = 'history'
|
||||
}
|
||||
history.all().then(res => {
|
||||
this.right.historyData = res.reverse()
|
||||
})
|
||||
},
|
||||
starEvent () {
|
||||
video.find({ detail: this.video.detail }).then(res => {
|
||||
if (res) {
|
||||
video.remove(this.video.id).then(r => {
|
||||
this.$message.info('删除成功')
|
||||
this.isStar = false
|
||||
})
|
||||
} else {
|
||||
const v = { ...this.video }
|
||||
if (v.id) {
|
||||
delete v.id
|
||||
}
|
||||
video.add(v).then(r => {
|
||||
this.$message.success('收藏成功')
|
||||
this.isStar = true
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
topEvent () {
|
||||
ipc.send('top')
|
||||
this.checkTop()
|
||||
},
|
||||
detailEvent () {
|
||||
this.detail = {
|
||||
show: true,
|
||||
v: this.video
|
||||
}
|
||||
},
|
||||
smallEvent () {}, // TODO 小窗口模式
|
||||
shareEvent () {
|
||||
this.share = {
|
||||
show: true,
|
||||
v: this.video
|
||||
}
|
||||
},
|
||||
clearAll () {
|
||||
history.clear().then(res => {
|
||||
this.right.historyData = []
|
||||
})
|
||||
},
|
||||
listItemEvent (n) {
|
||||
this.video.index = n
|
||||
},
|
||||
historyItemEvent (e) {
|
||||
this.video = e
|
||||
},
|
||||
removeItem (e) {
|
||||
history.remove(e.id).then(res => {
|
||||
history.all().then(e => {
|
||||
this.right.historyData = e.reverse()
|
||||
})
|
||||
})
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
this.xg = new Hls(this.config)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.play{
|
||||
position: relative;
|
||||
height: 660px;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
background-color: #ffffff;
|
||||
border-radius: 5px;
|
||||
box-shadow: 0 3px 1px -2px #8e8da233, 0 2px 2px 0 #8e8da224, 0 1px 5px 0 #8e8da21f;
|
||||
.box{
|
||||
width: 92%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
.title{
|
||||
width: 100%;
|
||||
height: 40px;
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
}
|
||||
.more{
|
||||
width: 100%;
|
||||
height: 60px;
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
span{
|
||||
display: flex;
|
||||
margin-right: 10px;
|
||||
cursor: pointer;
|
||||
&:hover{
|
||||
svg{
|
||||
stroke: #823aa0ee;
|
||||
stroke-width: 1.5;
|
||||
fill: #823aa022;
|
||||
}
|
||||
}
|
||||
&.active{
|
||||
svg{
|
||||
stroke: #823aa0;
|
||||
stroke-width: 2;
|
||||
fill: #823aa033;
|
||||
}
|
||||
}
|
||||
}
|
||||
svg{
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
stroke: #823aa099;
|
||||
stroke-width: 1;
|
||||
stroke-linecap: round;
|
||||
stroke-linejoin: round;
|
||||
fill: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
.list{
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
width: 300px;
|
||||
height: 100%;
|
||||
border: 1px solid #00000022;
|
||||
background-color: #fff;
|
||||
z-index: 555;
|
||||
border-radius: 3px;
|
||||
padding: 6px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
svg{
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
stroke: #823aa099;
|
||||
stroke-width: 1;
|
||||
stroke-linecap: round;
|
||||
stroke-linejoin: round;
|
||||
fill: none;
|
||||
}
|
||||
.list-top{
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
height: 30px;
|
||||
.list-top-title{
|
||||
font-size: 16px;
|
||||
}
|
||||
.list-top-close{
|
||||
display: inline-block;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
.list-body{
|
||||
flex: 1;
|
||||
overflow-y: auto;
|
||||
&::-webkit-scrollbar{
|
||||
width: 5px;
|
||||
height: 1px;
|
||||
}
|
||||
&::-webkit-scrollbar-thumb {
|
||||
border-radius: 10px;
|
||||
box-shadow: inset 0 0 5px #823aa005;
|
||||
background: #823aa055;
|
||||
position: absolute;
|
||||
}
|
||||
&::-webkit-scrollbar-track {
|
||||
box-shadow: inset 0 0 5px #823aa005;
|
||||
border-radius: 10px;
|
||||
background: #EDEDED;
|
||||
position: absolute;
|
||||
}
|
||||
ul{
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
list-style: none;
|
||||
li{
|
||||
position: relative;
|
||||
height: 28px;
|
||||
width: 100%;
|
||||
line-height: 28px;
|
||||
padding-left: 10px;
|
||||
font-size: 14px;
|
||||
cursor: pointer;
|
||||
color: #808695;
|
||||
&.active{
|
||||
background-color: #823aa011;
|
||||
}
|
||||
&:hover{
|
||||
background-color: #823aa011;
|
||||
.delete{
|
||||
display: inline-block;
|
||||
}
|
||||
}
|
||||
.title{
|
||||
display: inline-block;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
width: 231px;
|
||||
}
|
||||
.delete{
|
||||
display: none;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
height: 28px;
|
||||
width: 50px;
|
||||
text-align: center;
|
||||
&:hover{
|
||||
background-color: #823aa022;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.slideX-enter-active, .slideX-leave-active{
|
||||
transition: all .5s ease-in-out;
|
||||
}
|
||||
.slideX-enter, .slideX-leave-to{
|
||||
transform: translateX(100%);
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -0,0 +1,152 @@
|
||||
<template>
|
||||
<div class="setting" v-if="show.setting">
|
||||
<div class="logo"><img src="@/assets/image/logo.png"></div>
|
||||
<div class="info"><a href="https://github.com/Hunlongyu/ZY-Player">官网</a><a href="https://github.com/Hunlongyu/ZY-Player/issues">反馈</a></div>
|
||||
<div class="change">
|
||||
<div class="vue-select" @mouseleave="show.language = false">
|
||||
<div class="vs-placeholder" @click="show.language = true">{{$t('language')}}</div>
|
||||
<div class="vs-options" v-show="show.language">
|
||||
<ul>
|
||||
<li :class="s.language === i.key ? 'active' : ''" v-for="(i, j) in languages" :key="j" @click="languageClick(i.key)">{{ i.name }}</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="vue-select" @mouseleave="show.site = false">
|
||||
<div class="vs-placeholder" @click="show.site = true">{{$t('default_site')}}</div>
|
||||
<div class="vs-options" v-show="show.site">
|
||||
<ul>
|
||||
<li :class="s.site === i.key ? 'active' : ''" v-for="(i, j) in sites" :key="j" @click="siteClick(i.key)">{{ i.name }}</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="theme">主题</div>
|
||||
<div class="qrcode">喝咖啡</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import { mapMutations } from 'vuex'
|
||||
import setting from '../lib/dexie/setting'
|
||||
import { sites } from '../lib/site/sites'
|
||||
export default {
|
||||
name: 'setting',
|
||||
data () {
|
||||
return {
|
||||
s: {},
|
||||
languages: [
|
||||
{
|
||||
key: 'zhCn',
|
||||
name: '中文'
|
||||
},
|
||||
{
|
||||
key: 'en',
|
||||
name: 'English'
|
||||
}
|
||||
],
|
||||
sites: sites,
|
||||
show: {
|
||||
setting: false,
|
||||
language: false,
|
||||
site: false
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
theme: {
|
||||
get () {
|
||||
return this.$store.getters.getTheme
|
||||
},
|
||||
set (val) {
|
||||
this.SET_THEME(val)
|
||||
}
|
||||
},
|
||||
language: {
|
||||
get () {
|
||||
return this.$store.getters.getLanguage
|
||||
},
|
||||
set (val) {
|
||||
this.SET_LANGUAGE(val)
|
||||
}
|
||||
},
|
||||
site: {
|
||||
get () {
|
||||
return this.$store.getters.getSite
|
||||
},
|
||||
set (val) {
|
||||
this.SET_SITE(val)
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
...mapMutations(['SET_THEME', 'SET_LANGUAGE', 'SET_SITE']),
|
||||
languageClick (e) {
|
||||
this.language = e
|
||||
this.show.language = false
|
||||
this.$i18n.locale = e
|
||||
this.s.language = e
|
||||
setting.update(this.s).then(res => {
|
||||
this.$message.success('设置成功')
|
||||
})
|
||||
},
|
||||
siteClick (e) {
|
||||
this.site = e
|
||||
this.show.site = false
|
||||
this.s.site = e
|
||||
setting.update(this.s).then(res => {
|
||||
this.$message.success('设置成功')
|
||||
})
|
||||
}
|
||||
},
|
||||
created () {
|
||||
setting.find().then(res => {
|
||||
this.s = res
|
||||
this.$i18n.locale = this.s.language
|
||||
this.show.setting = true
|
||||
})
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.setting{
|
||||
height: 660px;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
background-color: #ffffff;
|
||||
border-radius: 5px;
|
||||
box-shadow: 0 3px 1px -2px #8e8da233, 0 2px 2px 0 #8e8da224, 0 1px 5px 0 #8e8da21f;
|
||||
.logo{
|
||||
margin-top: 40px;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
img{
|
||||
width: 120px;
|
||||
height: auto;
|
||||
}
|
||||
}
|
||||
.info{
|
||||
width: 100%;
|
||||
margin-top: 20px;
|
||||
text-align: center;
|
||||
a{
|
||||
text-decoration: none;
|
||||
margin: 0 10px;
|
||||
font-size: 14px;
|
||||
color: #808695;
|
||||
&:hover{
|
||||
color: #4c4f57;
|
||||
}
|
||||
}
|
||||
}
|
||||
.change{
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
padding-left: 20px;
|
||||
margin-top: 40px;
|
||||
.vue-select{
|
||||
margin-right: 20px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -0,0 +1,199 @@
|
||||
<template>
|
||||
<div class="share" id="share" @click="shareClickEvent">
|
||||
<div class="left">
|
||||
<img :src="this.card.img" alt="">
|
||||
</div>
|
||||
<div class="right">
|
||||
<div class="title">{{ card.name }}</div>
|
||||
<qrcode-vue id="qr" :value="value" :size="160" level="L" />
|
||||
<div class="tips">
|
||||
<p>长按识别二维码, 即可播放.</p>
|
||||
<p><img src="@/assets/image/logo.png"></p>
|
||||
<p class="zy">『ZY Player』提供技术支持.严禁传播违法资源</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="share-mask" v-show="loading">
|
||||
<div class="loader"></div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import { mapMutations } from 'vuex'
|
||||
import tools from '../lib/site/tools'
|
||||
import QrcodeVue from 'qrcode.vue'
|
||||
import html2canvas from 'html2canvas'
|
||||
// const { clipboard, nativeImage } = require('electron')
|
||||
export default {
|
||||
name: 'share',
|
||||
data () {
|
||||
return {
|
||||
card: {
|
||||
img: '',
|
||||
name: '',
|
||||
png: ''
|
||||
},
|
||||
value: 'https://www.baidu.com',
|
||||
loading: true
|
||||
}
|
||||
},
|
||||
components: {
|
||||
QrcodeVue
|
||||
},
|
||||
computed: {
|
||||
share: {
|
||||
get () {
|
||||
return this.$store.getters.getShare
|
||||
},
|
||||
set (val) {
|
||||
this.SET_SHARE(val)
|
||||
}
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
share: {
|
||||
handler () {
|
||||
this.getDetail()
|
||||
},
|
||||
deep: true
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
...mapMutations(['SET_SHARE']),
|
||||
// getDetail () {
|
||||
// this.loading = true
|
||||
// tools.detail_get(this.share.v.site, this.share.v.detail).then(res => {
|
||||
// const info = res.info
|
||||
// const parser = new DOMParser()
|
||||
// const html = parser.parseFromString(info, 'text/html')
|
||||
// const img = html.querySelector('img').src
|
||||
// this.card.img = img
|
||||
// this.card.name = this.share.v.name
|
||||
// this.loading = false
|
||||
// this.$nextTick(() => {
|
||||
// const dom = document.getElementById('share')
|
||||
// html2canvas(dom, { allowTaint: true, useCORS: true }).then(res => {
|
||||
// const png = res.toDataURL('image/png')
|
||||
// const p = nativeImage.createFromDataURL(png)
|
||||
// clipboard.writeImage(p)
|
||||
// this.$message.success('已复制到剪贴板中, 快去分享吧~')
|
||||
// this.share.show = true
|
||||
// })
|
||||
// })
|
||||
// })
|
||||
// },
|
||||
shareClickEvent () {
|
||||
this.share = {
|
||||
show: false,
|
||||
v: {}
|
||||
}
|
||||
}
|
||||
},
|
||||
created () {
|
||||
this.getDetail()
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.share{
|
||||
position: absolute;
|
||||
bottom: 20px;
|
||||
right: 20px;
|
||||
width: 540px;
|
||||
height: 360px;
|
||||
background-color: #fff;
|
||||
border-radius: 2px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
border: 1px solid #cfcfcf;
|
||||
padding: 20px;
|
||||
z-index: 888;
|
||||
.left, .right{
|
||||
width: 50%;
|
||||
height: 100%;
|
||||
}
|
||||
.left{
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
img{
|
||||
height: 320px;
|
||||
width: auto;
|
||||
max-width: 240px;
|
||||
}
|
||||
}
|
||||
.right{
|
||||
.title{
|
||||
font-size: 18px;
|
||||
color: #666;
|
||||
margin-bottom: 10px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
#qr{
|
||||
text-align: center;
|
||||
}
|
||||
.tips{
|
||||
font-size: 14px;
|
||||
text-align: center;
|
||||
color: #808695;
|
||||
img{
|
||||
width: 50px;
|
||||
}
|
||||
.zy{
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
}
|
||||
.share-mask{
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
background-color: #fff;
|
||||
.loader {
|
||||
color: #823aa055;
|
||||
font-size: 8px;
|
||||
width: 1em;
|
||||
height: 1em;
|
||||
border-radius: 50%;
|
||||
position: relative;
|
||||
text-indent: -9999em;
|
||||
animation: load4 1.3s infinite linear;
|
||||
transform: translateZ(0);
|
||||
}
|
||||
@keyframes load4 {
|
||||
0%,
|
||||
100% {
|
||||
box-shadow: 0 -3em 0 0.2em, 2em -2em 0 0em, 3em 0 0 -1em, 2em 2em 0 -1em, 0 3em 0 -1em, -2em 2em 0 -1em, -3em 0 0 -1em, -2em -2em 0 0;
|
||||
}
|
||||
12.5% {
|
||||
box-shadow: 0 -3em 0 0, 2em -2em 0 0.2em, 3em 0 0 0, 2em 2em 0 -1em, 0 3em 0 -1em, -2em 2em 0 -1em, -3em 0 0 -1em, -2em -2em 0 -1em;
|
||||
}
|
||||
25% {
|
||||
box-shadow: 0 -3em 0 -0.5em, 2em -2em 0 0, 3em 0 0 0.2em, 2em 2em 0 0, 0 3em 0 -1em, -2em 2em 0 -1em, -3em 0 0 -1em, -2em -2em 0 -1em;
|
||||
}
|
||||
37.5% {
|
||||
box-shadow: 0 -3em 0 -1em, 2em -2em 0 -1em, 3em 0em 0 0, 2em 2em 0 0.2em, 0 3em 0 0em, -2em 2em 0 -1em, -3em 0em 0 -1em, -2em -2em 0 -1em;
|
||||
}
|
||||
50% {
|
||||
box-shadow: 0 -3em 0 -1em, 2em -2em 0 -1em, 3em 0 0 -1em, 2em 2em 0 0em, 0 3em 0 0.2em, -2em 2em 0 0, -3em 0em 0 -1em, -2em -2em 0 -1em;
|
||||
}
|
||||
62.5% {
|
||||
box-shadow: 0 -3em 0 -1em, 2em -2em 0 -1em, 3em 0 0 -1em, 2em 2em 0 -1em, 0 3em 0 0, -2em 2em 0 0.2em, -3em 0 0 0, -2em -2em 0 -1em;
|
||||
}
|
||||
75% {
|
||||
box-shadow: 0em -3em 0 -1em, 2em -2em 0 -1em, 3em 0em 0 -1em, 2em 2em 0 -1em, 0 3em 0 -1em, -2em 2em 0 0, -3em 0em 0 0.2em, -2em -2em 0 0;
|
||||
}
|
||||
87.5% {
|
||||
box-shadow: 0em -3em 0 0, 2em -2em 0 -1em, 3em 0 0 -1em, 2em 2em 0 -1em, 0 3em 0 -1em, -2em 2em 0 0, -3em 0em 0 0, -2em -2em 0 0.2em;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -0,0 +1,160 @@
|
||||
<template>
|
||||
<div class="star">
|
||||
<div class="vue-table">
|
||||
<div class="tHead">
|
||||
<span class="name">影片名称</span>
|
||||
<span class="type">类型</span>
|
||||
<span class="time">时间</span>
|
||||
<span class="from">来源</span>
|
||||
<span class="operate" style="width: 160px">操作</span>
|
||||
</div>
|
||||
<div class="tBody">
|
||||
<ul v-show="!loading">
|
||||
<li v-for="(i, j) in data" :key="j" @click="detailEvent(i)">
|
||||
<span class="name">{{i.name}}</span>
|
||||
<span class="type">{{i.type}}</span>
|
||||
<span class="time">{{i.time}}</span>
|
||||
<span class="from">{{i.site | ftSite}}</span>
|
||||
<span class="operate" style="width: 160px">
|
||||
<span class="btn" @click.stop="playEvent(i)">播放</span>
|
||||
<span class="btn" @click.stop="deleteEvent(i)">删除</span>
|
||||
<span class="btn" @click.stop="shareEvent(i)">分享</span>
|
||||
<span class="btn" @click.stop="updateEvent(i)">同步</span>
|
||||
</span>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="tBody-mask" v-show="loading">
|
||||
<div class="loader"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="tFooter">
|
||||
<span class="tFooter-span">共 {{data.length}} 条数据</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import { mapMutations } from 'vuex'
|
||||
import tools from '../lib/site/tools'
|
||||
import video from '../lib/dexie/video'
|
||||
import { sites, getSite } from '../lib/site/sites'
|
||||
export default {
|
||||
name: 'star',
|
||||
data () {
|
||||
return {
|
||||
sites: sites,
|
||||
data: [],
|
||||
loading: true
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
view: {
|
||||
get () {
|
||||
return this.$store.getters.getView
|
||||
},
|
||||
set (val) {
|
||||
this.SET_VIEW(val)
|
||||
}
|
||||
},
|
||||
detail: {
|
||||
get () {
|
||||
return this.$store.getters.getDetail
|
||||
},
|
||||
set (val) {
|
||||
this.SET_DETAIL(val)
|
||||
}
|
||||
},
|
||||
video: {
|
||||
get () {
|
||||
return this.$store.getters.getVideo
|
||||
},
|
||||
set (val) {
|
||||
this.SET_VIDEO(val)
|
||||
}
|
||||
},
|
||||
share: {
|
||||
get () {
|
||||
return this.$store.getters.getShare
|
||||
},
|
||||
set (val) {
|
||||
this.SET_SHARE(val)
|
||||
}
|
||||
}
|
||||
},
|
||||
filters: {
|
||||
ftSite (e) {
|
||||
const name = getSite(e).name
|
||||
return name
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
view () {
|
||||
this.getAllStar()
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
...mapMutations(['SET_VIEW', 'SET_DETAIL', 'SET_VIDEO', 'SET_SHARE']),
|
||||
detailEvent (e) {
|
||||
this.detail = {
|
||||
show: true,
|
||||
v: e
|
||||
}
|
||||
},
|
||||
playEvent (e) {
|
||||
this.video = e
|
||||
this.view = 'Play'
|
||||
},
|
||||
deleteEvent (e) {
|
||||
video.remove(e.id).then(res => {
|
||||
if (res) {
|
||||
this.$message.warning('删除失败')
|
||||
} else {
|
||||
this.$message.success('删除成功')
|
||||
}
|
||||
this.getAllStar()
|
||||
})
|
||||
},
|
||||
shareEvent (e) {
|
||||
this.share = {
|
||||
show: true,
|
||||
v: e
|
||||
}
|
||||
},
|
||||
updateEvent (e) {
|
||||
tools.detail_get(e.site, e.detail).then(res => {
|
||||
const nameOne = e.name.replace(/\s*/g, '')
|
||||
const nameTwo = res.name.replace(/\s*/g, '')
|
||||
if (nameOne === nameTwo) {
|
||||
this.$message.info('同步成功, 未查询到更新.')
|
||||
} else {
|
||||
const h = e
|
||||
h.name = res.name
|
||||
video.update(h.id, h).then(res => {
|
||||
this.$message.success('同步成功, 查询到更新.')
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
getAllStar () {
|
||||
video.all().then(res => {
|
||||
this.data = res.reverse()
|
||||
this.loading = false
|
||||
})
|
||||
}
|
||||
},
|
||||
created () {
|
||||
this.getAllStar()
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.star{
|
||||
height: 660px;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
background-color: #ffffff;
|
||||
border-radius: 5px;
|
||||
box-shadow: 0 3px 1px -2px #8e8da233, 0 2px 2px 0 #8e8da224, 0 1px 5px 0 #8e8da21f;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
import Vue from 'vue'
|
||||
import Aside from './Aside'
|
||||
import Detail from './Detail'
|
||||
import Film from './Film'
|
||||
import Frame from './Frame'
|
||||
import Play from './Play'
|
||||
import Setting from './Setting'
|
||||
import Share from './Share'
|
||||
import Star from './Star'
|
||||
|
||||
export default {
|
||||
registerComponents () {
|
||||
Vue.component('Aside', Aside)
|
||||
Vue.component('Detail', Detail)
|
||||
Vue.component('Film', Film)
|
||||
Vue.component('Frame', Frame)
|
||||
Vue.component('Play', Play)
|
||||
Vue.component('Setting', Setting)
|
||||
Vue.component('Share', Share)
|
||||
Vue.component('Star', Star)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user