remove all files and reset project

This commit is contained in:
hunlongyu
2020-01-13 10:42:21 +08:00
parent 87760286db
commit 6e2e8e457e
40 changed files with 0 additions and 27282 deletions

View File

@@ -1,2 +0,0 @@
> 1%
last 2 versions

View File

@@ -1,5 +0,0 @@
[*.{js,jsx,ts,tsx,vue}]
indent_style = space
indent_size = 2
trim_trailing_whitespace = true
insert_final_newline = true

1
.env
View File

@@ -1 +0,0 @@
GH_TOKEN=7c1142e2f154c8c678bb762732dbcc2a63df9835

View File

@@ -1,17 +0,0 @@
module.exports = {
root: true,
env: {
node: true
},
'extends': [
'plugin:vue/essential',
'@vue/standard'
],
rules: {
'no-console': process.env.NODE_ENV === 'production' ? 'error' : 'off',
'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off'
},
parserOptions: {
parser: 'babel-eslint'
}
}

24
.gitignore vendored
View File

@@ -1,24 +0,0 @@
.DS_Store
node_modules
/dist
# local env files
.env.local
.env.*.local
# Log files
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# Editor directories and files
.idea
.vscode
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
#Electron-builder output
/dist_electron

21
LICENSE
View File

@@ -1,21 +0,0 @@
MIT License
Copyright (c) 2019 Hunlongyu
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@@ -1,59 +0,0 @@
<p align="center">
<img src="https://forthebadge.com/images/badges/built-with-love.svg">
<img src="https://forthebadge.com/images/badges/made-with-vue.svg">
<p>
<p align="center">
<img alt="GitHub" src="https://img.shields.io/github/license/Hunlongyu/ZY-Player?style=for-the-badge">
<img alt="GitHub All Releases" src="https://img.shields.io/github/downloads/Hunlongyu/ZY-Player/total?style=for-the-badge">
<img alt="GitHub release (latest by date including pre-releases)" src="https://img.shields.io/github/v/release/Hunlongyu/ZY-Player?include_prereleases&style=for-the-badge">
<p>
# ZY-Player
资源播放器, 提供影视资源的搜索,查看,播放,搜藏等功能.
### 截图:
![001.png](https://i.loli.net/2020/01/08/Fs1VyNzBfAldajr.png)
主界面 ⬆
![002.png](https://i.loli.net/2020/01/08/MOiRmvG17STYbp4.png)
搜索 ⬆
![003.png](https://i.loli.net/2020/01/08/XzJm4HYdnOjMGqN.png)
详情 ⬆
![004.png](https://i.loli.net/2020/01/08/t6GWIOghBUAEZuD.png)
播放 ⬆
![005.png](https://i.loli.net/2020/01/08/kqhtTD8WoUsvdyw.png)
搜藏 ⬆
### 下载地址:
蓝奏云: https://www.lanzous.com/i8jnk9e
### 未完成:
1. 主题: 暗黑主题
2. 更新: 自动更新以及手动更新
### 重要:
所有资源来自网上, 该软件不参与任何制作, 上传, 储存, 下载等内容. 该软件仅供学习参考, 请于安装后24小时内删除.
## Project setup
```
yarn install
```
### Compiles and hot-reloads for development
```
yarn serve
```
### Compiles and minifies for production
```
yarn build
```
### Lints and fixes files
```
yarn lint
```
### Customize configuration
See [Configuration Reference](https://cli.vuejs.org/config/).

View File

@@ -1,9 +0,0 @@
module.exports = {
presets: [
'@vue/app'
],
plugins: [['import', {
'libraryName': 'view-design',
'libraryDirectory': 'src/components'
}]]
}

15183
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,46 +0,0 @@
{
"name": "zy-player",
"version": "0.6.5",
"private": false,
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"lint": "vue-cli-service lint",
"electron:build": "vue-cli-service electron:build",
"dev": "vue-cli-service electron:serve",
"postinstall": "electron-builder install-app-deps",
"postuninstall": "electron-builder install-app-deps",
"eb": "vue-cli-service electron:build -p always",
"patch": "npm version patch && git push origin master && git push origin --tags",
"minor": "npm version minor && git push origin master && git push origin --tags",
"major": "npm version major && git push origin master && git push origin --tags"
},
"main": "background.js",
"dependencies": {
"axios": "^0.19.0",
"core-js": "^2.6.5",
"nedb": "^1.8.0",
"view-design": "^4.0.2",
"vue": "^2.6.10",
"vue-router": "^3.0.3",
"vuex": "^3.0.1",
"xgplayer": "^2.4.1",
"xgplayer-hls.js": "^2.1.6"
},
"devDependencies": {
"@vue/cli-plugin-babel": "^3.12.0",
"@vue/cli-plugin-eslint": "^3.12.0",
"@vue/cli-service": "^3.12.0",
"@vue/eslint-config-standard": "^4.0.0",
"babel-eslint": "^10.0.1",
"babel-plugin-import": "^1.13.0",
"electron": "7.1.7",
"electron-updater": "^4.2.0",
"eslint": "^5.16.0",
"eslint-plugin-vue": "^5.0.0",
"sass": "^1.19.0",
"sass-loader": "^8.0.0",
"vue-cli-plugin-electron-builder": "^1.4.2",
"vue-template-compiler": "^2.6.10"
}
}

View File

@@ -1,5 +0,0 @@
module.exports = {
plugins: {
autoprefixer: {}
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 264 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 91 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

View File

@@ -1,17 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<title>ZY Player</title>
</head>
<body>
<noscript>
<strong>We're sorry but evt doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
</noscript>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>

View File

@@ -1,73 +0,0 @@
<template>
<div id="app" :class="getTheme.color">
<Layout class="box">
<Sider class="sider" width="70"><ZYSider /></Sider>
<Layout>
<Header class="header"><ZYHeader /></Header>
<ZYContent class="content">
<router-view />
</ZYContent>
</Layout>
</Layout>
</div>
</template>
<script>
import { mapGetters, mapActions } from 'vuex'
import ZYSider from '@/components/zy_sider.vue'
import ZYHeader from '@/components/zy_header.vue'
import ZYContent from '@/components/zy_content.vue'
import setting from './plugin/nedb/setting'
export default {
name: 'app',
data () {
return {}
},
computed: {
...mapGetters([
'getTheme'
])
},
components: {
ZYSider,
ZYHeader,
ZYContent
},
methods: {
...mapActions([
'changeTheme'
])
},
beforeCreate () {},
created () {
setting.find({ $or: [{ theme: 'light' }, { theme: 'dark' }] }).then(e => {
if (e.length <= 0) {
setting.add({ theme: 'light' }).then(res => {
this.changeTheme({ id: res._id, color: res.theme })
})
} else {
this.changeTheme({ id: e[0]._id, color: e[0].theme })
}
})
}
}
</script>
<style lang="scss">
@import './assets/global/global.scss';
@import './assets/theme/dark.scss';
@import './assets/theme/light.scss';
html, body, #app, .box{
height: 100%;
}
.box{
.header{
width: 100%;
height: 50px;
padding: 0;
}
.content{
width: 100%;
height: 100%;
}
}
</style>

View File

@@ -1,50 +0,0 @@
.detail{
padding: 10px;
.detail-box{
border: 1px solid #ddd;
padding: 10px;
display: flex;
justify-content: flex-start;
align-items: flex-start;
margin-bottom: 10px;
flex-wrap: wrap;
.vodImg{
width: 200px;
img{
width: 100%;
height: auto;
}
}
.vodInfo{
flex: 1;
overflow: hidden;
margin-left: 20px;
.vodh{
h2{
display: inline-block;
}
span{
font-size: 12px;
color: #999;
margin-left: 10px;
}
label{
font-size: 20px;
font-weight: bold;
color: #f90;
margin-left: 20px;
}
}
li{
list-style: none;
font-size: 12px;
color: #666;
height: 20px;
overflow: hidden;
a{
pointer-events: none;
}
}
}
}
}

View File

@@ -1,7 +0,0 @@
.dark{
.sider,.header,.content{
background-color: #000;
color: #eee;
border: 1px solid #ccc;
}
}

View File

@@ -1,56 +0,0 @@
.light{
.sider,.header,.content{
background-color: #fff;
color: #515a6e;
}
.sider{
.sider-box{
color: #808695;
i{
&:hover{
color: #515a6e;
background-color: #efefef;
}
&.active{
color: #515a6e;
background-color: #efefef;
border-left: 4px solid #515a6e;
}
}
}
}
.header{
.header-box{
color: #808695;
i{
&:hover{
color: #515a6e;
background-color: #efefef;
border-bottom: 1px solid #808695;
}
}
}
}
.content{
border: 1px solid #dcdee2;
}
.search{
.search-middle{
.ivu-table-cell{
button{
margin: 0 4px;
}
}
}
.search-bottom{
border-top: 1px solid #f0f0f0;
}
}
.collection{
.ivu-table-cell{
button{
margin: 0 4px;
}
}
}
}

View File

@@ -1,109 +0,0 @@
/* global __static */
'use strict'
import { app, protocol, ipcMain, BrowserWindow } from 'electron'
import {
createProtocol
} from 'vue-cli-plugin-electron-builder/lib'
import { autoUpdater } from 'electron-updater'
import path from 'path'
const isDevelopment = process.env.NODE_ENV !== 'production'
// Keep a global reference of the window object, if you don't, the window will
// be closed automatically when the JavaScript object is garbage collected.
let win
// Scheme must be registered before the app is ready
protocol.registerSchemesAsPrivileged([{ scheme: 'app', privileges: { secure: true, standard: true } }])
function createWindow () {
// Create the browser window.
win = new BrowserWindow({
width: 1080,
height: 720,
frame: false,
webPreferences: {
webSecurity: false,
nodeIntegration: true
},
icon: path.join(__static, 'icon.png')
})
if (process.env.WEBPACK_DEV_SERVER_URL) {
// Load the url of the dev server if in development mode
win.loadURL(process.env.WEBPACK_DEV_SERVER_URL)
if (!process.env.IS_TEST) win.webContents.openDevTools()
} else {
createProtocol('app')
// Load the index.html when not in development
win.loadURL('app://./index.html')
autoUpdater.checkForUpdatesAndNotify()
}
win.on('closed', () => {
win = null
})
}
// Quit when all windows are closed.
app.on('window-all-closed', () => {
// On macOS it is common for applications and their menu bar
// to stay active until the user quits explicitly with Cmd + Q
if (process.platform !== 'darwin') {
app.quit()
}
})
app.on('activate', () => {
// On macOS it's common to re-create a window in the app when the
// dock icon is clicked and there are no other windows open.
if (win === null) {
createWindow()
}
})
ipcMain.on('min', e => win.minimize())
ipcMain.on('max', e => {
if (win.isMaximized()) {
win.unmaximize()
} else {
win.maximize()
}
})
ipcMain.on('close', e => win.close())
// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs.
app.on('ready', async () => {
if (isDevelopment && !process.env.IS_TEST) {
// Install Vue Devtools
// Devtools extensions are broken in Electron 6.0.0 and greater
// See https://github.com/nklayman/vue-cli-plugin-electron-builder/issues/378 for more info
// Electron will not launch with Devtools extensions installed on Windows 10 with dark mode
// If you are not using Windows 10 dark mode, you may uncomment these lines
// In addition, if the linked issue is closed, you can upgrade electron and uncomment these lines
// try {
// await installVueDevtools()
// } catch (e) {
// console.error('Vue Devtools failed to install:', e.toString())
// }
}
createWindow()
})
// Exit cleanly on request from parent process in development mode.
if (isDevelopment) {
if (process.platform === 'win32') {
process.on('message', data => {
if (data === 'graceful-exit') {
app.quit()
}
})
} else {
process.on('SIGTERM', () => {
app.quit()
})
}
}

View File

@@ -1,13 +0,0 @@
<template>
<router-view />
</template>
<script>
export default {
name: 'zy_content',
methods: {
switchTheme (e) {
this.theme = e
}
}
}
</script>

View File

@@ -1,39 +0,0 @@
<template>
<Row class="header-box">
<Icon type="md-remove" @click="clickFrameEvent('min')" />
<Icon type="md-add" @click="clickFrameEvent('max')" />
<Icon type="md-close" @click="clickFrameEvent('close')" />
</Row>
</template>
<script>
const { ipcRenderer: ipc } = require('electron')
export default {
name: 'zy_header',
methods: {
clickFrameEvent (e) {
ipc.send(e)
}
}
}
</script>
<style lang="scss" scoped>
.header-box{
position: absolute;
top: 0;
left: 70px;
width: calc(100% - 70px);
height: 50px;
-webkit-app-region: drag;
-webkit-user-select: none;
display: flex;
justify-content: flex-end;
i{
font-size: 20px;
width:50px;
height:50px;
line-height:50px;
cursor: pointer;
-webkit-app-region: no-drag;
}
}
</style>

View File

@@ -1,52 +0,0 @@
<template>
<Row class="sider-box">
<div class="top">
<Icon title="搜索" :class="iconActive === 'search' ? 'active': ''" type="md-search" @click="iconClickEvent('search')"/>
<Icon title="详情" v-show="Object.keys(video).length !== 0" :class="iconActive === 'detail' ? 'active': ''" type="md-list" @click="iconClickEvent('detail')"/>
<Icon title="播放" v-show="Object.keys(video).length !== 0" :class="iconActive === 'play' ? 'active': ''" type="md-play" @click="iconClickEvent('play')"/>
<Icon title="收藏" :class="iconActive === 'collection' ? 'active': ''" type="md-star" @click="iconClickEvent('collection')"/>
</div>
<div class="bottom">
<Icon title="设置" :class="iconActive === 'settings' ? 'active': ''" type="md-settings" @click="iconClickEvent('settings')"/>
</div>
</Row>
</template>
<script>
export default {
name: 'zy-sider',
computed: {
iconActive () {
return this.$store.getters.getIconActive
},
video () {
return this.$store.getters.getVideo
}
},
methods: {
iconClickEvent (e) {
this.$router.push({ name: e })
this.$store.commit('SET_ICON_ACTIVE', e)
}
}
}
</script>
<style lang="scss" scoped>
.sider-box{
height: 100%;
position: relative;
-webkit-app-region: drag;
-webkit-user-select: none;
.bottom{
position: absolute;
bottom: 0;
}
i{
-webkit-app-region: no-drag;
font-size: 32px;
width: 70px;
height: 70px;
line-height: 70px;
cursor: pointer;
}
}
</style>

View File

@@ -1,29 +0,0 @@
const sites = [
{
id: 'okzy',
name: 'OK资源网',
url: 'https://www.okzy.co'
},
{
id: 'zuidazy',
name: '最大资源网',
url: 'http://www.zuidazy1.com'
},
{
id: 'subo',
name: '速播资源站',
url: 'https://www.subo988.com'
},
{
id: 'zuixinzy',
name: '最新资源网',
url: 'http://www.zuixinzy.cc'
},
{
id: '123ku',
name: '123资源网',
url: 'https://www.123ku.com'
}
]
export default sites

View File

@@ -1,94 +0,0 @@
import axios from 'axios'
import sites from './sites'
const zy = {
num: 0,
page: 1,
key: '',
site: {},
list: [],
getInfoRequire () {
return new Promise((resolve, reject) => {
const key = encodeURI(this.key)
const params = `${this.site.url}/index.php?m=vod-search-pg-${this.page}-wd-${key}.html`
axios.get(params).then(res => {
this.getInfoHtml(res.data).then(res => {
resolve(res)
})
}).catch(err => {
reject(err)
})
})
},
getInfoHtml (txt) {
return new Promise((resolve, reject) => {
const parser = new DOMParser()
const html = parser.parseFromString(txt, 'text/html')
const list = html.querySelectorAll('.xing_vb li')
let d = {
list: [],
num: 0
}
for (let i = 1; i < list.length - 1; i++) {
let info = {
name: list[i].childNodes[1].innerText,
detail: this.site.url + list[i].childNodes[1].childNodes[0].getAttribute('href'),
category: list[i].childNodes[3].innerText,
time: list[i].childNodes[5].innerText,
index: 0,
urls: [],
check: false
}
d.list.push(info)
}
let num = html.querySelectorAll('.nvc dd span')[1].innerText
num = parseInt(num)
d.num = num
resolve(d)
})
},
info (n = 0, p = 1, k = null) {
return new Promise((resolve, reject) => {
this.page = p
this.key = k
this.num = n
this.site = sites[this.num]
this.getInfoRequire().then(res => {
resolve(res)
})
})
},
detail (url) {
return new Promise((resolve, reject) => {
axios.get(url).then(res => {
resolve(this.getDetailUrls(res.data))
}).catch(err => {
reject(err)
})
})
},
getDetailUrls (txt) {
return new Promise((resolve, reject) => {
const parser = new DOMParser()
let html = parser.parseFromString(txt, 'text/html')
let data = {
box: null,
info: null,
urls: []
}
data.box = html.querySelector('.vodBox').innerHTML
data.info = html.querySelector('.vodplayinfo').innerHTML
let urls = html.querySelectorAll('.vodplayinfo li')
let arr = []
for (let i in urls) {
let j = urls[i].innerText
if (j !== undefined && j.indexOf('.m3u8') !== -1) {
arr.push(urls[i].innerText)
}
}
data.urls = arr
resolve(data)
})
}
}
export default zy

View File

@@ -1,13 +0,0 @@
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
import '@/plugin/iview/'
Vue.config.productionTip = false
new Vue({
router,
store,
render: h => h(App)
}).$mount('#app')

View File

@@ -1,27 +0,0 @@
import Vue from 'vue'
import 'view-design/dist/styles/iview.css'
import {
Layout, Sider, Header, Content, Row, Col,
Icon, Button, Input, Select, Option, Table,
Message, Notice, Page
} from 'view-design'
Vue.component('Layout', Layout)
Vue.component('Sider', Sider)
Vue.component('Header', Header)
Vue.component('Content', Content)
Vue.component('Row', Row)
Vue.component('Col', Col)
Vue.component('Icon', Icon)
Vue.component('Button', Button)
Vue.component('Input', Input)
Vue.component('Select', Select)
Vue.component('Option', Option)
Vue.component('Table', Table)
Vue.component('Page', Page)
Vue.prototype.$Message = Message
Vue.prototype.$Notice = Notice
Vue.prototype.$Notice.config({
top: 60
})

View File

@@ -1,36 +0,0 @@
import Nedb from 'nedb'
export default class {
constructor () {
this.db = null
}
create (db) {
const name = process.env.NODE_ENV === 'development' ? 'ZY-dev' : 'ZY'
const database = {}
database.setting = new Nedb({
filename: name + db.setting,
autoload: true
})
database.video = new Nedb({
filename: name + db.video,
autoload: true
})
return database
}
init () {
if (this.db) {
return this.db
}
this.db = this.create({
setting: '-setting',
video: '-video'
})
return this.db
}
}

View File

@@ -1,32 +0,0 @@
import DB from './index'
const db = new DB()
const connect = db.init()
const setting = connect.setting
export default {
add (data) {
return new Promise((resolve, reject) => {
setting.insert(data, (err, docs) => {
if (err) { reject(err) }
resolve(docs)
})
})
},
find (data) {
return new Promise((resolve, reject) => {
setting.find(data, (err, docs) => {
if (err) { reject(err) }
resolve(docs)
})
})
},
update (id, data) {
return new Promise((resolve, reject) => {
setting.update({ _id: id }, { $set: data }, (err, docs) => {
if (err) { reject(err) }
resolve(docs)
})
})
}
}

View File

@@ -1,49 +0,0 @@
// import DB from './index'
import DB from './index'
const db = new DB()
const connect = db.init()
const video = connect.video
export default {
add (data) {
return new Promise((resolve, reject) => {
video.insert(data, (err, docs) => {
if (err) { reject(err) }
resolve(docs)
})
})
},
find (data) {
return new Promise((resolve, reject) => {
video.find(data, (err, docs) => {
if (err) { reject(err) }
resolve(docs)
})
})
},
update (id, data) {
return new Promise((resolve, reject) => {
video.find({ _id: id }, { $set: data }, (err, docs) => {
if (err) { reject(err) }
resolve(docs)
})
})
},
remove (id) {
return new Promise((resolve, reject) => {
video.remove({ _id: id }, {}, (err, docs) => {
if (err) { reject(err) }
resolve(docs)
})
})
},
removeAll () {
return new Promise((resolve, reject) => {
video.remove({}, { multi: true }, (err, docs) => {
if (err) { reject(err) }
resolve(docs)
})
})
}
}

View File

@@ -1,37 +0,0 @@
import Vue from 'vue'
import Router from 'vue-router'
import Search from './views/Search.vue'
Vue.use(Router)
export default new Router({
// mode: 'history',
// base: process.env.BASE_URL,
routes: [
{
path: '/',
name: 'search',
component: Search
},
{
path: '/detail',
name: 'detail',
component: () => import(/* webpackChunkName: "about" */ './views/Detail.vue')
},
{
path: '/settings',
name: 'settings',
component: () => import(/* webpackChunkName: "about" */ './views/Settings.vue')
},
{
path: '/play',
name: 'play',
component: () => import(/* webpackChunkName: "about" */ './views/Player.vue')
},
{
path: '/collection',
name: 'collection',
component: () => import(/* webpackChunkName: "about" */ './views/Collection.vue')
}
]
})

View File

@@ -1,57 +0,0 @@
import Vue from 'vue'
import Vuex from 'vuex'
import setting from '@/plugin/nedb/setting'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
site: 0,
theme: {
id: '',
color: 'light'
},
iconActive: 'search',
video: {}
},
getters: {
getSite: state => {
return state.site
},
getTheme: state => {
return state.theme
},
getIconActive: state => {
return state.iconActive
},
getVideo: state => {
return state.video
}
},
mutations: {
SET_SITE: (state, payload) => {
state.site = payload
},
SET_THEME: (state, payload) => {
state.theme = payload
},
SET_ICON_ACTIVE: (state, payload) => {
state.iconActive = payload
},
SET_VIDEO: (state, payload) => {
state.video = payload
}
},
actions: {
changeTheme: ({ commit }, payload) => {
setting.update(payload.id, { theme: payload.color }).then(res => {
commit('SET_THEME', payload)
})
},
changeSite: ({ commit }, payload) => {
setting.update(payload.id, { site: payload.site }).then(res => {
commit('SET_SITE', payload)
})
}
}
})

View File

@@ -1,90 +0,0 @@
<template>
<Row class="collection">
<div class="collectionBox">
<Table stripe :columns="columns" :data="data" :loading="loading">
<template slot-scope="{ row }" slot="action" >
<Button size="small" @click="play(row)">Play</Button>
<Button size="small" type="info" ghost @click="detailShow(row)">Detail</Button>
<Button size="small" type="error" ghost @click="deleteLi(row)">Delete</Button>
</template>
</Table>
</div>
</Row>
</template>
<script>
import db from '@/plugin/nedb/video'
export default {
name: 'collection',
data () {
return {
columns: [
{
title: 'Name',
key: 'name',
sortable: true
},
{
title: 'Category',
key: 'category',
width: 120,
align: 'center'
},
{
title: 'Time',
key: 'time',
width: 180,
align: 'center'
},
{
title: 'Action',
slot: 'action',
align: 'center',
width: 260
}
],
data: [],
loading: false,
detail: false
}
},
methods: {
getList () {
db.find().then(res => {
this.data = res
})
},
play (e) {
this.$router.push({ name: 'play' })
this.$store.commit('SET_ICON_ACTIVE', 'play')
this.$store.commit('SET_VIDEO', e)
},
detailShow (e) {
this.$store.commit('SET_ICON_ACTIVE', 'detail')
this.$store.commit('SET_VIDEO', e)
this.$router.push({ name: 'detail' })
},
deleteLi (e) {
db.remove(e._id).then(res => {
this.getList()
})
}
},
created () {
this.getList()
}
}
</script>
<style lang="scss" scoped>
.collection{
height: 100%;
position: relative;
.collectionBox{
position: absolute;
width: 100%;
top: 0px;
height: 100%;
overflow: scroll;
&::-webkit-scrollbar { display: none }
}
}
</style>

View File

@@ -1,71 +0,0 @@
<template>
<div class="detail">
<div v-show="box" class="detail-box" v-html="data.box"></div>
<div v-show="box" class="detail-box" v-html="data.info"></div>
<div v-show="box" class="detail-box">
<Button v-for="(i, j) in data.urls" :key="j" @click="playBtn(i, j, video)">{{i | ftLink}}</Button>
</div>
</div>
</template>
<script>
import zy from '@/lib/util.zy'
import { mapMutations } from 'vuex'
export default {
name: 'detail',
data () {
return {
data: {
box: null,
info: null,
m3u8: null
},
box: false
}
},
filters: {
ftLink (e) {
let name = e.split('$')[0]
return name
}
},
computed: {
video () {
return this.$store.getters.getVideo
}
},
methods: {
...mapMutations([
'SET_VIDEO'
]),
async getDetail () {
this.box = false
let url = this.video.detail
this.data = await zy.detail(url)
this.video.urls = this.data.urls
this.video.check = true
this.box = true
},
playBtn (i, j, e) {
this.video.index = j
this.$store.commit('SET_VIDEO', this.video)
this.$router.push({ name: 'play' })
this.$store.commit('SET_ICON_ACTIVE', 'play')
}
},
created () {
this.getDetail()
}
}
</script>
<style lang="scss" scoped>
.detail{
.btns{
margin-bottom: 10px;
}
.detail-box{
button{
margin: 4px;
}
}
}
</style>

View File

@@ -1,120 +0,0 @@
<template>
<Row class="player">
<div class="title">{{ video.name }} -- {{ info }}</div>
<div class="playerBox">
<div id="xg"></div>
</div>
<div class="list">
<Button v-for="(i, j) in video.urls" :key="j" @click="playBtn(i, j, video)">{{i | ftLink}}</Button>
</div>
</Row>
</template>
<script>
import 'xgplayer'
import Hls from 'xgplayer-hls.js'
import zy from '@/lib/util.zy'
export default {
name: 'player',
data () {
return {
data: {},
url: null,
xg: null,
info: '',
config: {
id: 'xg',
url: null,
fluid: true,
autoplay: true,
keyShortcut: 'on',
defaultPlaybackRate: 1,
playbackRate: [0.5, 0.75, 1, 1.5, 2]
}
}
},
filters: {
ftLink (e) {
let name = e.split('$')[0]
return name
}
},
computed: {
video () {
return this.$store.getters.getVideo
}
},
methods: {
init () {
if (this.video.check) {
let url = this.video.urls[this.video.index].split('$')[1]
this.info = this.video.urls[this.video.index].split('$')[0]
this.$nextTick(() => {
this.playEvent(url)
})
} else {
this.getDetail()
}
},
async getDetail () {
let d = this.video.detail
let index = this.video.index
this.data = await zy.detail(d)
let urls = this.data.urls
this.video.urls = urls
this.video.check = true
let playUrl = urls[index].split('$')[1]
this.info = urls[index].split('$')[0]
this.$nextTick(() => {
this.playEvent(playUrl)
})
},
playEvent (e) {
this.config.url = e
this.xg = new Hls(this.config)
},
playBtn (i, j, e) {
this.video.index = j
let url = this.video.urls[this.video.index].split('$')[1]
this.info = this.video.urls[this.video.index].split('$')[0]
this.xg.src = url
}
},
created () {
this.init()
},
destroyed () {
this.xg.destroy()
}
}
</script>
<style lang="scss" scoped>
.player{
padding: 10px;
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
.title{
margin-bottom: 8px;
font-size: 18px;
text-align: left;
width: 800px;
}
.playerBox{
width: 100%;
max-width: 800px;
border: 1px solid #000;
}
.list{
margin-top: 10px;
width: 800px;
text-align: left;
button{
margin-right: 10px;
margin-bottom: 10px;
}
}
}
</style>

View File

@@ -1,221 +0,0 @@
<template>
<div class="search">
<div :class="active ? 'search-top haveList': 'search-top'" >
<Input class="search-input" v-model.trim="txt" size="large" search placeholder="输入需要搜索的资源名称..." @on-search="searchEvent" clearable @on-clear="searchClear">
<Select slot="prepend" v-model="site" style="width: 120px;">
<Option v-for="(i, j) in sites" :key="j" :value="j">{{i.name}}</Option>
</Select>
<!-- eslint-disable-next-line -->
</Input>
</div>
<div class="search-middle" v-if="active">
<Table stripe :columns="columns" :data="data" :loading="loading">
<template slot-scope="{ row }" slot="action" >
<Button size="small" @click="play(row)">Play</Button>
<Button size="small" @click="collection(row)">Star</Button>
<Button size="small" @click="detail(row)">Detail</Button>
</template>
</Table>
</div>
<div class="search-bottom" v-if="active">
<Page :total="num" :current.sync="page" :page-size="50" show-total @on-change="onChange" />
</div>
</div>
</template>
<script>
import db from '@/plugin/nedb/video'
import zy from '@/lib/util.zy'
import sites from '@/lib/sites'
import { mapGetters, mapMutations } from 'vuex'
export default {
name: 'search',
data () {
return {
sites: sites,
txt: '',
active: false,
columns: [
{
title: 'Name',
key: 'name',
minWidth: 240
},
{
title: 'Category',
key: 'category',
width: 100,
align: 'center'
},
{
title: 'Time',
key: 'time',
width: 110,
align: 'center'
},
{
title: 'Action',
slot: 'action',
align: 'center',
width: 260
}
],
data: [],
page: 1,
num: 0,
loading: true
}
},
computed: {
...mapGetters(['getVideo']),
...mapGetters({
getSite: 'getSite'
}),
site: {
get () {
return this.getSite
},
set (val) {
this.SET_SITE(val)
}
}
},
methods: {
...mapMutations(['SET_SITE']),
async searchEvent () {
if (this.txt !== '') {
this.active = true
this.loading = true
this.page = 1
let z = await zy.info(this.site, this.page, this.txt)
this.data = z.list
this.num = z.num
this.loading = false
}
},
searchClear () {
this.txt = ''
this.active = false
this.loading = true
},
async onChange () {
let z = await zy.info(this.site, this.page, this.txt)
this.data = z.list
this.num = z.num
},
play (e) {
if (this.getVideo.detail !== e.detail) {
this.$store.commit('SET_VIDEO', e)
}
this.$store.commit('SET_ICON_ACTIVE', 'play')
this.$router.push({ name: 'play' })
},
async collection (e) {
let d = await zy.detail(e.detail)
let data = {
category: e.category,
detail: e.detail,
name: e.name,
time: e.time,
type: 'single',
index: 0,
urls: [],
check: false
}
data.urls = d.urls
data.check = true
this.$store.commit('SET_VIDEO', data)
db.find({ detail: data.detail }).then(res => {
if (res.length >= 1) {
this.$Notice.warning({
title: '资源已存在',
backgroud: true
})
} else {
db.add(data).then(res => {
this.$Notice.success({
title: '收藏成功',
backgroud: true
})
})
}
})
},
detail (e) {
this.$store.commit('SET_VIDEO', e)
this.$store.commit('SET_ICON_ACTIVE', 'detail')
this.$router.push({ name: 'detail' })
}
},
created () {
// this.sites = sites
}
}
</script>
<style lang="scss" scoped>
.search{
height: 100%;
position: relative;
.search-top{
position: absolute;
top: 0;
left: 0;
height: 60px;
width: 100%;
display: flex;
justify-content: center;
align-items: center;
animation: slideDown 0.6s cubic-bezier(0.250, 0.460, 0.450, 0.940) both;
.search-input{
width: 80%;
}
&.haveList{
animation: slideUp 0.4s cubic-bezier(0.250, 0.460, 0.450, 0.940) both;
}
@keyframes slideUp {
from {
height: 100%;
}
to{
height: 60px;
}
}
@keyframes slideDown {
from {
height: 60px;
}
to{
height: 100%;
}
}
}
.search-middle{
position: absolute;
top: 60px;
width: 100%;
height: calc(100% - 120px);
padding: 10px;
overflow: scroll;
&::-webkit-scrollbar { display: none }
animation: fade-in 1.4s cubic-bezier(0.390, 0.575, 0.565, 1.000) both;
}
@keyframes fade-in {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
.search-bottom{
position: absolute;
bottom: 0;
left: 0;
width: 100%;
height: 60px;
display: flex;
align-items: center;
justify-content: space-around;
padding: 0 10px;
}
}
</style>

View File

@@ -1,62 +0,0 @@
<template>
<Row class="setting">
<div class="item about">
<div class="title">关于:</div>
<ul>
<li>作者: <a href="https://github.com/Hunlongyu">Hunlongyu</a></li>
<li>官网: <a href="https://zy_player.hunlongyu.fun">ZY Player</a></li>
<li>反馈: <a href="https://github.com/Hunlongyu/ZY-Player/issues">Issues</a></li>
</ul>
</div>
<div class="item upgrade">
<div class="title">更新:</div>
<div class="btns">版本: v0.6.5</div>
<div class="btns"><Button @click="checkUpgrade">检查更新</Button></div>
</div>
<div class="item theme">
<div class="title">主题:</div>
<div class="btns">
<Button @click="changeTheme({ id: getTheme.id, color: 'light' })">light</Button>
<Button @click="changeTheme({ id: getTheme.id, color: 'dark' })">Dark</Button>
</div>
</div>
</Row>
</template>
<script>
import { mapGetters, mapActions } from 'vuex'
export default {
name: 'settings',
computed: {
...mapGetters([
'getTheme'
])
},
methods: {
...mapActions([
'changeTheme'
]),
checkUpgrade () {}
}
}
</script>
<style lang="scss" scoped>
.setting{
padding: 10px;
.item{
margin-bottom: 10px;
.title{
font-size: 16px;
}
ul{
margin-left: 10px;
list-style: none;
}
.btns{
margin-left: 10px;
button{
margin-right: 10px;
}
}
}
}
</style>

View File

@@ -1,21 +0,0 @@
module.exports = {
pluginOptions: {
electronBuilder: {
builderOptions: {
win: {
icon: './public/app.ico'
},
mac: {
icon: './public/app.png'
},
productName: 'ZY Player',
publish: ['github']
},
chainWebpackRendererProcess: config => {
if (process.env.NODE_ENV === 'development') {
config.plugins.delete('prefetch')
}
}
}
}
}

10535
yarn.lock

File diff suppressed because it is too large Load Diff