🎃 remove all file

This commit is contained in:
hunlongyu
2020-04-14 21:54:25 +08:00
parent d74485eaaf
commit 5b52dad32b
78 changed files with 0 additions and 14486 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

View File

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

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) 2020 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,50 +0,0 @@
<p align="center">
<img src="https://i.loli.net/2020/02/22/jvfBbnEuOq5RS9J.png" >
</p>
<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
资源播放器, 提供影视资源的浏览,搜索,播放,收藏,查看详情.
1. 视频连播
2. 手机观看
3. 分享资源
4. 多主题
5. ...
目前**新版本**正在筹备开发...[点击这里可以查看开发计划](https://github.com/Hunlongyu/ZY-Player/projects/3).
大家有什么新的需求建议欢迎踊跃提出[点击这里提意见](https://github.com/Hunlongyu/ZY-Player/issues/14).
(喜欢的这款播放器的,欢迎点击右上角的★,收藏一下.谢谢~)
### 下载 (目前最新版: v0.9.1):
1. [Github -- 官方下载](https://github.com/Hunlongyu/ZY-Player/releases)
2. [蓝奏云 -- 快速下载](https://www.lanzous.com/b04s6a3re) 密码:95px
### 截图:
主界面 ⬇
![film.png](https://i.loli.net/2020/01/19/U1EPzoJHhTDnuxA.png)
暗黑主题 ⬇
![dark.png](https://i.loli.net/2020/01/20/eU6J3EFcPTXnjlK.png)
搜索 ⬇
![search.png](https://i.loli.net/2020/01/19/BPvJKxlnNfquRI4.png)
搜索结果 ⬇
![search-keyword.png](https://i.loli.net/2020/01/19/6wfY3rPBokM15hl.png)
详情 ⬇
![detail.png](https://i.loli.net/2020/01/19/CN8E1ikyMbhzo9t.png)
播放 ⬇
![play.png](https://i.loli.net/2020/01/19/4XlJRqmx2y8zAec.png)
收藏 ⬇
![star.png](https://i.loli.net/2020/01/19/Q2fkWUvaXKZJcS4.png)
### 重要:
所有资源来自网上, 该软件不参与任何制作, 上传, 储存, 下载等内容. 该软件仅供学习参考, 请于安装后24小时内删除.

View File

@@ -1,14 +0,0 @@
module.exports = {
'presets': [
'@vue/cli-plugin-babel/preset'
],
'plugins': [
[
'component',
{
'libraryName': 'element-ui',
'styleLibraryName': 'theme-chalk'
}
]
]
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 233 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 831 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 80 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 353 KiB

View File

@@ -1 +0,0 @@
zy.hly120506.top

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 23 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 23 KiB

View File

@@ -1 +0,0 @@
<svg width="48" height="48" xmlns="http://www.w3.org/2000/svg"><g fill="none" fill-rule="evenodd"><path fill-opacity=".32" fill="#535FD7" d="M0 0h24v48H0z"/><path fill-opacity=".16" fill="#2FEAFC" d="M28 0h20v20H28z"/><path d="M14 9v4h20V9a1 1 0 0 0-1-1H15a1 1 0 0 0-1 1z" fill="#7C85E1"/><path d="M39 15H9a1 1 0 0 0-1 1v16a1 1 0 0 0 1 1h3V23h24v10h3a1 1 0 0 0 1-1V16a1 1 0 0 0-1-1zM20 40v-6h-6z" fill="#61EFFD"/><path d="M14 25v7h7a1 1 0 0 1 1 1v7h11a1 1 0 0 0 1-1V25H14z" fill="#7C85E1"/></g></svg>

Before

Width:  |  Height:  |  Size: 500 B

View File

@@ -1 +0,0 @@
<svg width="48" height="48" xmlns="http://www.w3.org/2000/svg"><g fill="none" fill-rule="evenodd"><path fill-opacity=".64" fill="#93F4FE" d="M0 0h24v48H0z"/><path fill-opacity=".64" fill="#FFCF7B" d="M28 0h20v20H28z"/><path d="M14 9v4h20V9a1 1 0 0 0-1-1H15a1 1 0 0 0-1 1z" fill="#7C85E1"/><path d="M39 15H9a1 1 0 0 0-1 1v16a1 1 0 0 0 1 1h3V23h24v10h3a1 1 0 0 0 1-1V16a1 1 0 0 0-1-1zM20 40v-6h-6z" fill="#535FD7"/><path d="M14 25v7h7a1 1 0 0 1 1 1v7h11a1 1 0 0 0 1-1V25H14z" fill="#7C85E1"/></g></svg>

Before

Width:  |  Height:  |  Size: 500 B

View File

@@ -1 +0,0 @@
<svg width="48" height="48" xmlns="http://www.w3.org/2000/svg"><g fill="none" fill-rule="evenodd"><path fill-opacity=".32" fill="#535FD7" d="M0 0h24v48H0z"/><path fill-opacity=".16" fill="#2FEAFC" d="M28 0h20v20H28z"/><path d="M40 19v-5a2 2 0 0 0-2-2H10a2 2 0 0 0-2 2v5h32z" fill="#61EFFD"/><path d="M8 23v11a2 2 0 0 0 2 2h28a2 2 0 0 0 2-2V23H8zm13 8h-9v-2h9v2zm15 0h-4v-2h4v2z" fill="#7C85E1"/></g></svg>

Before

Width:  |  Height:  |  Size: 405 B

View File

@@ -1 +0,0 @@
<svg width="48" height="48" xmlns="http://www.w3.org/2000/svg"><g fill="none" fill-rule="evenodd"><g fill-opacity=".64"><path fill="#93F4FE" d="M0 0h24v48H0z"/><path fill="#FFCF7B" d="M28 0h20v20H28z"/></g><path d="M40 19v-5a2 2 0 0 0-2-2H10a2 2 0 0 0-2 2v5h32z" fill="#535FD7"/><path d="M8 23v11a2 2 0 0 0 2 2h28a2 2 0 0 0 2-2V23H8zm13 8h-9v-2h9v2zm15 0h-4v-2h4v2z" fill="#7C85E1"/></g></svg>

Before

Width:  |  Height:  |  Size: 393 B

View File

@@ -1 +0,0 @@
<svg width="48" height="48" xmlns="http://www.w3.org/2000/svg"><g fill="none" fill-rule="evenodd"><path fill-opacity=".16" fill="#2FEAFC" d="M28 0h20v20H28z"/><path fill-opacity=".32" fill="#535FD7" d="M0 0h24v48H0z"/><path d="M18 9.256l-9.287 2.786A1.001 1.001 0 0 0 8 13v26l10-3.656V9.256z" fill="#61EFFD"/><path fill="#7C85E1" d="M28 12.523l-8-3.2v26.154l8 3.2z"/><path d="M40 9l-10 3.656v26.088l9.287-2.786c.423-.127.713-.517.713-.958V9z" fill="#61EFFD"/></g></svg>

Before

Width:  |  Height:  |  Size: 469 B

View File

@@ -1 +0,0 @@
<svg width="48" height="48" xmlns="http://www.w3.org/2000/svg"><g fill="none" fill-rule="evenodd"><path fill-opacity=".64" fill="#FFCF7B" d="M28 0h20v20H28z"/><path fill-opacity=".64" fill="#93F4FE" d="M0 0h24v48H0z"/><path d="M18 9.256l-9.287 2.786A1.001 1.001 0 0 0 8 13v26l10-3.656V9.256z" fill="#535FD7"/><path fill="#7C85E1" d="M28 12.523l-8-3.2v26.154l8 3.2z"/><path d="M40 9l-10 3.656v26.088l9.287-2.786c.423-.127.713-.517.713-.958V9z" fill="#535FD7"/></g></svg>

Before

Width:  |  Height:  |  Size: 469 B

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 9.7 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 9.7 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 7.7 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 7.7 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 9.5 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 10 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 21 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 21 KiB

View File

@@ -1 +0,0 @@
<svg width="32" height="32" xmlns="http://www.w3.org/2000/svg"><defs><linearGradient x1="20.313%" y1="83.13%" x2="79.211%" y2="18.665%" id="a"><stop stop-color="#93F4FE" offset="0%"/><stop stop-color="#535FD7" offset="100%"/></linearGradient><linearGradient x1="50%" y1="0%" x2="77.135%" y2="77.109%" id="b"><stop stop-color="#FFF" stop-opacity=".48" offset="0%"/><stop stop-color="#FFF" stop-opacity="0" offset="100%"/></linearGradient></defs><g fill="none" fill-rule="evenodd"><path d="M16 0C7.163 0 0 7.163 0 16s7.163 16 16 16 16-7.163 16-16C31.99 7.168 24.832.01 16 0z" fill="url(#a)"/><path d="M29.012 25.313A11.98 11.98 0 0 1 25 26c-6.627 0-12-5.373-12-12 0-6.235 4.756-11.36 10.838-11.944C28.705 4.8 31.993 10.016 32 16c0 3.474-1.107 6.69-2.988 9.313z" fill="url(#b)"/></g></svg>

Before

Width:  |  Height:  |  Size: 786 B

View File

@@ -1 +0,0 @@
<svg width="32" height="32" xmlns="http://www.w3.org/2000/svg"><defs><linearGradient x1="50%" y1="0%" x2="77.135%" y2="77.109%" id="a"><stop stop-color="#FE7E1F" offset="0%"/><stop stop-color="#FFCF7B" offset="100%"/></linearGradient><linearGradient x1="50%" y1="0%" x2="77.135%" y2="77.109%" id="b"><stop stop-color="#FFF" stop-opacity=".48" offset="0%"/><stop stop-color="#FFF" stop-opacity="0" offset="100%"/></linearGradient></defs><g fill="none" fill-rule="evenodd"><path d="M16 0C7.163 0 0 7.163 0 16s7.163 16 16 16 16-7.163 16-16C31.99 7.168 24.832.01 16 0z" fill="url(#a)"/><path d="M29.012 25.313A11.98 11.98 0 0 1 25 26c-6.627 0-12-5.373-12-12 0-6.235 4.756-11.36 10.838-11.944C28.705 4.8 31.993 10.016 32 16c0 3.474-1.107 6.69-2.988 9.313z" fill="url(#b)"/></g></svg>

Before

Width:  |  Height:  |  Size: 778 B

View File

@@ -1 +0,0 @@
!function(){const e=document,t=e.documentElement,n=e.body,i=e.getElementById("lights-toggle"),s=window.sr=ScrollReveal();function a(){let e=i.parentNode.querySelector(".label-text");i.checked?(n.classList.remove("lights-off"),e&&(e.innerHTML="dark")):(n.classList.add("lights-off"),e&&(e.innerHTML="light"))}t.classList.remove("no-js"),t.classList.add("js"),window.addEventListener("load",function(){n.classList.add("is-loaded")}),n.classList.contains("has-animations")&&window.addEventListener("load",function(){s.reveal(".feature",{duration:600,distance:"20px",easing:"cubic-bezier(0.215, 0.61, 0.355, 1)",origin:"right",viewFactor:.2})}),i&&(window.addEventListener("load",a),i.addEventListener("change",a))}();

View File

@@ -1,149 +0,0 @@
<!DOCTYPE html>
<html lang="en" class="no-js">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>ZY Player</title>
<link href="https://fonts.googleapis.com/css?family=Heebo:400,700|IBM+Plex+Sans:600" rel="stylesheet">
<link rel="stylesheet" href="dist/css/style.css">
<script src="https://unpkg.com/scrollreveal@4.0.0/dist/scrollreveal.min.js"></script>
</head>
<body class="is-boxed has-animations">
<div class="body-wrap boxed-container">
<header class="site-header">
<div class="container">
<div class="site-header-inner">
<div class="brand header-brand">
<h1 class="m-0">
<a href="#">
<img class="header-logo-image asset-light" src="dist/images/logo-light.svg" alt="Logo">
<img class="header-logo-image asset-dark" src="dist/images/logo-dark.svg" alt="Logo">
</a>
</h1>
</div>
</div>
</div>
</header>
<main>
<section class="hero">
<div class="container">
<div class="hero-inner">
<div class="hero-copy">
<h1 class="hero-title mt-0">ZY Player</h1>
<p class="hero-paragraph">ZY Player 影视资源播放器, 可以直接浏览或者搜索影视资源,所有资源点击即可播放.软件免费,没有广告~</p>
<div class="hero-cta">
<a class="button button-primary" href="https://github.com/Hunlongyu/ZY-Player/releases/latest">立即下载</a>
<div class="lights-toggle">
<input id="lights-toggle" type="checkbox" name="lights-toggle" class="switch" checked="checked">
<label for="lights-toggle" class="text-xs"><span>切换主题<span class="label-text">dark</span></span></label>
</div>
</div>
</div>
<div class="hero-media">
<div class="header-illustration">
<img class="header-illustration-image asset-light" src="dist/images/header-illustration-light.svg" alt="Header illustration">
<img class="header-illustration-image asset-dark" src="dist/images/header-illustration-dark.svg" alt="Header illustration">
</div>
<div class="hero-media-illustration">
<img class="hero-media-illustration-image asset-light" src="dist/images/hero-media-illustration-light.svg" alt="Hero media illustration">
<img class="hero-media-illustration-image asset-dark" src="dist/images/hero-media-illustration-dark.svg" alt="Hero media illustration">
</div>
<div class="hero-media-container">
<img class="hero-media-image asset-light" src="https://i.loli.net/2020/01/21/HfRhqXDTJMlEIaP.jpg" alt="Hero media">
<img class="hero-media-image asset-dark" src="https://i.loli.net/2020/01/21/hGYrDKQbXZctfVs.jpg" alt="Hero media">
</div>
</div>
</div>
</div>
</section>
<section class="features section">
<div class="container">
<div class="features-inner section-inner has-bottom-divider">
<div class="features-header text-center">
<div class="container-sm">
<div class="features-image">
<img class="features-illustration asset-dark" src="dist/images/features-illustration-dark.svg" alt="Feature illustration">
<img style="transform: none;" class="features-box asset-dark" src="https://i.loli.net/2020/01/21/exXt3mfsJSGuhn5.jpg" alt="Feature box">
<img class="features-illustration asset-dark" src="dist/images/features-illustration-top-dark.svg" alt="Feature illustration top">
<img class="features-illustration asset-light" src="dist/images/features-illustration-light.svg" alt="Feature illustration">
<img style="transform: none;" class="features-box asset-light" src="https://i.loli.net/2020/01/21/exXt3mfsJSGuhn5.jpg" alt="Feature box">
<img class="features-illustration asset-light" src="dist/images/features-illustration-top-light.svg" alt="Feature illustration top">
</div>
</div>
</div>
<div class="features-wrap">
<div class="feature is-revealing">
<div class="feature-inner">
<div class="feature-icon">
<img class="asset-light" src="dist/images/feature-01-light.svg" alt="Feature 01">
<img class="asset-dark" src="dist/images/feature-01-dark.svg" alt="Feature 01">
</div>
<div class="feature-content">
<h3 class="feature-title mt-0">开源免费</h3>
<p class="text-sm mb-0">代码开源, 软件免费使用, 无广告, 不窃取用户信息, MIT协议.</p>
</div>
</div>
</div>
<div class="feature is-revealing">
<div class="feature-inner">
<div class="feature-icon">
<img class="asset-light" src="dist/images/feature-02-light.svg" alt="Feature 02">
<img class="asset-dark" src="dist/images/feature-02-dark.svg" alt="Feature 02">
</div>
<div class="feature-content">
<h3 class="feature-title mt-0">资源丰富</h3>
<p class="text-sm mb-0">所有资源都来自多个著名资源网站, 海量资源, 应有尽有.</p>
</div>
</div>
</div>
<div class="feature is-revealing">
<div class="feature-inner">
<div class="feature-icon">
<img class="asset-light" src="dist/images/feature-03-light.svg" alt="Feature 03">
<img class="asset-dark" src="dist/images/feature-03-dark.svg" alt="Feature 03">
</div>
<div class="feature-content">
<h3 class="feature-title mt-0">功能强大</h3>
<p class="text-sm mb-0">支持多源切换, 搜索. 支持预览详情, 支持收藏, 支持暗黑主题.</p>
</div>
</div>
</div>
</div>
</div>
</div>
</section>
</main>
<!-- <footer class="site-footer has-top-divider">
<div class="container">
<div class="site-footer-inner">
<div class="brand footer-brand">
<a href="#">
<img class="asset-light" src="dist/images/logo-light.svg" alt="Logo">
<img class="asset-dark" src="dist/images/logo-dark.svg" alt="Logo">
</a>
</div>
<ul class="footer-links list-reset">
<li>
<a href="#">Contact</a>
</li>
<li>
<a href="#">About us</a>
</li>
<li>
<a href="#">FAQ's</a>
</li>
<li>
<a href="#">Support</a>
</li>
</ul>
</div>
</div>
</footer> -->
</div>
<script src="dist/js/main.min.js"></script>
</body>
</html>

View File

@@ -1,60 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>ZY Player</title>
<style>
*{
margin: 0;
padding: 0;
}
html,body{
width: 100%;
height: 100%;
overflow: hidden;
}
#mse{
width: 100%;
height: 100%;
}
</style>
</head>
<body>
<div id="mse"></div>
<script src="//cdn.jsdelivr.net/npm/xgplayer/browser/index.js" type="text/javascript"></script>
<script src="//cdn.jsdelivr.net/npm/xgplayer-hls.js/browser/index.js" charset="utf-8"></script>
<script>
function get (name) {
var reg = new RegExp("(^|&)"+ name +"=([^&]*)(&|$)");
var r = window.location.search.substr(1).match(reg);//search,查询?后面的参数,并匹配正则
if (r!=null)return unescape(r[2]); return null;
}
let link = window.location.href
let info = get('info')
let time = get('time')
let flag = info.indexOf('$')
let url
if (flag > 0) {
url = info.split('$')[1]
} else {
url = info
}
let player = new window.HlsJsPlayer({
id: 'mse',
url: url,
fluid: true,
autoplay: true,
playsinline: true,
height: window.innerHeight,
width: window.innerWidth,
'x5-video-player-fullscreen': true,
'x5-video-orientation': 'landscape'
})
player.on('play', function () {
player.currentTime = time
})
</script>
</body>
</html>

View File

@@ -1,54 +0,0 @@
{
"name": "zy",
"version": "0.9.1",
"author": "Hunlongyu",
"description": "ZY Player 资源播放器",
"private": true,
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"lint": "vue-cli-service lint",
"dev": "vue-cli-service electron:serve",
"electron:build": "vue-cli-service electron:build",
"postinstall": "electron-builder install-app-deps",
"postuninstall": "electron-builder install-app-deps",
"electron:generate-icons": "electron-icon-builder --input=./public/icon.png --output=build --flatten",
"bp": "vue-cli-service electron:build --win --x64 -p always"
},
"main": "background.js",
"dependencies": {
"core-js": "^3.4.4",
"dexie": "^2.0.4",
"electron-updater": "^4.2.0",
"element-ui": "^2.4.5",
"flyio": "^0.6.14",
"qrcanvas": "^3.0.6",
"vue": "^2.6.10",
"vue-class-component": "^7.0.2",
"vue-property-decorator": "^8.3.0",
"vuex": "^3.1.2",
"xgplayer": "^2.4.7",
"xgplayer-hls.js": "^2.1.6"
},
"devDependencies": {
"@vue/cli-plugin-babel": "^4.1.0",
"@vue/cli-plugin-eslint": "^4.1.0",
"@vue/cli-plugin-router": "^4.1.0",
"@vue/cli-plugin-typescript": "^4.1.0",
"@vue/cli-plugin-vuex": "^4.1.0",
"@vue/cli-service": "^4.1.0",
"@vue/eslint-config-standard": "^4.0.0",
"@vue/eslint-config-typescript": "^4.0.0",
"babel-plugin-component": "^1.1.1",
"electron": "7.1.9",
"electron-icon-builder": "^1.0.2",
"eslint": "^5.16.0",
"eslint-plugin-vue": "^5.0.0",
"sass": "^1.23.7",
"sass-loader": "^8.0.0",
"typescript": "~3.5.3",
"vue-cli-plugin-electron-builder": "^1.4.4",
"vue-cli-plugin-element": "^1.0.1",
"vue-template-compiler": "^2.6.10"
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 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 %>icon.png">
<title>ZY Player</title>
</head>
<body>
<noscript>
<strong>We're sorry but zy 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,143 +0,0 @@
<template>
<el-container id="app" :class="appTheme">
<el-header class="Header">
<i class="el-icon-minus" @click="clickFrameEvent('min')"></i>
<i class="el-icon-plus" @click="clickFrameEvent('max')"></i>
<i class="el-icon-close" @click="clickFrameEvent('close')"></i>
<el-row class="Header-box">
</el-row>
</el-header>
<el-container>
<el-aside class="Aside" width="70px">
<el-row class="top">
<i title="浏览" :class="Main === 'Film' ? 'el-icon-film active' : 'el-icon-film'" @click="asideMenuClick('Film')"></i>
<i title="搜索" :class="Main === 'Search' ? 'el-icon-search active' : 'el-icon-search'" @click="asideMenuClick('Search')"></i>
<i title="播放" :class="Main === 'Player' ? 'el-icon-video-play active' : 'el-icon-video-play'" @click="asideMenuClick('Player')"></i>
<i title="收藏" :class="Main === 'Star' ? 'el-icon-star-off active' : 'el-icon-star-off'" @click="asideMenuClick('Star')"></i>
</el-row>
<el-row class="bottom">
<i title="设置" :class="Main === 'Setting' ? 'el-icon-setting active' : 'el-icon-setting'" @click="asideMenuClick('Setting')"></i>
</el-row>
</el-aside>
<el-main class="Main">
<Film v-show="Main === 'Film'" />
<Search v-show="Main === 'Search'" />
<Player v-show="Main === 'Player'" />
<Star v-show="Main === 'Star'" />
<Setting v-show="Main === 'Setting'" />
</el-main>
</el-container>
<el-drawer class="drawer" :visible.sync="detail.show" :show-close="true" size="90%" :with-header="true" direction="btt" title="详情">
<Detail />
</el-drawer>
</el-container>
</template>
<script lang="ts">
import Vue from 'vue'
import Detail from '@/components/detail.vue'
import { mapMutations } from 'vuex'
const { ipcRenderer: ipc } = require('electron')
export default Vue.extend({
data () {
return {
appTheme: 'theme-light'
}
},
computed: {
Main: {
get () {
return this.$store.getters.getMain
},
set (val) {
this.SET_MAIN(val)
}
},
detail: {
get () {
return this.$store.getters.getDetail
},
set (val) {
this.SET_DETAIL(val)
}
},
theme () {
return this.$store.getters.getTheme
}
},
watch: {
theme () {
this.changeTheme()
}
},
components: {
Detail
},
methods: {
...mapMutations(['SET_DETAIL', 'SET_MAIN']),
clickFrameEvent (e:string) {
ipc.send(e)
},
asideMenuClick (e:string) {
this.Main = e
},
changeTheme () {
this.appTheme = `theme-${this.theme}`
}
}
})
</script>
<style lang="scss">
@import './assets/theme/global.scss';
@import './assets/theme/dark.scss';
@import './assets/theme/light.scss';
@import './assets/theme/pink.scss';
@import './assets/theme/green.scss';
*{
margin: 0;
padding: 0;
box-sizing: border-box;
}
html,body{
height: 100%;
}
#app{
height: 100%;
.Header{
display: flex;
justify-content: flex-end;
align-items: center;
-webkit-app-region: drag;
-webkit-user-select: none;
padding: 0;
i{
width: 60px;
height: 60px;
font-size: 30px;
cursor: pointer;
-webkit-app-region: no-drag;
display: flex;
justify-content: center;
align-items: center;
}
}
.Aside{
-webkit-app-region: drag;
-webkit-user-select: none;
text-align: center;
i{
-webkit-app-region: no-drag;
font-size: 32px;
width: 70px;
height: 70px;
line-height: 70px;
cursor: pointer;
}
}
.Main{
height: 100%;
overflow: hidden;
user-select: none;
}
}
</style>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 232 KiB

View File

@@ -1,159 +0,0 @@
.theme-dark{
color: var(--d-c);
background-color: var(--d-bgc);
.el-button, input, select, .el-select{
color: var(--d-c);
background-color: var(--d-bgc);
border-color: var(--d-bdc);
}
.el-select .el-input .el-select__caret{
color: var(--d-icon)
}
.el-button--text{
border: none;
}
.el-button--text:focus, .el-button--text:hover{
color: var(--d-c-h);
}
.el-tabs__active-bar{
background-color: var(--d-bdc);
}
.el-tabs__item:hover, .el-tabs__item.is-active{
color: var(--d-c-h);
}
.el-tabs__item, .el-tabs__nav-wrap::after{
color: var(--d-c);
background-color: var(--d-bgc);
border-color: var(--d-bdc);
}
.el-table--border::after, .el-table--droup::after, .el-table::before,
.el-table, .el-table th, .el-table tr,
.el-table--striped .el-table__body tr.el-table__row--striped td,
.el-table--enable-row-hover .el-table__body tr:hover>td,
.el-table td, .el-table th.is-leaf{
color: var(--d-c);
background-color: var(--d-bgc);
border-color: var(--d-bdc);
}
.el-pagination, .el-pagination .el-pagination__total, .el-pagination .el-pagination__jump,
.el-pagination .btn-next, .el-pagination .btn-prev, .el-pager li{
color: var(--d-c);
background-color: var(--d-bgc);
}
.el-pager li:hover, .el-pager li.active, .el-pager li.btn-quicknext, .el-pager li.btn-quickprev{
color: var(--d-c-h);
}
.el-input__inner, .el-input__inner:hover,
.el-input-group__append, .el-input-group__prepend{
background-color: var(--d-bgc);
border-color: var(--d-bdc);
}
.el-input.is-active .el-input__inner, .el-input__inner:focus{
border-color: var(--d-bdc);
}
.el-input__inner{
border-color: var(--d-bdc);
}
.el-select .el-input.is-focus .el-input__inner,
.el-select .el-input__inner:focus,
.el-select:hover .el-input__inner{
border-color: var(--d-bdc);
}
input::-webkit-input-placeholder{
color: var(--d-c);
}
.el-icon-search{
color: var(--d-icon);
}
.el-select-dropdown{
color: var(--d-c);
}
.el-drawer{
background-color: var(--d-bgc) !important;
overflow: auto;
&::-webkit-scrollbar{
width: 0px;
}
}
.el-loading-mask{
background-color: var(--d-bgc);
opacity: 0.9;
}
.el-slider__bar{
background-color: var(--d-c-h);
}
.el-slider__button{
border-color: var(--d-c-h);
}
.Header, .Aside{
i{
color: var(--d-icon);
&:hover{
color: var(--d-icon-h);
background-color: var(--d-bgc-h);
}
}
}
.Aside{
i{
&.active{
color: var(--d-icon-h);
background-color: var(--d-bgc-h);
border-left: 4px solid var(--d-icon-h);
}
}
}
.Main{
.film, .search, .star, .player{
button:hover{
color: var(--d-c-h);
background: var(--d-bgc);
border-color: var(--d-bdc);
}
.table-box{
&::-webkit-scrollbar-track {
box-shadow: inset 0 0 6px var(--d-bdc);
}
&::-webkit-scrollbar-thumb {
background-color: var(--d-icon);
outline: 1px solid var(--d-icon);
}
}
}
.player{
.el-button--primary.is-plain{
color: var(--d-c);
background-color: var(--d-bgc-h);
border-color: var(--d-bdc);
}
}
.setting{
.el-link, .card{
color: var(--d-c);
background-color: var(--d-bgc);
border-color: var(--d-bdc);
}
}
}
.detail{
color: var(--d-c);
&::-webkit-scrollbar-track {
box-shadow: inset 0 0 6px var(--d-bdc);
}
&::-webkit-scrollbar-thumb {
background-color: var(--d-icon);
outline: 1px solid var(--d-icon);
}
.box, .info, .urls{
border: 1px solid var(--d-bdc);
}
.vodInfo{
li, span, a{
color: var(--d-c);
}
label{
color: #f90;
}
}
}
}

View File

@@ -1,37 +0,0 @@
:root{
// light
--l-c: #808695;
--l-c-h: #515a6e;
--l-icon: #C0C4CC;
--l-icon-h: #515a6e;
--l-bgc: #ffffff;
--l-bgc-h: #efefef;
--l-bdc: #dcdee2;
// dark
--d-c: #919191;
--d-c-h: #454545;
--d-icon: #919191;
--d-icon-h: #919191;
--d-bgc: #242424;
--d-bgc-h: #454545;
--d-bdc: #7a7a7a;
// pink
--p-c: #ffffff;
--p-c-h: #fd7792;
--p-icon: #ffffff;
--p-icon-h: #fd7792;
--p-bgc: #ffbaba;
--p-bgc-h: #ffc5c5;
--p-bdc: #fdcfcf;
// green
--g-c: #ffffff;
--g-c-h: #ebe65b;
--g-icon: #ffffff;
--g-icon-h: #ebe65b;
--g-bgc: #4baea0;
--g-bgc-h: #6db8ac;
--g-bdc: #76d3c5;
}

View File

@@ -1,159 +0,0 @@
.theme-green{
color: var(--g-c);
background-color: var(--g-bgc);
.el-button, input, select, .el-select{
color: var(--g-c);
background-color: var(--g-bgc);
border-color: var(--g-bdc);
}
.el-select .el-input .el-select__caret{
color: var(--g-icon)
}
.el-button--text{
border: none;
}
.el-button--text:focus, .el-button--text:hover{
color: var(--g-c-h);
}
.el-tabs__active-bar{
background-color: var(--g-bdc);
}
.el-tabs__item:hover, .el-tabs__item.is-active{
color: var(--g-c-h);
}
.el-tabs__item, .el-tabs__nav-wrap::after{
color: var(--g-c);
background-color: var(--g-bgc);
border-color: var(--g-bdc);
}
.el-table--border::after, .el-table--group::after, .el-table::before,
.el-table, .el-table th, .el-table tr,
.el-table--striped .el-table__body tr.el-table__row--striped td,
.el-table--enable-row-hover .el-table__body tr:hover>td,
.el-table td, .el-table th.is-leaf{
color: var(--g-c);
background-color: var(--g-bgc);
border-color: var(--g-bdc);
}
.el-pagination, .el-pagination .el-pagination__total, .el-pagination .el-pagination__jump,
.el-pagination .btn-next, .el-pagination .btn-prev, .el-pager li{
color: var(--g-c);
background-color: var(--g-bgc);
}
.el-pager li:hover, .el-pager li.active, .el-pager li.btn-quicknext, .el-pager li.btn-quickprev{
color: var(--g-c-h);
}
.el-input__inner, .el-input__inner:hover,
.el-input-group__append, .el-input-group__prepend{
background-color: var(--g-bgc);
border-color: var(--g-bdc);
}
.el-input.is-active .el-input__inner, .el-input__inner:focus{
border-color: var(--g-bdc);
}
.el-input__inner{
border-color: var(--g-bdc);
}
.el-select .el-input.is-focus .el-input__inner,
.el-select .el-input__inner:focus,
.el-select:hover .el-input__inner{
border-color: var(--g-bdc);
}
input::-webkit-input-placeholder{
color: var(--g-c);
}
.el-icon-search{
color: var(--g-icon);
}
.el-select-dropdown{
color: var(--g-c);
}
.el-drawer{
background-color: var(--g-bgc) !important;
overflow: auto;
&::-webkit-scrollbar{
width: 0px;
}
}
.el-loading-mask{
background-color: var(--g-bgc);
opacity: 0.9;
}
.el-slider__bar{
background-color: var(--g-c-h);
}
.el-slider__button{
border-color: var(--g-c-h);
}
.Header, .Aside{
i{
color: var(--g-icon);
&:hover{
color: var(--g-icon-h);
background-color: var(--g-bgc-h);
}
}
}
.Aside{
i{
&.active{
color: var(--g-icon-h);
background-color: var(--g-bgc-h);
border-left: 4px solid var(--g-icon-h);
}
}
}
.Main{
.film, .search, .star, .player{
button:hover{
color: var(--g-c-h);
background: var(--g-bgc);
border-color: var(--g-bdc);
}
.table-box{
&::-webkit-scrollbar-track {
box-shadow: inset 0 0 6px var(--g-bdc);
}
&::-webkit-scrollbar-thumb {
background-color: var(--g-icon);
outline: 1px solid var(--g-icon);
}
}
}
.player{
.el-button--primary.is-plain{
color: var(--g-c-h);
background-color: var(--g-bgc-h);
border-color: var(--g-bdc);
}
}
.setting{
.el-link, .card{
color: var(--g-c);
background-color: var(--g-bgc);
border-color: var(--g-bdc);
}
}
}
.detail{
color: var(--g-c);
&::-webkit-scrollbar-track {
box-shadow: inset 0 0 6px var(--g-bdc);
}
&::-webkit-scrollbar-thumb {
background-color: var(--g-icon);
outline: 1px solid var(--g-icon);
}
.box, .info, .urls{
border: 1px solid var(--g-bdc);
}
.vodInfo{
li, span, a{
color: var(--g-c);
}
label{
color: #f90;
}
}
}
}

View File

@@ -1,77 +0,0 @@
.theme-light{
color: var(--l-c);
background-color: var(--l-bgc);
.el-table, .el-tabs__item, .btn-next, input{
color: var(--l-c);
}
.el-pagination, .el-pagination .el-pagination__total, .el-pagination .el-pagination__jump,
.el-pagination .btn-next, .el-pagination .btn-prev{
color: var(--l-c);
}
.el-drawer{
overflow: auto;
&::-webkit-scrollbar{
width: 0px;
}
}
.Header, .Aside{
i{
color: var(--l-icon);
&:hover{
color: var(--l-icon-h);
background-color: var(--l-bgc-h);
}
}
}
.Aside{
i{
&.active{
color: var(--l-icon-h);
background-color: var(--l-bgc-h);
border-left: 4px solid var(--l-icon-h);
}
}
}
.Main{
.film, .search, .star, .player, .setting{
.table-box{
&::-webkit-scrollbar-track {
box-shadow: inset 0 0 6px var(--l-bdc);
}
&::-webkit-scrollbar-thumb {
background-color: var(--l-icon);
outline: 1px solid var(--l-icon);
}
}
}
.setting{
.el-link, .card{
color: var(--l-c);
}
.qrcode img{
box-shadow: 0px 0px 5px var(--l-icon);
}
}
}
.detail{
color: var(--l-c);
&::-webkit-scrollbar-track {
box-shadow: inset 0 0 6px var(--l-bdc);
}
&::-webkit-scrollbar-thumb {
background-color: var(--l-icon);
outline: 1px solid var(--l-icon);
}
.box, .info, .urls{
border: 1px solid var(--l-bdc);
}
.vodInfo{
li, span, a{
color: var(--l-c);
}
label{
color: #f90;
}
}
}
}

View File

@@ -1,159 +0,0 @@
.theme-pink{
color: var(--p-c);
background-color: var(--p-bgc);
.el-button, input, select, .el-select{
color: var(--p-c);
background-color: var(--p-bgc);
border-color: var(--p-bdc);
}
.el-select .el-input .el-select__caret{
color: var(--p-icon)
}
.el-button--text{
border: none;
}
.el-button--text:focus, .el-button--text:hover{
color: var(--p-c-h);
}
.el-tabs__active-bar{
background-color: var(--p-bdc);
}
.el-tabs__item:hover, .el-tabs__item.is-active{
color: var(--p-c-h);
}
.el-tabs__item, .el-tabs__nav-wrap::after{
color: var(--p-c);
background-color: var(--p-bgc);
border-color: var(--p-bdc);
}
.el-table--border::after, .el-table--proup::after, .el-table::before,
.el-table, .el-table th, .el-table tr,
.el-table--striped .el-table__body tr.el-table__row--striped td,
.el-table--enable-row-hover .el-table__body tr:hover>td,
.el-table td, .el-table th.is-leaf{
color: var(--p-c);
background-color: var(--p-bgc);
border-color: var(--p-bdc);
}
.el-pagination, .el-pagination .el-pagination__total, .el-pagination .el-pagination__jump,
.el-pagination .btn-next, .el-pagination .btn-prev, .el-pager li{
color: var(--p-c);
background-color: var(--p-bgc);
}
.el-pager li:hover, .el-pager li.active, .el-pager li.btn-quicknext, .el-pager li.btn-quickprev{
color: var(--p-c-h);
}
.el-input__inner, .el-input__inner:hover,
.el-input-group__append, .el-input-group__prepend{
background-color: var(--p-bgc);
border-color: var(--p-bdc);
}
.el-input.is-active .el-input__inner, .el-input__inner:focus{
border-color: var(--p-bdc);
}
.el-input__inner{
border-color: var(--p-bdc);
}
.el-select .el-input.is-focus .el-input__inner,
.el-select .el-input__inner:focus,
.el-select:hover .el-input__inner{
border-color: var(--p-bdc);
}
input::-webkit-input-placeholder{
color: var(--p-c);
}
.el-icon-search{
color: var(--p-icon);
}
.el-select-dropdown{
color: var(--p-c);
}
.el-drawer{
background-color: var(--p-bgc) !important;
overflow: auto;
&::-webkit-scrollbar{
width: 0px;
}
}
.el-loading-mask{
background-color: var(--p-bgc);
opacity: 0.9;
}
.el-slider__bar{
background-color: var(--p-c-h);
}
.el-slider__button{
border-color: var(--p-c-h);
}
.Header, .Aside{
i{
color: var(--p-icon);
&:hover{
color: var(--p-icon-h);
background-color: var(--p-bgc-h);
}
}
}
.Aside{
i{
&.active{
color: var(--p-icon-h);
background-color: var(--p-bgc-h);
border-left: 4px solid var(--p-icon-h);
}
}
}
.Main{
.film, .search, .star, .player{
button:hover{
color: var(--p-c-h);
background: var(--p-bgc);
border-color: var(--p-bdc);
}
.table-box{
&::-webkit-scrollbar-track {
box-shadow: inset 0 0 6px var(--p-bdc);
}
&::-webkit-scrollbar-thumb {
background-color: var(--p-icon);
outline: 1px solid var(--p-icon);
}
}
}
.player{
.el-button--primary.is-plain{
color: var(--p-c-h);
background-color: var(--p-bgc-h);
border-color: var(--p-bdc);
}
}
.setting{
.el-link, .card{
color: var(--p-c);
background-color: var(--p-bgc);
border-color: var(--p-bdc);
}
}
}
.detail{
color: var(--p-c);
&::-webkit-scrollbar-track {
box-shadow: inset 0 0 6px var(--p-bdc);
}
&::-webkit-scrollbar-thumb {
background-color: var(--p-icon);
outline: 1px solid var(--p-icon);
}
.box, .info, .urls{
border: 1px solid var(--p-bdc);
}
.vodInfo{
li, span, a{
color: var(--p-c);
}
label{
color: #f90;
}
}
}
}

View File

@@ -1,153 +0,0 @@
'use strict'
import { app, protocol, ipcMain, BrowserWindow } from 'electron'
import {
createProtocol,
installVueDevtools
} from 'vue-cli-plugin-electron-builder/lib'
import path from 'path'
import { autoUpdater } from 'electron-updater'
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: BrowserWindow | null
// 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
},
// @ts-ignore
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 as string)
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', () => {
if (win) {
win.minimize()
}
})
ipcMain.on('max', e => {
if (win) {
if (win.isMaximized()) {
win.unmaximize()
} else {
win.maximize()
}
}
})
ipcMain.on('close', e => {
if (win) {
win.close()
}
})
ipcMain.on('opacity', (e, arg) => {
if (win) {
win.setOpacity(arg)
}
})
ipcMain.on('top', () => {
if (win) {
if (win.isAlwaysOnTop()) {
win.setAlwaysOnTop(false)
} else {
win.setAlwaysOnTop(true)
}
}
})
const gotTheLock = app.requestSingleInstanceLock()
if (!gotTheLock) {
app.quit()
} else {
app.on('second-instance', (event, commandLine, workingDirectory) => {
// 当运行第二个实例时,将会聚焦到win这个窗口
if (win) {
if (win.isMinimized()) win.restore()
win.focus()
}
})
// 创建 win, 加载应用的其余部分, etc...
app.on('ready', () => {
createWindow()
})
}
// 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,159 +0,0 @@
<template>
<el-row class="detail">
<el-row class="detail-box" v-loading="loading">
<el-row v-html="detail.box" class="box"></el-row>
<el-row v-html="detail.info" class="info"></el-row>
<el-row class="urls">
<el-button size="mini" v-for="(i, j) in detail.urls" :key="j" @click="playBtn(i, j)">{{i | ftLink}}</el-button>
</el-row>
</el-row>
</el-row>
</template>
<script lang="ts">
import Vue from 'vue'
import zy from '@/lib/util.zy'
import { mapMutations } from 'vuex'
export default Vue.extend({
name: 'detail',
data () {
return {
detail: {},
loading: true
}
},
computed: {
d () {
return this.$store.getters.getDetail
},
video: {
get () {
return this.$store.getters.getVideo
},
set (val) {
this.SET_VIDEO(val)
}
},
Main: {
get () {
return this.$store.getters.getMain
},
set (val) {
this.SET_MAIN(val)
}
}
},
watch: {
d () {
this.getDetailEvent()
}
},
filters: {
ftLink (e: string) {
let name = e.split('$')[0]
return name
}
},
methods: {
...mapMutations(['SET_MAIN', 'SET_VIDEO']),
getDetailEvent () {
let url = this.d.video.detail
this.detail = {}
this.loading = true
zy.detail(url).then((res: any) => {
this.detail = res
this.loading = false
})
},
playBtn (i: string, j: number) {
if (this.Main !== 'Player') {
this.d.video.index = j
this.video = this.d.video
this.Main = 'Player'
} else {
this.d.video.index = j
this.video = this.d.video
}
this.d.show = false
}
},
created () {
this.getDetailEvent()
}
})
</script>
<style lang="scss">
.detail{
box-sizing: border-box;
padding: 0 60px;
user-select: auto;
.detail-box{
width: 100%;
.box{
display: flex;
justify-content: flex-start;
align-items: flex-start;
flex-wrap: wrap;
width: 100%;
padding: 10px;
.vodImg{
width: 200px;
img{
width: 100%;
height: auto;
}
}
.vodAd{
display: none;
}
.vodInfo{
flex: 1;
margin-left: 20px;
.vodh{
h2{
display: inline-block;
}
span{
font-size: 12px;
margin-left: 10px;
}
label{
font-size: 20px;
font-weight: bold;
margin-left: 20px;
}
}
.cont, .tags{
display: none;
}
li{
list-style: none;
font-size: 14px;
height: 20px;
overflow: hidden;
a{
display: none;
pointer-events: none;
}
span{
word-wrap:break-word
}
}
}
}
.info, .urls{
padding: 10px;
margin-top: 10px;
}
.info{
font-size: 14px;
}
.urls{
margin-bottom: 20px;
padding-bottom: 0;
button{
margin: 0 10px 10px 0;
}
}
}
}
</style>

View File

@@ -1,41 +0,0 @@
interface Site {
id: string
name: string
url: string
type: Array<any>
}
const sites:Array<Site> = [
{
id: 'okzy',
name: 'OK资源网',
url: 'https://www.okzy.co',
type: [[ '最新', '0' ], [ '电影', '1' ], [ '电视剧', '2' ], [ '综艺', '3' ], [ '动漫', '4' ], [ '伦理', '21' ], [ '福利', '22' ], [ '解说', '33' ]]
},
{
id: 'zuidazy',
name: '最大资源网',
url: 'http://www.zuidazy1.com',
type: [[ '最新', '0' ], [ '电影', '1' ], [ '电视剧', '2' ], [ '综艺', '3' ], [ '动漫', '4' ], [ '福利', '16' ], [ '伦理', '17' ], [ '音乐', '18' ]]
},
{
id: 'subo',
name: '速播资源站',
url: 'https://www.subo988.com',
type: [[ '最新', '0' ], [ '电影', '1' ], [ '电视剧', '2' ], [ '综艺', '3' ], [ '动漫', '4' ], [ '伦理', '16' ], [ '音乐', '20' ]]
},
{
id: 'zuixinzy',
name: '最新资源网',
url: 'http://www.zuixinzy.cc',
type: [[ '最新', '0' ], [ '电影', '1' ], [ '电视剧', '2' ], [ '综艺', '3' ], [ '动漫', '4' ], ['伦理', '21'], ['情色', '23'], [ '福利', '30' ], [ '解说', '34' ]]
},
{
id: '123ku',
name: '123资源网',
url: 'https://www.123ku.com',
type: [[ '最新', '0' ], [ '电影', '1' ], [ '电视剧', '2' ], [ '综艺', '3' ], [ '动漫', '4' ], [ '伦理', '16' ]]
}
]
export default sites

View File

@@ -1,173 +0,0 @@
import fly from 'flyio'
import sites from './sites'
import { TimeSelect } from 'element-ui'
interface ZY {
num: number
page: number
key: string
site: any
list: Array<string>
getInfoRequire: any
getInfoHtml: any
info: any
detail: any
films: any
}
interface info {
name?: string
type?: string
time?: string
detail?: string
urls?: Array<string>
index?: number
}
interface detail {
box?: any
info?: any
urls?: Array<string>
}
fly.config.timeout = 10000
const zy: ZY = {
num: 0,
page: 1,
key: '',
site: {},
list: [],
getInfoRequire () {
return new Promise((resolve, reject) => {
let key = encodeURI(this.key)
const params = `${this.site.url}/index.php?m=vod-search-pg-${this.page}-wd-${key}.html`
fly.get(params).then(res => {
this.getInfoHtml(res.data).then((data: any) => {
resolve(data)
})
}).catch(err => {
reject(err)
})
})
},
getInfoHtml (txt: string): any {
return new Promise((resolve, reject) => {
try {
const parser = new DOMParser()
const html = parser.parseFromString(txt, 'text/html')
const list: any = html.querySelectorAll('.xing_vb li')
let d: any = { list: [], total: 0 }
for (let i = 1; i < list.length - 1; i++) {
let info: info = {
name: list[i].childNodes[1].innerText,
type: list[i].childNodes[3].innerText,
time: list[i].childNodes[5].innerText,
detail: this.site.url + list[i].childNodes[1].childNodes[0].getAttribute('href'),
index: 0,
urls: []
}
d.list.push(info)
}
let num: any = (<HTMLImageElement>html.querySelectorAll('.nvc dd span')[1]).innerText
num = parseInt(num)
d.total = num
resolve(d)
} catch (err) {
reject(err)
}
})
},
info (n: number = 0, p: number = 1, k: string = '') {
return new Promise((resolve, reject) => {
this.num = n
this.page = p
this.key = k
this.site = sites[n]
this.getInfoRequire().then((res: any) => {
resolve(res)
}).catch((err: any) => {
reject(err)
})
})
},
detail (url: string) {
return new Promise((resolve, reject) => {
if (!url) return
fly.get(url).then(res => {
const parser = new DOMParser()
let html = parser.parseFromString(res.data, 'text/html')
let data: detail = {
box: '',
info: '',
urls: []
}
let vodBox = html.querySelector('.vodBox')
if (vodBox) {
data.box = vodBox.innerHTML
}
let vodInfo = {}
if (url.indexOf('123ku') !== -1 || url.indexOf('subo988') !== -1) {
vodInfo = html.querySelectorAll('.vodplayinfo')[1]
} else {
vodInfo = <HTMLImageElement>html.querySelector('.vodplayinfo')
}
data.info = (<HTMLImageElement>vodInfo).innerText
let urls = html.querySelectorAll('.vodplayinfo li')
let arr = []
for (let i in urls) {
let j = (<HTMLImageElement>urls[i]).innerText
if (j !== undefined && j.indexOf('.m3u8') !== -1) {
arr.push((<HTMLImageElement>urls[i]).innerText)
}
}
data.urls = arr
resolve(data)
}).catch(err => {
reject(err)
})
})
},
films (n: number = 0, p: number = 1, type: string = '0') {
return new Promise((resolve, reject) => {
this.site = sites[n]
let url: string = sites[n].url
let params: string = ''
if (type === '0') {
params = `${url}/?m=vod-index-pg-${p}.html`
} else {
params = `${url}/?m=vod-type-id-${type}-pg-${p}.html`
}
fly.get(params).then(res => {
const parser = new DOMParser()
const html = parser.parseFromString(res.data, 'text/html')
const list: any = html.querySelectorAll('.xing_vb li')
let d: any = { list: [], total: 0 }
for (let i = 1; i < list.length - 1; i++) {
let info: info = {
name: list[i].childNodes[1].innerText,
type: list[i].childNodes[3].innerText,
time: list[i].childNodes[5].innerText,
detail: this.site.url + list[i].querySelector('a').getAttribute('href'),
index: 0,
urls: []
}
d.list.push(info)
}
let num: any = html.querySelectorAll('.pages')
if (num) {
let n = num[0].innerText
n = n.split('条')[0]
n = n.split('共')[1]
n = parseInt(n)
d.total = n
}
resolve(d)
}).catch(err => {
reject(err)
})
})
}
}
export default zy

View File

@@ -1,14 +0,0 @@
import Vue from 'vue'
import App from './App.vue'
import store from './store'
import './plugins/element.ts'
import Register from './page/register'
Vue.config.productionTip = false
Register.registerComponents()
new Vue({
store,
render: h => h(App)
}).$mount('#app')

View File

@@ -1,176 +0,0 @@
<template>
<el-row class="film">
<el-row class="film-tabs">
<el-tabs v-model="tabs" @tab-click="tabClick">
<el-tab-pane class="film-tabpane" v-for="(i, j) in sites[site].type" :key="j" :label="i[0]" :name="i[1]"></el-tab-pane>
</el-tabs>
</el-row>
<el-row class="film-table-box table-box">
<el-table :data="filmData" stripe class="film-table" v-loading="loading" size="mini">
<el-table-column prop="name" label="影片名称"></el-table-column>
<el-table-column prop="type" label="影片类别" width="120"></el-table-column>
<el-table-column prop="time" label="更新时间" width="180"></el-table-column>
<el-table-column label="操作" width="120">
<template slot-scope="scope">
<el-button size="small" type="text" @click="tableBtnClick('detail', scope.row)">详情</el-button>
<el-button size="small" type="text" @click="tableBtnClick('star', scope.row)">收藏</el-button>
<el-button size="small" type="text" @click="tableBtnClick('play', scope.row)">播放</el-button>
</template>
</el-table-column>
</el-table>
</el-row>
<el-row class="film-bottom" type="flex" justify="space-between">
<el-select v-model="site" placeholder="请选择" size="small" @change="selectSite">
<el-option
v-for="(i, j) in sites"
:key="i.id"
:label="i.name"
:value="j">
</el-option>
</el-select>
<el-pagination
small
layout="total, prev, pager, next, jumper"
:current-page="filmPage"
@current-change="pageChange"
:page-size="50"
:total="filmTotal">
</el-pagination>
</el-row>
</el-row>
</template>
<script lang="ts">
import Vue from 'vue'
import zy from '@/lib/util.zy'
import sites from '@/lib/sites'
import { mapMutations } from 'vuex'
import video from '@/plugins/dexie/video'
export default Vue.extend({
data () {
return {
sites: sites,
tabs: '0',
filmPage: 1,
filmTotal: 0,
filmData: [],
loading: false
}
},
computed: {
video: {
get () {
return this.$store.getters.getVideo
},
set (val) {
this.SET_VIDEO(val)
}
},
site: {
get () {
return this.$store.getters.getSite
},
set (val) {
this.SET_SITE(val)
}
},
Main: {
get () {
return this.$store.getters.getMain
},
set (val) {
this.SET_MAIN(val)
}
}
},
methods: {
...mapMutations(['SET_SITE', 'SET_DETAIL', 'SET_MAIN', 'SET_VIDEO']),
tabClick (tab:any) {
this.filmPage = 1
this.getFilmList(this.site, this.filmPage, tab.name)
},
selectSite (e:any) {
this.site = e
this.tabs = '0'
this.filmPage = 1
this.getFilmList(e, 1, '0')
},
pageChange (e:number) {
this.filmPage = e
this.getFilmList(this.site, this.filmPage, this.tabs)
},
getFilmList (n: number = 0, p: number = 1, type: string = '0') {
this.loading = true
this.filmData = []
this.tabs = type
zy.films(n, p, type).then((res: any) => {
this.filmTotal = res.total
this.filmData = res.list
this.filmPage = p
this.loading = false
}).catch((err: any) => {
if (err.status === 1) {
this.$message.warning('获取资源超时,请切换分类,或者切换源。')
}
})
},
tableBtnClick (type: string, e: any) {
if (type === 'detail') {
let d = {
show: true,
video: e
}
this.SET_DETAIL(d)
}
if (type === 'star') {
video.find({ detail: e.detail }).then(res => {
if (res) {
this.$message.warning('已存在')
} else {
video.add(e).then(res => {
this.$message.success('收藏成功')
})
}
})
}
if (type === 'play') {
this.Main = 'Player'
this.video = e
}
}
},
created () {
this.getFilmList()
}
})
</script>
<style lang="scss" scoped>
.film{
height: 100%;
position: relative;
.film-tabs{
position: absolute;
top: 0px;
left: 0;
width: 100%;
height: 60px;
}
.film-table-box{
position: absolute;
top: 54px;
width: 100%;
height: calc(100% - 100px);
overflow: auto;
&::-webkit-scrollbar{
width: 6px;
}
}
.film-bottom{
position: absolute;
bottom: 0;
left: 0;
width: 100%;
height: 40px;
align-items: center;
}
}
</style>

View File

@@ -1,291 +0,0 @@
<template>
<el-row class="player">
<el-row class="player-show" v-if="Object.keys(video).length > 0">
<el-row class="player-title">
<el-row class="player-title-box" type="flex" justify="space-between">
<span>
<span>{{video.name ? video.name + ' -- ' : '' }}</span>
<span>{{ num }}</span>
</span>
<span>
<el-button size="mini" @click="topEvent('top')" icon="el-icon-place" title="置顶" circle></el-button>
<el-button size="mini" @click="openDetail" icon="el-icon-document" title="查看详情" circle></el-button>
<el-button size="mini" v-show="!star" @click="starEvent" icon="el-icon-star-off" title="添加收藏" circle></el-button>
<el-button size="mini" v-show="star" @click="starEvent" icon="el-icon-star-on" title="取消收藏" circle></el-button>
<el-button size="mini" @click="shareEvent" icon="el-icon-share" title="分享" circle></el-button>
<el-popover placement="bottom" width="150" trigger="click">
<el-row id="qrcode"></el-row>
<el-button v-show="xg !== null" size="mini" @click="mobileEvent" icon="el-icon-mobile-phone" title="手机观看" circle slot="reference" style="margin-left: 10px;"></el-button>
</el-popover>
</span>
</el-row>
</el-row>
<el-row class="player-box">
<div id="xg"></div>
</el-row>
<el-row class="player-films table-box">
<el-row class="player-films-box">
<el-button :type="j === video.index ? 'primary' : ''" size="mini" v-for="(i, j) in urls" :key="j" @click="playBtnClick(i, j)" plain>{{i | ftLink}}</el-button>
</el-row>
</el-row>
</el-row>
<el-row class="player-none" v-if="Object.keys(video).length <= 0">
<el-row class="tips">
浏览或者搜索资源, 点击播放, 即可观看~
</el-row>
<el-row class="btns">
<el-button size="small" @click="goView('Film')" icon="el-icon-film">浏览</el-button>
<el-button size="small" @click="goView('Search')" icon="el-icon-search">搜索</el-button>
</el-row>
</el-row>
</el-row>
</template>
<script lang="ts">
import Vue from 'vue'
import { mapMutations } from 'vuex'
import zy from '@/lib/util.zy'
import 'xgplayer'
// @ts-ignore
import Hls from 'xgplayer-hls.js'
import video from '@/plugins/dexie/video'
import { qrcanvas } from 'qrcanvas'
const { ipcRenderer: ipc, clipboard } = require('electron')
export default Vue.extend({
data () {
return {
xg: null,
config: {
id: 'xg',
url: '',
cssFullscreen: true,
fluid: false,
autoplay: true,
videoInit: true,
keyShortcut: 'on',
defaultPlaybackRate: 1,
playbackRate: [0.5, 0.75, 1, 1.5, 2]
},
urls: [],
num: '',
star: false
}
},
computed: {
d () {
return this.$store.getters.getDetail
},
video: {
get () {
return this.$store.getters.getVideo
},
set (val) {
this.SET_VIDEO(val)
}
},
Main: {
get () {
return this.$store.getters.getMain
},
set (val) {
this.SET_MAIN(val)
}
}
},
watch: {
video: {
handler () {
this.getUrls()
},
deep: true
}
},
filters: {
ftLink (e: string) {
let name = e.split('$')[0]
return name
}
},
methods: {
...mapMutations(['SET_DETAIL', 'SET_VIDEO', 'SET_MAIN']),
topEvent (e:string) {
ipc.send(e)
},
goView (e: string) {
this.Main = e
},
openDetail () {
let d = {
show: true,
video: this.video
}
this.SET_DETAIL(d)
},
getUrls () {
if (this.xg) {
// @ts-ignore
this.xg.destroy(true)
this.xg = null
}
this.checkStar()
zy.detail(this.video.detail).then((res: any) => {
this.urls = res.urls
if (this.xg === null) {
let info: any = this.urls[this.video.index]
let url = info.split('$')[1]
this.num = info.split('$')[0]
this.config.url = url
this.$nextTick(() => {
this.xg = new Hls(this.config)
// @ts-ignore
this.xg.on('ended', () => {
if (this.urls.length > 1 && (this.urls.length - 1 > this.video.index)) {
this.$message.success('自动播放下一集')
this.video.index++
let v: any = this.urls[this.video.index]
let url = v.split('$')[1]
this.num = v.split('$')[0]
// @ts-ignore
this.xg.src = url
video.find({ detail: this.video.detail }).then(res => {
if (res) {
video.update(res.id, this.video)
}
})
}
})
})
}
})
},
checkStar () {
video.find({ detail: this.video.detail }).then(res => {
if (res) {
this.star = true
} else {
this.star = false
}
})
},
starEvent () {
video.find({ detail: this.video.detail }).then(res => {
if (res) {
video.remove(res.id).then(res => {
if (!res) {
this.$message.success('删除成功')
this.star = false
} else {
this.$message.warning('删除失败, 请重试~')
}
})
} else {
video.add(this.video).then(res => {
this.star = true
this.$message.success('收藏成功')
})
}
})
},
mobileEvent () {
let info = this.urls[this.video.index]
// @ts-ignore
let time = this.xg.currentTime
const canvas = qrcanvas({
size: 120,
data: `http://zy.hly120506.top/player/index.html?info=${info}&time=${time}`
})
const dom = document.getElementById('qrcode')
if (dom) {
dom.innerHTML = ''
dom.appendChild(canvas)
}
},
shareEvent () {
let info: string = this.urls[this.video.index]
let title = this.video.name.replace(/^\s*|\s*$/g, '')
let url = info.split('$')[1]
let data = `http://zy.hly120506.top/player/index.html?info=${url}`
let txt = `资源名称: ${title}\n播放地址:${data}`
clipboard.writeText(txt)
this.$message.success('资源已复制到剪贴板中,快去分享吧~')
},
playBtnClick (i: string, j: number) {
if (this.video.index !== j) {
let url = i.split('$')[1]
this.num = i.split('$')[0]
this.video.index = j
// @ts-ignore
this.xg.src = url
video.find({ detail: this.video.detail }).then(res => {
if (res) {
this.video.index = j
video.update(res.id, this.video)
}
})
}
}
}
})
</script>
<style lang="scss" scoped>
.player{
height: 100%;
width: 100%;
position: relative;
.player-show{
height: 100%;
width: 100%;
position: relative;
}
.player-none{
height: 100%;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
.tips{
font-size: 14px;
margin-bottom: 10px;
}
}
.player-title{
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 50px;
line-height: 50px;
.player-title-box{
width: 600px;
margin: 0 auto;
}
}
.player-box{
position: absolute;
top: 50px;
left: 0;
width: 100%;
height: 350px;
#xg{
margin: 0 auto;
}
}
.player-films{
position: absolute;
top: 400px;
left: 0;
width: 100%;
height: calc(100% - 400px);
overflow: auto;
button{
margin: 0 10px 10px 0;
}
&::-webkit-scrollbar{
width: 6px;
}
.player-films-box{
width: 600px;
margin: 0 auto;
}
}
}
</style>

View File

@@ -1,16 +0,0 @@
import Vue from 'vue'
import Film from './film.vue'
import Search from './search.vue'
import Player from './player.vue'
import Star from './star.vue'
import Setting from './setting.vue'
export default {
registerComponents () {
Vue.component('Film', Film)
Vue.component('Search', Search)
Vue.component('Player', Player)
Vue.component('Star', Star)
Vue.component('Setting', Setting)
}
}

View File

@@ -1,199 +0,0 @@
<template>
<el-row class="search">
<el-row class="search-box" :class="table === true ? 'search-box hasTable' : 'search-box'">
<el-input class="search-input" size="medium" clearable placeholder="请输入资源名称..." v-model.trim="keywords" @change="searchEvent" @clear="clearEvent">
<el-select v-model="site" slot="prepend" placeholder="请选择" @change="selectSite" style="width: 130px;">
<el-option v-for="(i, j) in sites" :key="i.id" :label="i.name" :value="j"></el-option>
</el-select>
<el-button slot="append" icon="el-icon-search" @click="searchEvent"></el-button>
</el-input>
</el-row>
<el-row v-show="table" class="search-table-box table-box">
<el-table :data="filmData" stripe class="search-table" size="mini" v-loading="loading">
<el-table-column prop="name" label="影片名称"></el-table-column>
<el-table-column prop="type" label="影片类别" width="120"></el-table-column>
<el-table-column prop="time" label="更新时间" width="180"></el-table-column>
<el-table-column label="操作" width="120">
<template slot-scope="scope">
<el-button size="small" type="text" @click="tableBtnClick('detail', scope.row)">详情</el-button>
<el-button size="small" type="text" @click="tableBtnClick('star', scope.row)">收藏</el-button>
<el-button size="small" type="text" @click="tableBtnClick('play', scope.row)">播放</el-button>
</template>
</el-table-column>
</el-table>
</el-row>
<el-row v-show="table" class="search-bottom" type="flex" justify="end">
<el-pagination
small
layout="total, prev, pager, next, jumper"
:current-page="filmPage"
:page-size="50"
@current-change="pageChange"
:total="filmTotal">
</el-pagination>
</el-row>
</el-row>
</template>
<script lang="ts">
import Vue from 'vue'
import sites from '@/lib/sites'
import zy from '@/lib/util.zy'
import { mapMutations } from 'vuex'
import video from '@/plugins/dexie/video'
export default Vue.extend({
data () {
return {
table: false,
sites: sites,
keywords: '',
filmData: [],
filmPage: 1,
filmTotal: 0,
loading: false
}
},
computed: {
video: {
get () {
return this.$store.getters.getVideo
},
set (val) {
this.SET_VIDEO(val)
}
},
site: {
get () {
return this.$store.getters.getSite
},
set (val) {
this.SET_SITE(val)
}
},
Main: {
get () {
return this.$store.getters.getMain
},
set (val) {
this.SET_MAIN(val)
}
}
},
methods: {
...mapMutations(['SET_SITE', 'SET_DETAIL', 'SET_MAIN', 'SET_VIDEO']),
selectSite (e:number) {
this.site = e
this.filmData = []
this.filmPage = 1
this.filmTotal = 0
this.searchEvent()
},
searchEvent () {
if (this.keywords !== '') {
this.loading = true
this.table = true
zy.info(this.site, this.filmPage, this.keywords).then((res: any) => {
this.filmData = res.list
this.filmTotal = res.total
this.loading = false
})
}
},
clearEvent () {
this.loading = false
this.filmData = []
this.filmTotal = 0
this.filmPage = 1
this.table = false
},
pageChange (e:number) {
this.filmPage = e
this.searchEvent()
},
tableBtnClick (type: string, e: any) {
if (type === 'detail') {
let d = {
show: true,
video: e
}
this.SET_DETAIL(d)
}
if (type === 'star') {
video.find({ detail: e.detail }).then(res => {
if (res) {
this.$message.warning('已存在')
} else {
video.add(e).then(res => {
this.$message.success('收藏成功')
})
}
})
}
if (type === 'play') {
this.Main = 'Player'
this.video = e
}
}
}
})
</script>
<style lang="scss" scoped>
.search{
height: 100%;
position: relative;
.search-box{
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 40px;
display: flex;
justify-content: center;
align-items: center;
animation: slideDown 0.6s cubic-bezier(0.250, 0.460, 0.450, 0.940) both;
@keyframes slideDown {
from {
height: 40px;
}
to{
height: 90%;
}
}
&.hasTable{
animation: slideUp 0.2s cubic-bezier(0.250, 0.460, 0.450, 0.940) both;
}
@keyframes slideUp {
from {
height: 90%;
opacity: 0;
}
to{
height: 40px;
opacity: 1;
}
}
}
.search-table-box{
position: absolute;
top: 40px;
width: 100%;
height: calc(100% - 100px);
overflow: auto;
&::-webkit-scrollbar{
width: 6px;
}
.search-table{
width: 100%;
}
}
.search-bottom{
position: absolute;
bottom: 0;
left: 0;
width: 100%;
height: 40px;
display: flex;
justify-content: flex-end;
align-items: center;
}
}
</style>

View File

@@ -1,217 +0,0 @@
<template>
<el-row class="setting">
<el-row class="setting-box table-box">
<el-row class="item site">
<el-row class="title"><i class="el-icon-set-up"></i><span>默认资源</span></el-row>
<el-row class="info">
<el-select v-model="dbSite" placeholder="请选择" size="small" @change="selectSite">
<el-option
v-for="(i, j) in sites"
:key="i.id"
:label="i.name"
:value="j">
</el-option>
</el-select>
</el-row>
</el-row>
<el-row class="item opacity">
<el-row class="title"><i class="el-icon-stopwatch"></i><span>透明度</span></el-row>
<el-row class="info">
<el-slider v-model="opacity" :min="50" :max="100" @input="setOpacity"></el-slider>
</el-row>
</el-row>
<el-row class="item theme">
<el-row class="title"><i class="el-icon-picture-outline-round"></i><span>主题</span></el-row>
<el-row class="card-box">
<el-card shadow="hover" class="card">
<img src="@/assets/image/light.png" class="image" @click="selectTheme('light')">
<span size="mini">Light</span>
</el-card>
<el-card shadow="hover" class="card">
<img src="@/assets/image/dark.png" class="image" @click="selectTheme('dark')">
<span size="mini">Dark</span>
</el-card>
<el-card shadow="hover" class="card">
<img src="@/assets/image/pink.png" class="image" @click="selectTheme('pink')">
<span size="mini">Pink</span>
</el-card>
<el-card shadow="hover" class="card">
<img src="@/assets/image/green.png" class="image" @click="selectTheme('green')">
<span size="mini">Green</span>
</el-card>
</el-row>
</el-row>
<el-row class="item about">
<el-row class="title"><i class="el-icon-view"></i><span>关于</span></el-row>
<el-row class="info">
<ul>
<li><el-link :underline="false" @click="linkOpen('https://github.com/Hunlongyu/ZY-Player')">官网: ZY Player</el-link></li>
<li><el-link :underline="false" @click="linkOpen('https://github.com/Hunlongyu/ZY-Player/issues')">反馈: Issues</el-link></li>
</ul>
</el-row>
</el-row>
<el-row class="item opacity">
<el-row class="title"><i class="el-icon-coffee"></i><span>请我喝一杯咖啡</span></el-row>
<el-row class="qrcode">
<img src="@/assets/image/alipay.png" alt="">
<img src="@/assets/image/wepay.jpg" alt="">
</el-row>
</el-row>
</el-row>
</el-row>
</template>
<script lang="ts">
import Vue from 'vue'
import sites from '@/lib/sites'
import { mapMutations } from 'vuex'
import { shell } from 'electron'
import site from '@/plugins/dexie/site'
import theme from '@/plugins/dexie/theme'
import fly from 'flyio'
const { ipcRenderer: ipc } = require('electron')
export default Vue.extend({
name: 'setting',
data () {
return {
sites: sites,
dbSite: 0,
opacity: 100,
download: false
}
},
computed: {
site: {
get () {
return this.$store.getters.getSite
},
set (val) {
this.SET_SITE(val)
}
},
theme: {
get () {
return this.$store.getters.getTheme
},
set (val) {
this.SET_THEME(val)
}
}
},
methods: {
...mapMutations(['SET_SITE', 'SET_THEME']),
linkOpen (e:string) {
if (e) {
shell.openExternal(e)
}
},
initSetting () {
site.find().then(res => {
if (!res) {
site.add({ site: 0 })
} else {
this.dbSite = res.site
this.site = res.site
}
})
theme.find().then(res => {
if (!res) {
theme.add({ theme: 'light' })
} else {
this.theme = res.theme
}
})
},
selectSite () {
site.update({ site: this.dbSite }).then(res => {
this.site = this.dbSite
this.$message.success('设置默认资源成功~')
}).catch(() => {
this.$message.warning('设置默认资源失败~')
})
},
selectTheme (e: string) {
theme.update({ theme: e }).then(res => {
this.theme = e
this.$message.success('切换主题成功~')
}).catch(() => {
this.$message.warning('切换主题失败~')
})
},
setOpacity () {
ipc.send('opacity', this.opacity / 100)
}
},
created () {
this.initSetting()
}
})
</script>
<style lang="scss" scoped>
.setting{
height: 100%;
position: relative;
.setting-box{
position: absolute;
width: 100%;
height: 100%;
overflow: auto;
&::-webkit-scrollbar{
width: 6px;
}
}
.item{
margin-bottom: 20px;
.title{
height: 24px;
line-height: 24px;
margin-bottom: 10px;
display: flex;
align-items: center;
i{
font-size: 24px;
margin-right: 6px;
}
}
}
.about{
ul{
list-style: none;
li{
height: 30px;
}
}
}
.opacity{
.info{
width: 196px;
margin-left: 12px;
}
}
.theme{
.card-box{
display: flex;
justify-content: flex-start;
.card{
width: 160px;
margin-right: 20px;
text-align: center;
img{
cursor: pointer;
width: 100%;
}
span{
font-size: 14px;
margin-top: 10px;
}
}
}
}
.qrcode{
img{
height: 300px;
width: auto;
margin: 0 4px;
}
}
}
</style>

View File

@@ -1,145 +0,0 @@
<template>
<el-row class="star">
<el-row class="star-table-box table-box">
<el-table :data="filmData" stripe class="film-table" size="mini" empty-text="收藏夹里空空的~快去填满吧~">
<el-table-column prop="name" label="影片名称"></el-table-column>
<el-table-column prop="type" label="影片类别" width="120"></el-table-column>
<el-table-column prop="time" label="更新时间" width="180"></el-table-column>
<el-table-column label="来源" width="120">
<template slot-scope="scope">
<span>{{ scope.row.detail | from }}</span>
</template>
</el-table-column>
<el-table-column label="操作" width="120">
<template slot-scope="scope">
<el-button size="small" type="text" @click="tableBtnClick('detail', scope.row)">详情</el-button>
<el-button size="small" type="text" @click="tableBtnClick('delete', scope.row)">删除</el-button>
<el-button size="small" type="text" @click="tableBtnClick('play', scope.row)">播放</el-button>
</template>
</el-table-column>
</el-table>
</el-row>
<el-row class="star-bottom">
<el-pagination
small
layout="total, prev, pager, next, jumper"
:current-page="filmPage"
:page-size="50"
:total="filmTotal">
</el-pagination>
</el-row>
</el-row>
</template>
<script lang="ts">
import Vue from 'vue'
import video from '@/plugins/dexie/video'
import sites from '@/lib/sites'
import { mapMutations } from 'vuex'
export default Vue.extend({
data () {
return {
filmData: [],
filmPage: 1,
filmTotal: 0
}
},
filters: {
from (e: string) {
for (let i in sites) {
let url = sites[i].url
let f = e.indexOf(url)
if (f >= 0) {
return sites[i].name
}
}
}
},
computed: {
video: {
get () {
return this.$store.getters.getVideo
},
set (val) {
this.SET_VIDEO(val)
}
},
Main: {
get () {
return this.$store.getters.getMain
},
set (val) {
this.SET_MAIN(val)
}
}
},
watch: {
Main: {
handler () {
this.getAllStar()
},
deep: true
}
},
methods: {
...mapMutations(['SET_DETAIL', 'SET_VIDEO', 'SET_MAIN']),
getAllStar () {
video.all().then(res => {
this.filmData = res
this.filmTotal = res.length
})
},
tableBtnClick (type: string, e: any) {
if (type === 'detail') {
let d = {
show: true,
video: e
}
this.SET_DETAIL(d)
}
if (type === 'delete') {
video.remove(e.id).then(res => {
if (!res) {
this.$message.success('删除成功')
} else {
this.$message.warning('删除失败, 请重试~')
}
this.getAllStar()
})
}
if (type === 'play') {
this.Main = 'Player'
this.video = e
}
}
},
created () {
this.getAllStar()
}
})
</script>
<style lang="scss" scoped>
.star{
height: 100%;
position: relative;
.star-table-box{
position: absolute;
top: 0px;
width: 100%;
height: calc(100% - 40px);
overflow: auto;
&::-webkit-scrollbar{
width: 6px;
}
}
.star-bottom{
position: absolute;
bottom: 0;
left: 0;
width: 100%;
height: 40px;
display: flex;
justify-content: flex-end;
align-items: center;
}
}
</style>

View File

@@ -1,42 +0,0 @@
import Dexie from 'dexie'
class ZYDB extends Dexie {
theme: Dexie.Table<theme, number>
site: Dexie.Table<site, number>
video: Dexie.Table<video, number>
constructor () {
super('ZYDB')
this.version(1).stores({
theme: '++id, theme',
site: '++id, site',
video: '++id, name, type, time, detail, urls, index'
})
this.theme = this.table('theme')
this.site = this.table('site')
this.video = this.table('video')
}
}
export interface theme {
id: number
theme?: string
}
export interface site {
id: number
site?: number
}
export interface video {
id?: number
name?: string
type?: string
time?: string
detail?: string
urls?: Array<string>
index?: number
}
export default new ZYDB()

View File

@@ -1,33 +0,0 @@
import db from './index'
export default {
add (data: any): Promise<any> {
return new Promise((resolve, reject) => {
db.site.add(data).then(res => {
resolve(res)
}).catch(err => {
reject(err)
})
})
},
find (): Promise<any> {
return new Promise((resolve, reject) => {
db.site.get(1).then((res: any) => {
resolve(res)
}).catch(err => {
reject(err)
})
})
},
update (data: any): Promise<any> {
return new Promise((resolve, reject) => {
db.site.update(1, data).then(updated => {
if (updated) {
resolve(updated)
} else {
reject(updated)
}
})
})
}
}

View File

@@ -1,33 +0,0 @@
import db from './index'
export default {
add (data: any): Promise<any> {
return new Promise((resolve, reject) => {
db.theme.add(data).then(res => {
resolve(res)
}).catch(err => {
reject(err)
})
})
},
find (): Promise<any> {
return new Promise((resolve, reject) => {
db.theme.get(1).then((res: any) => {
resolve(res)
}).catch(err => {
reject(err)
})
})
},
update (data: any): Promise<any> {
return new Promise((resolve, reject) => {
db.theme.update(1, data).then(updated => {
if (updated) {
resolve(updated)
} else {
reject(updated)
}
})
})
}
}

View File

@@ -1,69 +0,0 @@
import db from './index'
export default {
add (data: any): Promise<any> {
return new Promise((resolve, reject) => {
db.video.add(data).then(res => {
resolve(res)
}).catch(err => {
reject(err)
})
})
},
find (data: any): Promise<any> {
return new Promise((resolve, reject) => {
db.video.get(data).then(res => {
resolve(res)
}).catch(err => {
reject(err)
})
})
},
all (): Promise<any> {
return new Promise((resolve, reject) => {
db.video.toArray().then(res => {
resolve(res)
}).catch(err => {
reject(err)
})
})
},
update (id: number, data: any): Promise<any> {
return new Promise((resolve, reject) => {
db.video.update(id, data).then(updated => {
if (updated) {
resolve(updated)
} else {
reject(updated)
}
})
})
},
count (): Promise<any> {
return new Promise((resolve, reject) => {
db.video.count().then(res => {
resolve(res)
}).catch(err => {
reject(err)
})
})
},
remove (id: number) {
return new Promise((resolve, reject) => {
db.video.delete(id).then(res => {
resolve(res)
}).catch(err => {
reject(err)
})
})
},
clear () {
return new Promise((resolve, reject) => {
db.video.clear().then(res => {
resolve(res)
}).catch(err => {
reject(err)
})
})
}
}

View File

@@ -1,32 +0,0 @@
import Vue from 'vue'
import {
Container, Row, Col, Header, Aside, Main, Drawer,
Tabs, TabPane, Button, Select, Option, Pagination,
Table, TableColumn, Input, Card, Link, Loading,
Notification, Message, Slider, Popover
} from 'element-ui'
Vue.use(Container)
Vue.use(Row)
Vue.use(Col)
Vue.use(Header)
Vue.use(Aside)
Vue.use(Main)
Vue.use(Drawer)
Vue.use(Tabs)
Vue.use(TabPane)
Vue.use(Button)
Vue.use(Select)
Vue.use(Option)
Vue.use(Pagination)
Vue.use(Table)
Vue.use(TableColumn)
Vue.use(Input)
Vue.use(Card)
Vue.use(Link)
Vue.use(Loading)
Vue.use(Slider)
Vue.use(Popover)
Vue.prototype.$notify = Notification
Vue.prototype.$message = Message

13
src/shims-tsx.d.ts vendored
View File

@@ -1,13 +0,0 @@
import Vue, { VNode } from 'vue'
declare global {
namespace JSX {
// tslint:disable no-empty-interface
interface Element extends VNode {}
// tslint:disable no-empty-interface
interface ElementClass extends Vue {}
interface IntrinsicElements {
[elem: string]: any
}
}
}

4
src/shims-vue.d.ts vendored
View File

@@ -1,4 +0,0 @@
declare module '*.vue' {
import Vue from 'vue'
export default Vue
}

View File

@@ -1,54 +0,0 @@
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
Main: 'Film',
site: 0,
theme: 'light',
detail: {
show: false,
video: ''
},
dUrl: '',
video: {}
},
getters: {
getMain: state => {
return state.Main
},
getSite: state => {
return state.site
},
getTheme: state => {
return state.theme
},
getDetail: state => {
return state.detail
},
getVideo: state => {
return state.video
}
},
mutations: {
SET_MAIN: (state, payload) => {
state.Main = payload
},
SET_SITE: (state, payload) => {
state.site = payload
},
SET_THEME: (state, payload) => {
state.theme = payload
},
SET_DETAIL: (state, payload) => {
state.detail = payload
},
SET_VIDEO: (state, payload) => {
state.video = payload
}
},
actions: {},
modules: {}
})

View File

@@ -1,39 +0,0 @@
{
"compilerOptions": {
"target": "esnext",
"module": "esnext",
"strict": true,
"jsx": "preserve",
"importHelpers": true,
"moduleResolution": "node",
"experimentalDecorators": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"sourceMap": true,
"baseUrl": ".",
"types": [
"webpack-env"
],
"paths": {
"@/*": [
"src/*"
]
},
"lib": [
"esnext",
"dom",
"dom.iterable",
"scripthost"
]
},
"include": [
"src/**/*.ts",
"src/**/*.tsx",
"src/**/*.vue",
"tests/**/*.ts",
"tests/**/*.tsx"
],
"exclude": [
"node_modules"
]
}

View File

@@ -1,29 +0,0 @@
module.exports = {
pluginOptions: {
electronBuilder: {
builderOptions: {
win: {
icon: './build/icons/icon.ico',
target: [
'nsis','portable', 'zip',
]
},
nsis: {
oneClick: false,
allowToChangeInstallationDirectory: true
},
productName: 'ZY Player',
publish: [{
'provider': 'github',
'owner': 'Hunlongyu',
'repo': 'ZY-Player'
}]
},
chainWebpackRendererProcess: config => {
if (process.env.NODE_ENV === 'development') {
config.plugins.delete('prefetch')
}
}
}
}
}

11383
yarn.lock

File diff suppressed because it is too large Load Diff