Compare commits
63 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9b1995e596 | ||
|
|
b89b56cce4 | ||
|
|
84e2f456f8 | ||
|
|
3e345bf57b | ||
|
|
d70da3dc3e | ||
|
|
8f6a8fef07 | ||
|
|
bda6e32b04 | ||
|
|
51fd2c47da | ||
|
|
5b3a2efc42 | ||
|
|
791febea06 | ||
|
|
402aa62589 | ||
|
|
70b49c8424 | ||
|
|
d22d52a317 | ||
|
|
c936e8479a | ||
|
|
ed8ceffd9c | ||
|
|
22c471332d | ||
|
|
99480f82e7 | ||
|
|
7695b6376d | ||
|
|
3e7eab6d5b | ||
|
|
123579cb1a | ||
|
|
b1b55042b5 | ||
|
|
5549b59730 | ||
|
|
474717c2df | ||
|
|
81c17e5104 | ||
|
|
c8e6e8703c | ||
|
|
74a7d6b35b | ||
|
|
055813eabd | ||
|
|
6311cba1d1 | ||
|
|
8ea52857a5 | ||
|
|
0776147a89 | ||
|
|
75cc6dd3c1 | ||
|
|
ba8312b78c | ||
|
|
5b51f18675 | ||
|
|
307391da4d | ||
|
|
8d1d751a3c | ||
|
|
d64a834c7f | ||
|
|
b5778be234 | ||
|
|
5bf514ffcc | ||
|
|
8e380b6463 | ||
|
|
152b654d41 | ||
|
|
8f10dcfb20 | ||
|
|
d0024458ea | ||
|
|
f6d479de21 | ||
|
|
40cb662e7e | ||
|
|
f271d92149 | ||
|
|
4d391dbe14 | ||
|
|
5b52dad32b | ||
|
|
d74485eaaf | ||
|
|
10baba4241 | ||
|
|
90a2c55059 | ||
|
|
aea794bf29 | ||
|
|
636ef602b1 | ||
|
|
b75de05f09 | ||
|
|
9a14219418 | ||
|
|
2a0afa6ce0 | ||
|
|
f003b1b148 | ||
|
|
55ac770461 | ||
|
|
4505186307 | ||
|
|
9ce1a8ddf6 | ||
|
|
ee1fb8fbe5 | ||
|
|
8bee55f706 | ||
|
|
7c5dd0be8d | ||
|
|
ffee7321a0 |
@@ -1,2 +1,3 @@
|
||||
> 1%
|
||||
last 2 versions
|
||||
not dead
|
||||
|
||||
15
.eslintrc.js
@@ -3,16 +3,15 @@ module.exports = {
|
||||
env: {
|
||||
node: true
|
||||
},
|
||||
'extends': [
|
||||
extends: [
|
||||
'plugin:vue/essential',
|
||||
'@vue/standard',
|
||||
'@vue/typescript'
|
||||
'@vue/standard'
|
||||
],
|
||||
rules: {
|
||||
'no-console': process.env.NODE_ENV === 'production' ? 'error' : 'off',
|
||||
'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off'
|
||||
},
|
||||
parserOptions: {
|
||||
parser: '@typescript-eslint/parser'
|
||||
parser: 'babel-eslint'
|
||||
},
|
||||
rules: {
|
||||
'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
|
||||
'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off'
|
||||
}
|
||||
}
|
||||
|
||||
35
.github/workflows/release.yml
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
name: release-build
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- v*.*.*
|
||||
|
||||
jobs:
|
||||
release:
|
||||
runs-on: ${{ matrix.os }}
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
os: [windows-latest, macos-latest, ubuntu-latest]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-node@v1
|
||||
with:
|
||||
node-version: 12
|
||||
|
||||
- run: |
|
||||
yarn
|
||||
yarn release
|
||||
shell: pwsh
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Release
|
||||
uses: softprops/action-gh-release@v1
|
||||
with:
|
||||
files: |
|
||||
dist_electron/win-unpacked/*.exe
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
51
README.md
@@ -1,45 +1,42 @@
|
||||
<p align="center">
|
||||
<img src="https://i.loli.net/2020/01/20/WEj3Yw8rPXqTcHe.png" >
|
||||
<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 src="https://github.com/aleen42/badges/raw/master/src/visual_studio_code_flat_square.svg?sanitize=true">
|
||||
<img src="https://github.com/aleen42/badges/raw/master/src/vue_flat_square.svg?sanitize=true">
|
||||
<img src="https://github.com/aleen42/badges/raw/master/src/javascript_flat_square.svg?sanitize=true">
|
||||
<img src="https://github.com/aleen42/badges/raw/master/src/eslint_flat_square.svg?sanitize=true">
|
||||
</p>
|
||||
<p align="center">
|
||||
<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">
|
||||
<img alt="GitHub" src="https://img.shields.io/github/license/Hunlongyu/ZY-Player?style=for-the-badge">
|
||||
<img src="https://img.shields.io/github/workflow/status/Hunlongyu/ZY-Player/release-build?style=for-the-badge">
|
||||
<p>
|
||||
|
||||
# ZY Player
|
||||
资源播放器, 提供影视资源的浏览,搜索,播放,收藏,查看详情等功能.
|
||||
|
||||
### 下载:
|
||||
[下载地址](https://github.com/Hunlongyu/ZY-Player/releases)
|
||||
## ZY Player
|
||||
|
||||
### 截图:
|
||||
主界面 ⬇
|
||||

|
||||
暗黑主题 ⬇
|
||||

|
||||
搜索 ⬇
|
||||

|
||||
搜索结果 ⬇
|
||||

|
||||
详情 ⬇
|
||||

|
||||
播放 ⬇
|
||||

|
||||
收藏 ⬇
|
||||

|
||||
|
||||
### 开发计划:
|
||||
[第二期开发计划](https://github.com/Hunlongyu/ZY-Player/projects/2)
|
||||
### 新版内测
|
||||
|
||||
### 未完成:
|
||||
1. 更换图标: 求大神设计一个 zy 的logo, 256x256 像素,风格请参考:
|
||||
新版本: v0.9.x 已开发完, 现进行内测, [点击查看内测公告](https://github.com/Hunlongyu/ZY-Player/issues/24)
|
||||
|
||||

|
||||
[点击这里可以查看开发计划](https://github.com/Hunlongyu/ZY-Player/projects/3).
|
||||
|
||||
大家有什么新的需求建议欢迎踊跃提出[点击这里提意见](https://github.com/Hunlongyu/ZY-Player/issues/14)
|
||||
|
||||
1. [Github -- 官方下载](https://github.com/Hunlongyu/ZY-Player/releases)
|
||||
|
||||
2. [蓝奏云 -- 快速下载](https://www.lanzous.com/b04s6a3re) 密码:95px
|
||||
|
||||
#### 截图:
|
||||

|
||||

|
||||

|
||||
|
||||
### 重要:
|
||||
所有资源来自网上, 该软件不参与任何制作, 上传, 储存, 下载等内容. 该软件仅供学习参考, 请于安装后24小时内删除.
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
module.exports = {
|
||||
'presets': [
|
||||
presets: [
|
||||
'@vue/cli-plugin-babel/preset'
|
||||
],
|
||||
'plugins': [
|
||||
plugins: [
|
||||
[
|
||||
'component',
|
||||
{
|
||||
'libraryName': 'element-ui',
|
||||
'styleLibraryName': 'theme-chalk'
|
||||
libraryName: 'element-ui',
|
||||
styleLibraryName: 'theme-chalk'
|
||||
}
|
||||
]
|
||||
]
|
||||
|
||||
|
Before Width: | Height: | Size: 93 KiB After Width: | Height: | Size: 233 KiB |
|
Before Width: | Height: | Size: 4.5 KiB After Width: | Height: | Size: 9.3 KiB |
|
Before Width: | Height: | Size: 497 B After Width: | Height: | Size: 831 B |
|
Before Width: | Height: | Size: 891 B After Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 8.0 KiB After Width: | Height: | Size: 20 KiB |
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 2.0 KiB |
|
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 3.4 KiB |
|
Before Width: | Height: | Size: 32 KiB After Width: | Height: | Size: 80 KiB |
|
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 4.4 KiB |
|
Before Width: | Height: | Size: 353 KiB After Width: | Height: | Size: 353 KiB |
@@ -1 +1 @@
|
||||
zy.hly120506.top
|
||||
zyplayer.fun
|
||||
3
docs/dist/css/style.css
vendored
1
docs/dist/images/cta-illustration-dark.svg
vendored
|
Before Width: | Height: | Size: 23 KiB |
1
docs/dist/images/cta-illustration-light.svg
vendored
|
Before Width: | Height: | Size: 23 KiB |
1
docs/dist/images/feature-01-dark.svg
vendored
@@ -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 |
1
docs/dist/images/feature-01-light.svg
vendored
@@ -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 |
1
docs/dist/images/feature-02-dark.svg
vendored
@@ -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 |
1
docs/dist/images/feature-02-light.svg
vendored
@@ -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 |
1
docs/dist/images/feature-03-dark.svg
vendored
@@ -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 |
1
docs/dist/images/feature-03-light.svg
vendored
@@ -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 |
|
Before Width: | Height: | Size: 9.7 KiB |
|
Before Width: | Height: | Size: 9.7 KiB |
|
Before Width: | Height: | Size: 7.7 KiB |
|
Before Width: | Height: | Size: 7.7 KiB |
|
Before Width: | Height: | Size: 9.5 KiB |
|
Before Width: | Height: | Size: 10 KiB |
|
Before Width: | Height: | Size: 21 KiB |
|
Before Width: | Height: | Size: 21 KiB |
1
docs/dist/images/logo-dark.svg
vendored
@@ -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 |
1
docs/dist/images/logo-light.svg
vendored
@@ -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 |
1
docs/dist/js/main.min.js
vendored
@@ -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))}();
|
||||
150
docs/index.html
@@ -1,149 +1,11 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" class="no-js">
|
||||
<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">
|
||||
<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>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>官网</title>
|
||||
</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>
|
||||
待重建
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -1,54 +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 url = info.split('$')[1]
|
||||
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>
|
||||
38
docs/player/player.html
Normal file
@@ -0,0 +1,38 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name=viewport content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no,minimal-ui">
|
||||
<meta name="referrer" content="no-referrer">
|
||||
<title>ZY Player</title>
|
||||
<style type="text/css">
|
||||
html, body {width:100%;height:100%;margin:0;padding:0;overflow:hidden;}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="mse"></div>
|
||||
<script src="//cdn.jsdelivr.net/npm/xgplayer@1.1.4/browser/index.js" charset="utf-8"></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 url = get('url')
|
||||
let player = new HlsJsPlayer({
|
||||
"id": "mse",
|
||||
"url": url,
|
||||
"playsinline": true,
|
||||
"autoplay": true,
|
||||
"fluid": true,
|
||||
"height": window.innerHeight,
|
||||
"width": window.innerWidth,
|
||||
"playbackRate": [ 0.5, 0.75, 1, 1.25, 1.5, 1.75, 2, 3 ],
|
||||
"x5-video-player-type": "h5",
|
||||
"x5-video-player-fullscreen": "true",
|
||||
"x5-video-orientation": "landscape"
|
||||
})
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
72
package.json
@@ -1,54 +1,58 @@
|
||||
{
|
||||
"name": "zy",
|
||||
"version": "0.8.9",
|
||||
"author": "Hunlongyu",
|
||||
"description": "ZY Player 资源播放器",
|
||||
"version": "0.9.19",
|
||||
"private": true,
|
||||
"author": {
|
||||
"name": "Hunlongyu",
|
||||
"email": "hunlongyu@gmail.com"
|
||||
},
|
||||
"description": "ZY Player 资源播放器",
|
||||
"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",
|
||||
"dev": "vue-cli-service electron:serve",
|
||||
"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 -p always"
|
||||
"release": "vue-cli-service electron:build -p always"
|
||||
},
|
||||
"main": "background.js",
|
||||
"dependencies": {
|
||||
"core-js": "^3.4.4",
|
||||
"axios": "^0.19.2",
|
||||
"core-js": "^3.6.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",
|
||||
"electron-updater": "^4.2.5",
|
||||
"element-ui": "^2.13.1",
|
||||
"html2canvas": "^1.0.0-rc.5",
|
||||
"leancloud-storage": "^4.5.3",
|
||||
"macaddress": "^0.2.9",
|
||||
"modern-normalize": "^0.6.0",
|
||||
"qrcode.vue": "^1.7.0",
|
||||
"vue": "^2.6.11",
|
||||
"vue-i18n": "^8.17.0",
|
||||
"vuex": "^3.1.3",
|
||||
"xgplayer": "^2.6.14",
|
||||
"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",
|
||||
"@vue/cli-plugin-babel": "~4.3.0",
|
||||
"@vue/cli-plugin-eslint": "~4.3.0",
|
||||
"@vue/cli-plugin-vuex": "~4.3.0",
|
||||
"@vue/cli-service": "~4.3.0",
|
||||
"@vue/eslint-config-standard": "^5.1.2",
|
||||
"babel-eslint": "^10.1.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"
|
||||
"electron": "^8.2.1",
|
||||
"eslint": "^6.7.2",
|
||||
"eslint-plugin-import": "^2.20.2",
|
||||
"eslint-plugin-node": "^11.1.0",
|
||||
"eslint-plugin-promise": "^4.2.1",
|
||||
"eslint-plugin-standard": "^4.0.0",
|
||||
"eslint-plugin-vue": "^6.2.2",
|
||||
"sass": "^1.26.3",
|
||||
"sass-loader": "^8.0.2",
|
||||
"vue-cli-plugin-electron-builder": "2.0.0-beta.6",
|
||||
"vue-template-compiler": "^2.6.11"
|
||||
}
|
||||
}
|
||||
|
||||
BIN
public/icon.png
|
Before Width: | Height: | Size: 8.6 KiB After Width: | Height: | Size: 17 KiB |
@@ -5,11 +5,20 @@
|
||||
<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>
|
||||
<title><%= htmlWebpackPlugin.options.title %></title>
|
||||
<script>
|
||||
var _hmt = _hmt || [];
|
||||
(function() {
|
||||
var hm = document.createElement("script");
|
||||
hm.src = "https://hm.baidu.com/hm.js?62aeb2505bfa26a2461d2a7a3b485096";
|
||||
var s = document.getElementsByTagName("script")[0];
|
||||
s.parentNode.insertBefore(hm, s);
|
||||
})();
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<noscript>
|
||||
<strong>We're sorry but zy doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
|
||||
<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
|
||||
</noscript>
|
||||
<div id="app"></div>
|
||||
<!-- built files will be auto injected -->
|
||||
|
||||
155
src/App.vue
@@ -1,65 +1,38 @@
|
||||
<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>
|
||||
<div id="app" :class="appTheme">
|
||||
<Aside />
|
||||
<div class="zy-body">
|
||||
<Frame />
|
||||
<Film v-show="view === 'Film'" />
|
||||
<Play v-show="view === 'Play'" />
|
||||
<Star v-show="view === 'Star'" />
|
||||
<Setting v-show="view === 'Setting'" />
|
||||
</div>
|
||||
<transition name="slide">
|
||||
<Detail v-if="detail.show"/>
|
||||
</transition>
|
||||
<transition name="slide">
|
||||
<Share v-if="share.show"/>
|
||||
</transition>
|
||||
</div>
|
||||
</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({
|
||||
<script>
|
||||
export default {
|
||||
name: 'App',
|
||||
data () {
|
||||
return {
|
||||
appTheme: 'theme-light'
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
Main: {
|
||||
get () {
|
||||
return this.$store.getters.getMain
|
||||
},
|
||||
set (val) {
|
||||
this.SET_MAIN(val)
|
||||
}
|
||||
view () {
|
||||
return this.$store.getters.getView
|
||||
},
|
||||
detail: {
|
||||
get () {
|
||||
return this.$store.getters.getDetail
|
||||
},
|
||||
set (val) {
|
||||
this.SET_DETAIL(val)
|
||||
}
|
||||
detail () {
|
||||
return this.$store.getters.getDetail
|
||||
},
|
||||
share () {
|
||||
return this.$store.getters.getShare
|
||||
},
|
||||
theme () {
|
||||
return this.$store.getters.getTheme
|
||||
@@ -70,72 +43,38 @@ export default Vue.extend({
|
||||
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';
|
||||
*{
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
html,body{
|
||||
@import './assets/scss/theme.scss';
|
||||
html, body, #app{
|
||||
height: 100%;
|
||||
border-radius: 6px;
|
||||
}
|
||||
#app{
|
||||
#app {
|
||||
font-family: 'Helvetica Neue', Helvetica, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', SimSun, sans-serif;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-webkit-tap-highlight-color: transparent;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
user-select: none;
|
||||
.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{
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: flex-start;
|
||||
.zy-body{
|
||||
flex: 1;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
align-items: flex-start;
|
||||
flex-direction: column;
|
||||
padding: 0 20px 20px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
BIN
src/assets/image/alipay.png
Normal file
|
After Width: | Height: | Size: 38 KiB |
|
Before Width: | Height: | Size: 72 KiB After Width: | Height: | Size: 80 KiB |
BIN
src/assets/image/green.png
Normal file
|
After Width: | Height: | Size: 61 KiB |
|
Before Width: | Height: | Size: 78 KiB After Width: | Height: | Size: 75 KiB |
BIN
src/assets/image/logo.png
Normal file
|
After Width: | Height: | Size: 20 KiB |
BIN
src/assets/image/wepay.jpg
Normal file
|
After Width: | Height: | Size: 232 KiB |
217
src/assets/scss/style.scss
Normal file
@@ -0,0 +1,217 @@
|
||||
// svg
|
||||
.zy-svg{
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
svg{
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
stroke-width: 1;
|
||||
stroke-linecap: round;
|
||||
stroke-linejoin: round;
|
||||
fill: none;
|
||||
}
|
||||
}
|
||||
|
||||
// select
|
||||
.zy-select{
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
width: 200px;
|
||||
height: 30px;
|
||||
cursor: pointer;
|
||||
border-radius: 3px;
|
||||
user-select: none;
|
||||
vertical-align: middle;
|
||||
.vs-placeholder{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding-left: 25px;
|
||||
padding-right: 25px;
|
||||
&::after{
|
||||
display: inline-block;
|
||||
margin-left: .255em;
|
||||
vertical-align: .255em;
|
||||
content: "";
|
||||
border-top: .3em solid;
|
||||
border-right: .3em solid transparent;
|
||||
border-bottom: 0;
|
||||
border-left: .3em solid transparent;
|
||||
}
|
||||
}
|
||||
.vs-options{
|
||||
z-index: 2;
|
||||
width: 100%;
|
||||
overflow-y: auto;
|
||||
min-height: 0;
|
||||
ul{
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
list-style: none;
|
||||
li{
|
||||
width: 100%;
|
||||
height: 30px;
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
padding-left: 25px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// table
|
||||
.zy-table{
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
font-size: 15px;
|
||||
.tHead{
|
||||
height: 50px;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
border-bottom: 1px solid;
|
||||
padding: 0 5px 0 0;
|
||||
font-weight: 600;
|
||||
span{
|
||||
display: flex;
|
||||
width: 180px;
|
||||
font-size: 16px;
|
||||
&.name{
|
||||
flex: 1;
|
||||
padding-left: 15px;
|
||||
}
|
||||
&.type{
|
||||
width: 120px;
|
||||
}
|
||||
&.from{
|
||||
width: 120px;
|
||||
}
|
||||
&.operate{
|
||||
width: 120px;
|
||||
}
|
||||
}
|
||||
}
|
||||
.tBody{
|
||||
flex: 1;
|
||||
overflow-y: scroll;
|
||||
border-bottom: 1px solid;
|
||||
ul{
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
li{
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
flex-direction: row;
|
||||
height: 50px;
|
||||
border-bottom: 1px solid;
|
||||
cursor: pointer;
|
||||
span{
|
||||
display: flex;
|
||||
width: 180px;
|
||||
font-size: 13px;
|
||||
height: 50px;
|
||||
line-height: 50px;
|
||||
&.name{
|
||||
flex: 1;
|
||||
padding-left: 15px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
&.type{
|
||||
width: 120px;
|
||||
}
|
||||
&.from{
|
||||
width: 120px;
|
||||
}
|
||||
&.operate{
|
||||
width: 120px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.tFooter{
|
||||
width: 100%;
|
||||
height: 40px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
flex-direction: row;
|
||||
padding-right: 10px;
|
||||
.tFooter-span{
|
||||
padding-left: 10px;
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// scroll
|
||||
.zy-scroll{
|
||||
&::-webkit-scrollbar{
|
||||
width: 5px;
|
||||
height: 1px;
|
||||
}
|
||||
&::-webkit-scrollbar-thumb {
|
||||
border-radius: 10px;
|
||||
position: absolute;
|
||||
}
|
||||
&::-webkit-scrollbar-track {
|
||||
border-radius: 10px;
|
||||
position: absolute;
|
||||
}
|
||||
}
|
||||
|
||||
// loading
|
||||
.zy-loading{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
.loader {
|
||||
font-size: 8px;
|
||||
width: 1em;
|
||||
height: 1em;
|
||||
border-radius: 50%;
|
||||
position: relative;
|
||||
text-indent: -9999em;
|
||||
animation: load4 1.3s infinite linear;
|
||||
transform: translateZ(0);
|
||||
}
|
||||
@keyframes load4 {
|
||||
0%,
|
||||
100% {
|
||||
box-shadow: 0 -3em 0 0.2em, 2em -2em 0 0em, 3em 0 0 -1em, 2em 2em 0 -1em, 0 3em 0 -1em, -2em 2em 0 -1em, -3em 0 0 -1em, -2em -2em 0 0;
|
||||
}
|
||||
12.5% {
|
||||
box-shadow: 0 -3em 0 0, 2em -2em 0 0.2em, 3em 0 0 0, 2em 2em 0 -1em, 0 3em 0 -1em, -2em 2em 0 -1em, -3em 0 0 -1em, -2em -2em 0 -1em;
|
||||
}
|
||||
25% {
|
||||
box-shadow: 0 -3em 0 -0.5em, 2em -2em 0 0, 3em 0 0 0.2em, 2em 2em 0 0, 0 3em 0 -1em, -2em 2em 0 -1em, -3em 0 0 -1em, -2em -2em 0 -1em;
|
||||
}
|
||||
37.5% {
|
||||
box-shadow: 0 -3em 0 -1em, 2em -2em 0 -1em, 3em 0em 0 0, 2em 2em 0 0.2em, 0 3em 0 0em, -2em 2em 0 -1em, -3em 0em 0 -1em, -2em -2em 0 -1em;
|
||||
}
|
||||
50% {
|
||||
box-shadow: 0 -3em 0 -1em, 2em -2em 0 -1em, 3em 0 0 -1em, 2em 2em 0 0em, 0 3em 0 0.2em, -2em 2em 0 0, -3em 0em 0 -1em, -2em -2em 0 -1em;
|
||||
}
|
||||
62.5% {
|
||||
box-shadow: 0 -3em 0 -1em, 2em -2em 0 -1em, 3em 0 0 -1em, 2em 2em 0 -1em, 0 3em 0 0, -2em 2em 0 0.2em, -3em 0 0 0, -2em -2em 0 -1em;
|
||||
}
|
||||
75% {
|
||||
box-shadow: 0em -3em 0 -1em, 2em -2em 0 -1em, 3em 0em 0 -1em, 2em 2em 0 -1em, 0 3em 0 -1em, -2em 2em 0 0, -3em 0em 0 0.2em, -2em -2em 0 0;
|
||||
}
|
||||
87.5% {
|
||||
box-shadow: 0em -3em 0 0, 2em -2em 0 -1em, 3em 0 0 -1em, 2em 2em 0 -1em, 0 3em 0 -1em, -2em 2em 0 0, -3em 0em 0 0, -2em -2em 0 0.2em;
|
||||
}
|
||||
}
|
||||
}
|
||||
61
src/assets/scss/theme.scss
Normal file
@@ -0,0 +1,61 @@
|
||||
:root{
|
||||
// light
|
||||
--l-c-0: #823aa0;
|
||||
--l-c-1: #823aa011;
|
||||
--l-c-2: #823aa022;
|
||||
--l-c-3: #823aa033;
|
||||
--l-c-5: #823aa055;
|
||||
--l-c-8: #823aa088;
|
||||
--l-c-9: #823aa099;
|
||||
--l-fc-1: #808695;
|
||||
--l-fc-2: #332f5c;
|
||||
--l-fc-3: #823aa0;
|
||||
--l-bgc-1: #ffffff;
|
||||
--l-bgc-2: #f2f6f9;
|
||||
--l-bsc: 0 3px 1px -2px #8e8da233, 0 2px 2px 0 #8e8da224, 0 1px 5px 0 #8e8da21f;
|
||||
--l-bsc-2: 0 -4px 23px 0 #8e8da233;
|
||||
--l-bsc-hover: 0 14px 26px -12px #8e8da26b, 0 4px 23px 0 #8e8da21f, 0 8px 10px -5px #8e8da233;
|
||||
--l-bsc-scroll: inset 0 0 5px #823aa005;
|
||||
|
||||
// dark
|
||||
--d-c-0: #38dd77;
|
||||
--d-c-1: #38dd7711;
|
||||
--d-c-2: #38dd7722;
|
||||
--d-c-3: #38dd7733;
|
||||
--d-c-5: #38dd7755;
|
||||
--d-c-8: #38dd7788;
|
||||
--d-c-9: #38dd7799;
|
||||
--d-fc-1: #808695;
|
||||
--d-fc-2: #acacac;
|
||||
--d-fc-3: #38dd77;
|
||||
--d-bgc-1: #222222;
|
||||
--d-bgc-2: #2f2f2f;
|
||||
--d-bsc: 0 3px 1px -2px #38dd7733, 0 2px 2px 0 #38dd7722, 0 1px 5px 0 #38dd7711;
|
||||
--d-bsc-2: 0 -4px 23px 0 #38dd7733;
|
||||
--d-bsc-hover: 0 14px 26px -12px #38dd7733, 0 4px 23px 0 #38dd7722, 0 8px 10px -5px #38dd7711;
|
||||
--d-bsc-scroll: inset 0 0 5px #38dd7705;
|
||||
|
||||
// green
|
||||
--g-c-0: #EAEF9D;
|
||||
--g-c-1: #EAEF9D11;
|
||||
--g-c-2: #EAEF9D22;
|
||||
--g-c-3: #EAEF9D33;
|
||||
--g-c-5: #EAEF9D55;
|
||||
--g-c-8: #EAEF9D88;
|
||||
--g-c-9: #EAEF9D99;
|
||||
--g-fc-1: #80B155;
|
||||
--g-fc-2: #C1D95CAA;
|
||||
--g-fc-3: #C1D95C;
|
||||
--g-bgc-1: #336A29;
|
||||
--g-bgc-2: #498428;
|
||||
--g-bsc: 0 3px 1px -2px #C1D95C33, 0 2px 2px 0 #C1D95C22, 0 1px 5px 0 #C1D95C11;
|
||||
--g-bsc-2: 0 -4px 23px 0 #C1D95C33;
|
||||
--g-bsc-hover: 0 14px 26px -12px #C1D95C33, 0 4px 23px 0 #C1D95C22, 0 8px 10px -5px #C1D95C11;
|
||||
--g-bsc-scroll: inset 0 0 5px #C1D95C05;
|
||||
}
|
||||
|
||||
@import './theme/light.scss';
|
||||
@import './theme/dark.scss';
|
||||
@import './theme/green.scss';
|
||||
|
||||
@import './style.scss';
|
||||
349
src/assets/scss/theme/dark.scss
Normal file
@@ -0,0 +1,349 @@
|
||||
.theme-dark{
|
||||
background-color: var(--d-bgc-1);
|
||||
.xgplayer-skin-default video{
|
||||
background-color: var(--d-bgc-2);
|
||||
}
|
||||
.el-pagination{
|
||||
background-color: var(--d-bgc-1);
|
||||
color: var(--d-fc-1);
|
||||
.el-pagination__total, .el-pagination__jump, .el-input__inner{
|
||||
color: var(--d-fc-1);
|
||||
background-color: var(--d-bgc-1);
|
||||
}
|
||||
.el-input__inner{
|
||||
border-color: var(--d-c-3);
|
||||
}
|
||||
.el-pager{
|
||||
.number{
|
||||
background-color: var(--d-bgc-1);
|
||||
}
|
||||
.number:hover{
|
||||
color: var(--d-c-8);
|
||||
}
|
||||
.active{
|
||||
color: var(--d-c-9);
|
||||
}
|
||||
}
|
||||
.more, .btn-next, .btn-prev{
|
||||
background-color: var(--d-bgc-1);
|
||||
&:hover{
|
||||
color: var(--d-c-8);
|
||||
}
|
||||
}
|
||||
}
|
||||
.zy-select{
|
||||
color: var(--d-fc-1);
|
||||
background-color: var(--d-bgc-1);
|
||||
box-shadow: var(--d-bsc);
|
||||
&:hover{
|
||||
box-shadow: var(--d-bsc-hover);
|
||||
}
|
||||
.vs-options{
|
||||
background-color: var(--d-bgc-1);
|
||||
box-shadow: var(--d-bsc);
|
||||
ul{
|
||||
li{
|
||||
&:hover{
|
||||
background-color: var(--d-c-1);
|
||||
}
|
||||
&.active{
|
||||
background-color: var(--d-c-3);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.zy-table{
|
||||
color: var(--d-fc-2);
|
||||
.tHead{
|
||||
background-color: var(--d-bgc-1);
|
||||
border-bottom-color: var(--d-c-3);
|
||||
}
|
||||
.tBody{
|
||||
border-bottom-color: var(--d-c-3);
|
||||
ul{
|
||||
li{
|
||||
border-bottom-color: var(--d-c-2);
|
||||
&:hover{
|
||||
animation: d-tableHoverAni 0.2s ease both;
|
||||
@keyframes d-tableHoverAni {
|
||||
to{
|
||||
box-shadow: var(--d-bsc-hover);
|
||||
}
|
||||
}
|
||||
}
|
||||
span{
|
||||
&.btn:hover{
|
||||
color: var(--d-fc-3)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.tFooter{
|
||||
.tFooter-span{
|
||||
color: var(--d-fc-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
.zy-scroll{
|
||||
&:hover{
|
||||
&::-webkit-scrollbar-thumb {
|
||||
box-shadow: var(--d-bsc-scroll);
|
||||
background: var(--d-c-3);
|
||||
}
|
||||
&::-webkit-scrollbar-track {
|
||||
box-shadow: var(--d-bsc-scroll);
|
||||
background: var(--bgc);
|
||||
}
|
||||
}
|
||||
}
|
||||
.zy-loading{
|
||||
.loader{
|
||||
color: var(--d-c-3);
|
||||
}
|
||||
}
|
||||
.zy-body{
|
||||
background-color: var(--d-bgc-2);
|
||||
}
|
||||
.aside{
|
||||
.zy-svg{
|
||||
svg{
|
||||
stroke: var(--d-c-0);
|
||||
}
|
||||
&:hover{
|
||||
background-color: var(--d-c-2);
|
||||
}
|
||||
&.active{
|
||||
svg{
|
||||
stroke: var(--d-c-0);
|
||||
stroke-width: 2;
|
||||
fill: var(--d-c-2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.frame{
|
||||
span{
|
||||
&.min{
|
||||
background-color: #ffbe2a;
|
||||
}
|
||||
&.close{
|
||||
background-color: #ff5f56;
|
||||
}
|
||||
}
|
||||
}
|
||||
.detail{
|
||||
color: var(--d-fc-1);
|
||||
background-color:var(--d-bgc-1);
|
||||
box-shadow: var(--d-bsc-2);
|
||||
.detail-content{
|
||||
.detail-close{
|
||||
svg{
|
||||
stroke-width: 1;
|
||||
stroke: var(--d-c-8);
|
||||
&:hover{
|
||||
stroke-width: 2px;
|
||||
stroke: var(--d-c-9);
|
||||
}
|
||||
}
|
||||
}
|
||||
.detail-body{
|
||||
.info, .desc, .m3u8_urls, .mp4_urls{
|
||||
border-color: var(--d-c-2);
|
||||
}
|
||||
.m3u8_urls, .mp4_urls{
|
||||
.box{
|
||||
span{
|
||||
border-color: var(--d-c-5);
|
||||
&:hover{
|
||||
color: var(--d-fc-2);
|
||||
background-color: var(--d-c-1);
|
||||
border-color: var(--d-c-8);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.film{
|
||||
.top{
|
||||
.search{
|
||||
background-color: var(--d-bgc-1);
|
||||
box-shadow: var(--d-bsc);
|
||||
&:hover{
|
||||
box-shadow: var(--d-bsc-hover);
|
||||
}
|
||||
svg{
|
||||
stroke: var(--d-c-0);
|
||||
stroke-width: 1;
|
||||
fill: none;
|
||||
}
|
||||
.search-box{
|
||||
background-color: var(--d-bgc-1);
|
||||
}
|
||||
&.active{
|
||||
box-shadow: var(--d-bsc-hover);
|
||||
svg{
|
||||
stroke-width: 1.5;
|
||||
fill: var(--d-c-2);
|
||||
}
|
||||
}
|
||||
input{
|
||||
color: var(--d-fc-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
.middle{
|
||||
background-color: var(--d-bgc-1);
|
||||
box-shadow: var(--d-bsc);
|
||||
}
|
||||
}
|
||||
.play{
|
||||
background-color: var(--d-bgc-1);
|
||||
box-shadow: var(--d-bsc);
|
||||
.title{
|
||||
color: var(--d-fc-1);
|
||||
}
|
||||
.box{
|
||||
.more{
|
||||
span{
|
||||
svg{
|
||||
stroke: var(--d-c-5);
|
||||
stroke-width: 1;
|
||||
fill: none;
|
||||
}
|
||||
&:hover{
|
||||
svg{
|
||||
stroke: var(--d-c-8);
|
||||
stroke-width: 1.5;
|
||||
fill: var(--d-c-2);
|
||||
}
|
||||
}
|
||||
&.active{
|
||||
svg{
|
||||
stroke: var(--d-c-9);
|
||||
stroke-width: 2;
|
||||
fill: var(--d-c-3);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.list{
|
||||
border: 1px solid var(--d-c-3);
|
||||
background-color: var(--d-bgc-2);
|
||||
.list-top{
|
||||
color: var(--d-fc-2);
|
||||
.list-top-close{
|
||||
svg{
|
||||
stroke: var(--d-c-5);
|
||||
stroke-width: 1;
|
||||
fill: none;
|
||||
&:hover{
|
||||
stroke: var(--d-c-8);
|
||||
stroke-width: 1.5;
|
||||
fill: var(--d-c-2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.list-body{
|
||||
.list-item{
|
||||
li{
|
||||
color: var(--d-fc-1);
|
||||
&.active{
|
||||
background-color: var(--d-c-2);
|
||||
color: var(--d-fc-3);
|
||||
}
|
||||
}
|
||||
}
|
||||
.list-history{
|
||||
li{
|
||||
.title{
|
||||
color: var(--d-fc-1);
|
||||
}
|
||||
&.active{
|
||||
background-color: var(--d-c-2);
|
||||
.title{
|
||||
color: var(--d-fc-3);
|
||||
}
|
||||
}
|
||||
&:hover{
|
||||
background-color: var(--d-c-3);
|
||||
.detail-delete{
|
||||
display: inline-block;
|
||||
color: var(--d-fc-2);
|
||||
}
|
||||
}
|
||||
.detail-delete{
|
||||
&:hover{
|
||||
background-color: var(--d-c-2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.play-mask{
|
||||
background-color: var(--d-bgc-1);
|
||||
color: var(--d-fc-1);
|
||||
}
|
||||
}
|
||||
.star{
|
||||
background-color: var(--d-bgc-1);
|
||||
box-shadow: var(--d-bsc);
|
||||
}
|
||||
.setting{
|
||||
background-color: var(--d-bgc-1);
|
||||
box-shadow: var(--d-bsc);
|
||||
.info{
|
||||
a{
|
||||
color: var(--d-fc-1);
|
||||
&:hover{
|
||||
color: var(--d-fc-2);
|
||||
}
|
||||
}
|
||||
}
|
||||
.theme{
|
||||
.title{
|
||||
color: var(--d-fc-1);
|
||||
}
|
||||
.theme-item{
|
||||
box-shadow: var(--d-bsc);
|
||||
&:hover{
|
||||
box-shadow: var(--d-bsc-hover);
|
||||
.theme-name{
|
||||
color: var(--d-fc-2)
|
||||
}
|
||||
}
|
||||
.theme-name{
|
||||
color: var(--d-fc-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
.qrcode{
|
||||
.title{
|
||||
color: var(--d-fc-1);
|
||||
}
|
||||
.qrcode-item{
|
||||
box-shadow: var(--d-bsc);
|
||||
}
|
||||
}
|
||||
}
|
||||
.share{
|
||||
background-color: var(--d-bgc-1);
|
||||
color: var(--d-fc-1);
|
||||
border: 1px solid var(--d-c-8);
|
||||
.right{
|
||||
color: var(--d-fc-1);
|
||||
.tops{
|
||||
color: var(--d-fc-2);
|
||||
}
|
||||
}
|
||||
.share-mask{
|
||||
background-color: var(--d-bgc-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
349
src/assets/scss/theme/green.scss
Normal file
@@ -0,0 +1,349 @@
|
||||
.theme-green{
|
||||
background-color: var(--g-bgc-1);
|
||||
.xgplayer-skin-default video{
|
||||
background-color: var(--g-bgc-2);
|
||||
}
|
||||
.el-pagination{
|
||||
background-color: var(--g-bgc-1);
|
||||
color: var(--g-fc-1);
|
||||
.el-pagination__total, .el-pagination__jump, .el-input__inner{
|
||||
color: var(--g-fc-1);
|
||||
background-color: var(--g-bgc-1);
|
||||
}
|
||||
.el-input__inner{
|
||||
border-color: var(--g-c-3);
|
||||
}
|
||||
.el-pager{
|
||||
.number{
|
||||
background-color: var(--g-bgc-1);
|
||||
}
|
||||
.number:hover{
|
||||
color: var(--g-c-8);
|
||||
}
|
||||
.active{
|
||||
color: var(--g-c-9);
|
||||
}
|
||||
}
|
||||
.more, .btn-next, .btn-prev{
|
||||
background-color: var(--g-bgc-1);
|
||||
&:hover{
|
||||
color: var(--g-c-8);
|
||||
}
|
||||
}
|
||||
}
|
||||
.zy-select{
|
||||
color: var(--g-fc-1);
|
||||
background-color: var(--g-bgc-1);
|
||||
box-shadow: var(--g-bsc);
|
||||
&:hover{
|
||||
box-shadow: var(--g-bsc-hover);
|
||||
}
|
||||
.vs-options{
|
||||
background-color: var(--g-bgc-1);
|
||||
box-shadow: var(--g-bsc);
|
||||
ul{
|
||||
li{
|
||||
&:hover{
|
||||
background-color: var(--g-c-1);
|
||||
}
|
||||
&.active{
|
||||
background-color: var(--g-c-3);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.zy-table{
|
||||
color: var(--g-fc-2);
|
||||
.tHead{
|
||||
background-color: var(--g-bgc-1);
|
||||
border-bottom-color: var(--g-c-3);
|
||||
}
|
||||
.tBody{
|
||||
border-bottom-color: var(--g-c-3);
|
||||
ul{
|
||||
li{
|
||||
border-bottom-color: var(--g-c-2);
|
||||
&:hover{
|
||||
animation: d-tableHoverAni 0.2s ease both;
|
||||
@keyframes d-tableHoverAni {
|
||||
to{
|
||||
box-shadow: var(--g-bsc-hover);
|
||||
}
|
||||
}
|
||||
}
|
||||
span{
|
||||
&.btn:hover{
|
||||
color: var(--g-fc-3)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.tFooter{
|
||||
.tFooter-span{
|
||||
color: var(--g-fc-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
.zy-scroll{
|
||||
&:hover{
|
||||
&::-webkit-scrollbar-thumb {
|
||||
box-shadow: var(--g-bsc-scroll);
|
||||
background: var(--g-c-3);
|
||||
}
|
||||
&::-webkit-scrollbar-track {
|
||||
box-shadow: var(--g-bsc-scroll);
|
||||
background: var(--bgc);
|
||||
}
|
||||
}
|
||||
}
|
||||
.zy-loading{
|
||||
.loader{
|
||||
color: var(--g-c-3);
|
||||
}
|
||||
}
|
||||
.zy-body{
|
||||
background-color: var(--g-bgc-2);
|
||||
}
|
||||
.aside{
|
||||
.zy-svg{
|
||||
svg{
|
||||
stroke: var(--g-c-0);
|
||||
}
|
||||
&:hover{
|
||||
background-color: var(--g-c-2);
|
||||
}
|
||||
&.active{
|
||||
svg{
|
||||
stroke: var(--g-c-0);
|
||||
stroke-width: 2;
|
||||
fill: var(--g-c-2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.frame{
|
||||
span{
|
||||
&.min{
|
||||
background-color: #ffbe2a;
|
||||
}
|
||||
&.close{
|
||||
background-color: #ff5f56;
|
||||
}
|
||||
}
|
||||
}
|
||||
.detail{
|
||||
color: var(--g-fc-1);
|
||||
background-color:var(--g-bgc-1);
|
||||
box-shadow: var(--g-bsc-2);
|
||||
.detail-content{
|
||||
.detail-close{
|
||||
svg{
|
||||
stroke-width: 1;
|
||||
stroke: var(--g-c-8);
|
||||
&:hover{
|
||||
stroke-width: 2px;
|
||||
stroke: var(--g-c-9);
|
||||
}
|
||||
}
|
||||
}
|
||||
.detail-body{
|
||||
.info, .desc, .m3u8_urls, .mp4_urls{
|
||||
border-color: var(--g-c-2);
|
||||
}
|
||||
.m3u8_urls, .mp4_urls{
|
||||
.box{
|
||||
span{
|
||||
border-color: var(--g-c-5);
|
||||
&:hover{
|
||||
color: var(--g-fc-2);
|
||||
background-color: var(--g-c-1);
|
||||
border-color: var(--g-c-8);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.film{
|
||||
.top{
|
||||
.search{
|
||||
background-color: var(--g-bgc-1);
|
||||
box-shadow: var(--g-bsc);
|
||||
&:hover{
|
||||
box-shadow: var(--g-bsc-hover);
|
||||
}
|
||||
svg{
|
||||
stroke: var(--g-c-0);
|
||||
stroke-width: 1;
|
||||
fill: none;
|
||||
}
|
||||
.search-box{
|
||||
background-color: var(--g-bgc-1);
|
||||
}
|
||||
&.active{
|
||||
box-shadow: var(--g-bsc-hover);
|
||||
svg{
|
||||
stroke-width: 1.5;
|
||||
fill: var(--g-c-2);
|
||||
}
|
||||
}
|
||||
input{
|
||||
color: var(--g-fc-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
.middle{
|
||||
background-color: var(--g-bgc-1);
|
||||
box-shadow: var(--g-bsc);
|
||||
}
|
||||
}
|
||||
.play{
|
||||
background-color: var(--g-bgc-1);
|
||||
box-shadow: var(--g-bsc);
|
||||
.title{
|
||||
color: var(--g-fc-1);
|
||||
}
|
||||
.box{
|
||||
.more{
|
||||
span{
|
||||
svg{
|
||||
stroke: var(--g-c-5);
|
||||
stroke-width: 1;
|
||||
fill: none;
|
||||
}
|
||||
&:hover{
|
||||
svg{
|
||||
stroke: var(--g-c-8);
|
||||
stroke-width: 1.5;
|
||||
fill: var(--g-c-2);
|
||||
}
|
||||
}
|
||||
&.active{
|
||||
svg{
|
||||
stroke: var(--g-c-9);
|
||||
stroke-width: 2;
|
||||
fill: var(--g-c-3);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.list{
|
||||
border: 1px solid var(--g-c-3);
|
||||
background-color: var(--g-bgc-2);
|
||||
.list-top{
|
||||
color: var(--g-fc-2);
|
||||
.list-top-close{
|
||||
svg{
|
||||
stroke: var(--g-c-5);
|
||||
stroke-width: 1;
|
||||
fill: none;
|
||||
&:hover{
|
||||
stroke: var(--g-c-8);
|
||||
stroke-width: 1.5;
|
||||
fill: var(--g-c-2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.list-body{
|
||||
.list-item{
|
||||
li{
|
||||
color: var(--g-fc-1);
|
||||
&.active{
|
||||
background-color: var(--g-c-2);
|
||||
color: var(--g-fc-3);
|
||||
}
|
||||
}
|
||||
}
|
||||
.list-history{
|
||||
li{
|
||||
.title{
|
||||
color: var(--g-fc-1);
|
||||
}
|
||||
&.active{
|
||||
background-color: var(--g-c-2);
|
||||
.title{
|
||||
color: var(--g-fc-3);
|
||||
}
|
||||
}
|
||||
&:hover{
|
||||
background-color: var(--g-c-3);
|
||||
.detail-delete{
|
||||
display: inline-block;
|
||||
color: var(--g-fc-2);
|
||||
}
|
||||
}
|
||||
.detail-delete{
|
||||
&:hover{
|
||||
background-color: var(--g-c-2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.play-mask{
|
||||
background-color: var(--g-bgc-1);
|
||||
color: var(--g-fc-1);
|
||||
}
|
||||
}
|
||||
.star{
|
||||
background-color: var(--g-bgc-1);
|
||||
box-shadow: var(--g-bsc);
|
||||
}
|
||||
.setting{
|
||||
background-color: var(--g-bgc-1);
|
||||
box-shadow: var(--g-bsc);
|
||||
.info{
|
||||
a{
|
||||
color: var(--g-fc-1);
|
||||
&:hover{
|
||||
color: var(--g-fc-2);
|
||||
}
|
||||
}
|
||||
}
|
||||
.theme{
|
||||
.title{
|
||||
color: var(--g-fc-1);
|
||||
}
|
||||
.theme-item{
|
||||
box-shadow: var(--g-bsc);
|
||||
&:hover{
|
||||
box-shadow: var(--g-bsc-hover);
|
||||
.theme-name{
|
||||
color: var(--g-fc-2)
|
||||
}
|
||||
}
|
||||
.theme-name{
|
||||
color: var(--g-fc-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
.qrcode{
|
||||
.title{
|
||||
color: var(--g-fc-1);
|
||||
}
|
||||
.qrcode-item{
|
||||
box-shadow: var(--g-bsc);
|
||||
}
|
||||
}
|
||||
}
|
||||
.share{
|
||||
background-color: var(--g-bgc-1);
|
||||
color: var(--g-fc-1);
|
||||
border: 1px solid var(--g-c-8);
|
||||
.right{
|
||||
color: var(--g-fc-1);
|
||||
.tops{
|
||||
color: var(--g-fc-2);
|
||||
}
|
||||
}
|
||||
.share-mask{
|
||||
background-color: var(--g-bgc-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
340
src/assets/scss/theme/light.scss
Normal file
@@ -0,0 +1,340 @@
|
||||
.theme-light{
|
||||
background-color: var(--l-bgc-1);
|
||||
.xgplayer-skin-default video{
|
||||
background-color: var(--l-bgc-2);
|
||||
}
|
||||
.el-pagination{
|
||||
color: var(--l-fc-1);
|
||||
.el-pagination__total, .el-pagination__jump, .el-input__inner{
|
||||
color: var(--l-fc-1);
|
||||
}
|
||||
.el-pager{
|
||||
.number:hover{
|
||||
color: var(--l-c-8);
|
||||
}
|
||||
.active{
|
||||
color: var(--l-c-9);
|
||||
}
|
||||
}
|
||||
.more, .btn-next, .btn-prev{
|
||||
&:hover{
|
||||
color: var(--l-c-8);
|
||||
}
|
||||
}
|
||||
}
|
||||
.zy-select{
|
||||
color: var(--l-fc-1);
|
||||
background-color: var(--l-bgc-1);
|
||||
box-shadow: var(--l-bsc);
|
||||
&:hover{
|
||||
box-shadow: var(--l-bsc-hover);
|
||||
}
|
||||
.vs-options{
|
||||
background-color: var(--l-bgc-1);
|
||||
box-shadow: var(--l-bsc);
|
||||
ul{
|
||||
li{
|
||||
&:hover{
|
||||
background-color: var(--l-c-1);
|
||||
}
|
||||
&.active{
|
||||
background-color: var(--l-c-3);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.zy-table{
|
||||
color: var(--l-fc-2);
|
||||
.tHead{
|
||||
background-color: var(--l-bgc-1);
|
||||
border-bottom-color: var(--l-c-3);
|
||||
}
|
||||
.tBody{
|
||||
border-bottom-color: var(--l-c-3);
|
||||
ul{
|
||||
li{
|
||||
border-bottom-color: var(--l-c-2);
|
||||
&:hover{
|
||||
animation: l-tableHoverAni 0.2s ease both;
|
||||
@keyframes l-tableHoverAni {
|
||||
to{
|
||||
box-shadow: var(--l-bsc-hover);
|
||||
}
|
||||
}
|
||||
}
|
||||
span{
|
||||
&.btn:hover{
|
||||
color: var(--l-fc-3)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.tFooter{
|
||||
.tFooter-span{
|
||||
color: var(--l-fc-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
.zy-scroll{
|
||||
&:hover{
|
||||
&::-webkit-scrollbar-thumb {
|
||||
box-shadow: var(--l-bsc-scroll);
|
||||
background: var(--l-c-3);
|
||||
}
|
||||
&::-webkit-scrollbar-track {
|
||||
box-shadow: var(--l-bsc-scroll);
|
||||
background: var(--bgc);
|
||||
}
|
||||
}
|
||||
}
|
||||
.zy-loading{
|
||||
.loader{
|
||||
color: var(--l-c-3);
|
||||
}
|
||||
}
|
||||
.zy-body{
|
||||
background-color: var(--l-bgc-2);
|
||||
}
|
||||
.aside{
|
||||
.zy-svg{
|
||||
svg{
|
||||
stroke: var(--l-c-0);
|
||||
}
|
||||
&:hover{
|
||||
background-color: var(--l-c-2);
|
||||
}
|
||||
&.active{
|
||||
svg{
|
||||
stroke: var(--l-c-0);
|
||||
stroke-width: 2;
|
||||
fill: var(--l-c-2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.frame{
|
||||
span{
|
||||
&.min{
|
||||
background-color: #ffbe2a;
|
||||
}
|
||||
&.close{
|
||||
background-color: #ff5f56;
|
||||
}
|
||||
}
|
||||
}
|
||||
.detail{
|
||||
color: var(--l-fc-1);
|
||||
background-color:var(--l-bgc-1);
|
||||
box-shadow: var(--l-bsc-2);
|
||||
.detail-content{
|
||||
.detail-close{
|
||||
svg{
|
||||
stroke-width: 1;
|
||||
stroke: var(--l-c-8);
|
||||
&:hover{
|
||||
stroke-width: 2px;
|
||||
stroke: var(--l-c-9);
|
||||
}
|
||||
}
|
||||
}
|
||||
.detail-body{
|
||||
.info, .desc, .m3u8_urls, .mp4_urls{
|
||||
border-color: var(--l-c-2);
|
||||
}
|
||||
.m3u8_urls, .mp4_urls{
|
||||
.box{
|
||||
span{
|
||||
border-color: var(--l-c-5);
|
||||
&:hover{
|
||||
color: var(--l-fc-2);
|
||||
background-color: var(--l-c-1);
|
||||
border-color: var(--l-c-8);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.film{
|
||||
.top{
|
||||
.search{
|
||||
background-color: var(--l-bgc-1);
|
||||
box-shadow: var(--l-bsc);
|
||||
&:hover{
|
||||
box-shadow: var(--l-bsc-hover);
|
||||
}
|
||||
svg{
|
||||
stroke: #823aa099;
|
||||
stroke-width: 1;
|
||||
fill: none;
|
||||
}
|
||||
.search-box{
|
||||
background-color: none;
|
||||
}
|
||||
&.active{
|
||||
box-shadow: var(--l-bsc-hover);
|
||||
svg{
|
||||
stroke-width: 1.5;
|
||||
fill: var(--l-c-2);
|
||||
}
|
||||
}
|
||||
input{
|
||||
color: var(--l-fc-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
.middle{
|
||||
background-color: var(--l-bgc-1);
|
||||
box-shadow: var(--l-bsc);
|
||||
}
|
||||
}
|
||||
.play{
|
||||
background-color: var(--l-bgc-1);
|
||||
box-shadow: var(--l-bsc);
|
||||
.title{
|
||||
color: var(--d-fc-1);
|
||||
}
|
||||
.box{
|
||||
.more{
|
||||
span{
|
||||
svg{
|
||||
stroke: var(--l-c-5);
|
||||
stroke-width: 1;
|
||||
fill: none;
|
||||
}
|
||||
&:hover{
|
||||
svg{
|
||||
stroke: var(--l-c-8);
|
||||
stroke-width: 1.5;
|
||||
fill: var(--l-c-2);
|
||||
}
|
||||
}
|
||||
&.active{
|
||||
svg{
|
||||
stroke: var(--l-c-9);
|
||||
stroke-width: 2;
|
||||
fill: var(--l-c-3);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.list{
|
||||
border: 1px solid var(--l-c-3);
|
||||
background-color: var(--l-bgc-2);
|
||||
.list-top{
|
||||
color: var(--l-fc-2);
|
||||
.list-top-close{
|
||||
svg{
|
||||
stroke: var(--l-c-5);
|
||||
stroke-width: 1;
|
||||
fill: none;
|
||||
&:hover{
|
||||
stroke: var(--l-c-8);
|
||||
stroke-width: 1.5;
|
||||
fill: var(--l-c-2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.list-body{
|
||||
.list-item{
|
||||
li{
|
||||
color: var(--l-fc-1);
|
||||
&.active{
|
||||
background-color: var(--l-c-2);
|
||||
color: var(--l-fc-3);
|
||||
}
|
||||
}
|
||||
}
|
||||
.list-history{
|
||||
li{
|
||||
.title{
|
||||
color: var(--l-fc-1);
|
||||
}
|
||||
&.active{
|
||||
background-color: var(--l-c-2);
|
||||
.title{
|
||||
color: var(--l-fc-3);
|
||||
}
|
||||
}
|
||||
&:hover{
|
||||
background-color: var(--l-c-3);
|
||||
.detail-delete{
|
||||
display: inline-block;
|
||||
color: var(--l-fc-2);
|
||||
}
|
||||
}
|
||||
.detail-delete{
|
||||
&:hover{
|
||||
background-color: var(--l-c-2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.play-mask{
|
||||
background-color: var(--l-bgc-1);
|
||||
color: var(--l-fc-1);
|
||||
}
|
||||
}
|
||||
.star{
|
||||
background-color: var(--l-bgc-1);
|
||||
box-shadow: var(--l-bsc);
|
||||
}
|
||||
.setting{
|
||||
background-color: var(--l-bgc-1);
|
||||
box-shadow: var(--l-bsc);
|
||||
.info{
|
||||
a{
|
||||
color: var(--l-fc-1);
|
||||
&:hover{
|
||||
color: var(--l-fc-2);
|
||||
}
|
||||
}
|
||||
}
|
||||
.theme{
|
||||
.title{
|
||||
color: var(--l-fc-1);
|
||||
}
|
||||
.theme-item{
|
||||
box-shadow: var(--l-bsc);
|
||||
&:hover{
|
||||
box-shadow: var(--l-bsc-hover);
|
||||
.theme-name{
|
||||
color: var(--l-fc-2)
|
||||
}
|
||||
}
|
||||
.theme-name{
|
||||
color: var(--l-fc-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
.qrcode{
|
||||
.title{
|
||||
color: var(--l-fc-1);
|
||||
}
|
||||
.qrcode-item{
|
||||
box-shadow: var(--l-bsc);
|
||||
}
|
||||
}
|
||||
}
|
||||
.share{
|
||||
background-color: var(--l-bgc-1);
|
||||
color: var(--l-fc-1);
|
||||
border: 1px solid var(--l-c-8);
|
||||
.right{
|
||||
color: var(--l-fc-1);
|
||||
.tops{
|
||||
color: var(--l-fc-2);
|
||||
}
|
||||
}
|
||||
.share-mask{
|
||||
background-color: var(--l-bgc-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,109 +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-button--text{
|
||||
border: none;
|
||||
}
|
||||
.el-tabs__item, .el-tabs__nav-wrap::after{
|
||||
color: var(--d-c);
|
||||
background-color: var(--d-bgc);
|
||||
border-color: var(--d-dbc);
|
||||
}
|
||||
.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(--d-c);
|
||||
background-color: var(--d-bgc);
|
||||
border-color: var(--d-dbc);
|
||||
}
|
||||
.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-input__inner,
|
||||
.el-input-group__append, .el-input-group__prepend{
|
||||
background-color: var(--d-bgc);
|
||||
border-color: var(--d-dbc);
|
||||
}
|
||||
.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;
|
||||
}
|
||||
.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{
|
||||
.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);
|
||||
}
|
||||
}
|
||||
}
|
||||
.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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,19 +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;
|
||||
}
|
||||
@@ -1,74 +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);
|
||||
}
|
||||
}
|
||||
}
|
||||
.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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
137
src/background.js
Normal file
@@ -0,0 +1,137 @@
|
||||
'use strict'
|
||||
|
||||
import { app, ipcMain, protocol, 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
|
||||
let mini
|
||||
|
||||
// Scheme must be registered before the app is ready
|
||||
protocol.registerSchemesAsPrivileged([{ scheme: 'app', privileges: { secure: true, standard: true } }])
|
||||
|
||||
function createWindow () {
|
||||
win = new BrowserWindow({
|
||||
width: 1080,
|
||||
height: 720,
|
||||
frame: false,
|
||||
resizable: false,
|
||||
transparent: true,
|
||||
webPreferences: {
|
||||
webSecurity: false,
|
||||
nodeIntegration: process.env.ELECTRON_NODE_INTEGRATION
|
||||
},
|
||||
// eslint-disable-next-line
|
||||
icon: path.join(__static, 'icon.png')
|
||||
})
|
||||
|
||||
if (process.env.WEBPACK_DEV_SERVER_URL) {
|
||||
win.loadURL(process.env.WEBPACK_DEV_SERVER_URL)
|
||||
if (!process.env.IS_TEST) win.webContents.openDevTools()
|
||||
} else {
|
||||
win.loadURL('app://./index.html')
|
||||
autoUpdater.checkForUpdatesAndNotify()
|
||||
}
|
||||
|
||||
win.on('closed', () => {
|
||||
win = null
|
||||
})
|
||||
}
|
||||
|
||||
function createMini () {
|
||||
mini = new BrowserWindow({
|
||||
width: 550,
|
||||
minWidth: 260,
|
||||
height: 340,
|
||||
minHeight: 180,
|
||||
frame: false,
|
||||
resizable: true,
|
||||
transparent: true,
|
||||
alwaysOnTop: true,
|
||||
webPreferences: {
|
||||
webSecurity: false,
|
||||
nodeIntegration: process.env.ELECTRON_NODE_INTEGRATION
|
||||
},
|
||||
// eslint-disable-next-line
|
||||
icon: path.join(__static, 'icon.png')
|
||||
})
|
||||
|
||||
if (process.env.WEBPACK_DEV_SERVER_URL) {
|
||||
mini.loadURL(process.env.WEBPACK_DEV_SERVER_URL + 'mini')
|
||||
if (!process.env.IS_TEST) mini.webContents.openDevTools()
|
||||
} else {
|
||||
mini.loadURL('app://./mini.html')
|
||||
}
|
||||
|
||||
mini.on('closed', () => {
|
||||
mini = null
|
||||
})
|
||||
}
|
||||
|
||||
app.allowRendererProcessReuse = true
|
||||
|
||||
app.on('window-all-closed', () => {
|
||||
if (process.platform !== 'darwin') {
|
||||
app.quit()
|
||||
}
|
||||
})
|
||||
|
||||
app.on('activate', () => {
|
||||
if (win === null) {
|
||||
createWindow()
|
||||
}
|
||||
if (mini === null) {
|
||||
createMini()
|
||||
}
|
||||
})
|
||||
|
||||
ipcMain.on('min', () => {
|
||||
win.minimize()
|
||||
})
|
||||
ipcMain.on('close', () => {
|
||||
win.close()
|
||||
})
|
||||
|
||||
ipcMain.on('mini', () => {
|
||||
createMini()
|
||||
win.close()
|
||||
})
|
||||
ipcMain.on('miniMin', () => {
|
||||
mini.minimize()
|
||||
})
|
||||
ipcMain.on('miniClose', () => {
|
||||
mini.close()
|
||||
createWindow()
|
||||
})
|
||||
ipcMain.on('miniOpacity', (e, arg) => {
|
||||
mini.setOpacity(arg)
|
||||
})
|
||||
|
||||
app.on('ready', async () => {
|
||||
if (!process.env.WEBPACK_DEV_SERVER_URL) {
|
||||
createProtocol('app')
|
||||
}
|
||||
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()
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -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()
|
||||
})
|
||||
}
|
||||
}
|
||||
77
src/components/Aside.vue
Normal file
@@ -0,0 +1,77 @@
|
||||
<template>
|
||||
<div class="aside">
|
||||
<span :class="[view === 'Film' ? 'active ': ''] + 'zy-svg'" @click="changeView('Film')">
|
||||
<svg role="img" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" aria-labelledby="apertureIconTitle">
|
||||
<title id="apertureIconTitle">{{$t('view')}}</title>
|
||||
<path d="M12 22C17.5228 22 22 17.5228 22 12C22 6.47715 17.5228 2 12 2C6.47715 2 2 6.47715 2 12C2 17.5228 6.47715 22 12 22Z"></path>
|
||||
<g stroke-linecap="round">
|
||||
<path d="M3 16H14.3164"></path>
|
||||
<path d="M4.03589 6.20575L9.68257 15.9861"></path>
|
||||
<path d="M13.0359 2.20575L7.37891 12.004"></path>
|
||||
<path d="M10.9641 21.7942L16.6146 12.0074"></path>
|
||||
<path d="M19.9641 17.7942L14.3086 7.99866"></path>
|
||||
<path d="M21 7.98721H9.71844"></path>
|
||||
</g>
|
||||
</svg>
|
||||
</span>
|
||||
<span :class="[view === 'Play' ? 'active ': ''] + 'zy-svg'" @click="changeView('Play')">
|
||||
<svg role="img" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" aria-labelledby="playIconTitle">
|
||||
<title id="playIconTitle">{{$t('play')}}</title>
|
||||
<path d="M20 12L5 21V3z"></path>
|
||||
</svg>
|
||||
</span>
|
||||
<span :class="[view === 'Star' ? 'active ': ''] + 'zy-svg'" @click="changeView('Star')">
|
||||
<svg role="img" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" aria-labelledby="favouriteIconTitle">
|
||||
<title id="favouriteIconTitle">{{$t('star')}}</title>
|
||||
<path d="M12,21 L10.55,19.7051771 C5.4,15.1242507 2,12.1029973 2,8.39509537 C2,5.37384196 4.42,3 7.5,3 C9.24,3 10.91,3.79455041 12,5.05013624 C13.09,3.79455041 14.76,3 16.5,3 C19.58,3 22,5.37384196 22,8.39509537 C22,12.1029973 18.6,15.1242507 13.45,19.7149864 L12,21 Z"></path>
|
||||
</svg>
|
||||
</span>
|
||||
<span :class="[view === 'Setting' ? 'active ': ''] + 'zy-svg'" @click="changeView('Setting')">
|
||||
<svg role="img" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" aria-labelledby="settingsIconTitle">
|
||||
<title id="settingsIconTitle">{{$t('setting')}}</title>
|
||||
<path d="M5.03506429,12.7050339 C5.01187484,12.4731696 5,12.2379716 5,12 C5,11.7620284 5.01187484,11.5268304 5.03506429,11.2949661 L3.20577137,9.23205081 L5.20577137,5.76794919 L7.9069713,6.32070904 C8.28729123,6.0461342 8.69629298,5.80882212 9.12862533,5.61412402 L10,3 L14,3 L14.8713747,5.61412402 C15.303707,5.80882212 15.7127088,6.0461342 16.0930287,6.32070904 L18.7942286,5.76794919 L20.7942286,9.23205081 L18.9649357,11.2949661 C18.9881252,11.5268304 19,11.7620284 19,12 C19,12.2379716 18.9881252,12.4731696 18.9649357,12.7050339 L20.7942286,14.7679492 L18.7942286,18.2320508 L16.0930287,17.679291 C15.7127088,17.9538658 15.303707,18.1911779 14.8713747,18.385876 L14,21 L10,21 L9.12862533,18.385876 C8.69629298,18.1911779 8.28729123,17.9538658 7.9069713,17.679291 L5.20577137,18.2320508 L3.20577137,14.7679492 L5.03506429,12.7050339 Z"></path>
|
||||
<circle cx="12" cy="12" r="1"></circle>
|
||||
</svg>
|
||||
</span>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import { mapMutations } from 'vuex'
|
||||
export default {
|
||||
name: 'Aside',
|
||||
computed: {
|
||||
view: {
|
||||
get () {
|
||||
return this.$store.getters.getView
|
||||
},
|
||||
set (val) {
|
||||
this.SET_VIEW(val)
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
...mapMutations(['SET_VIEW']),
|
||||
changeView (e) {
|
||||
this.view = e
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.aside{
|
||||
width: 60px;
|
||||
height: 100%;
|
||||
user-select: none;
|
||||
-webkit-app-region: drag;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
span{
|
||||
-webkit-app-region: no-drag;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
345
src/components/Detail.vue
Normal file
@@ -0,0 +1,345 @@
|
||||
<template>
|
||||
<div class="detail">
|
||||
<div class="detail-content">
|
||||
<div class="detail-header">
|
||||
<span class="detail-title">{{$t('detail')}}</span>
|
||||
<span class="detail-close zy-svg" @click="closeDetail">
|
||||
<svg role="img" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" aria-labelledby="closeIconTitle">
|
||||
<title id="closeIconTitle">{{$t('close')}}</title>
|
||||
<path d="M6.34314575 6.34314575L17.6568542 17.6568542M6.34314575 17.6568542L17.6568542 6.34314575"></path>
|
||||
</svg>
|
||||
</span>
|
||||
</div>
|
||||
<div class="detail-body zy-scroll" v-show="!loading" :style="{overflowY:scroll? 'auto' : 'hidden',paddingRight: scroll ? '0': '5px' }" @mouseenter="scroll = true" @mouseleave="scroll = false">
|
||||
<div class="info" v-html="vDetail.info"></div>
|
||||
<div class="desc" v-html="vDetail.desc" v-if="show.desc"></div>
|
||||
<div class="m3u8_urls">
|
||||
<div class="title">{{$t('play')}}:</div>
|
||||
<div class="box">
|
||||
<span v-for="(i, j) in vDetail.m3u8_urls" :key="j" @click="playEvent(j)">{{i | ftName}}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mp4_urls" v-if="show.download">
|
||||
<div class="title">{{$t('download')}}:</div>
|
||||
<div class="box">
|
||||
<span v-for="(i, j) in vDetail.mp4_urls" :key="j" @click="download(i)">{{i | ftName}}</span>
|
||||
<span @click="allDownload" v-show="vDetail.mp4_urls.length > 1">{{$t('all_download')}}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="detail-mask zy-loading" v-show="loading">
|
||||
<div class="loader"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import { mapMutations } from 'vuex'
|
||||
import tools from '../lib/site/tools'
|
||||
const { clipboard } = require('electron')
|
||||
export default {
|
||||
name: 'detail',
|
||||
data () {
|
||||
return {
|
||||
scroll: false,
|
||||
loading: true,
|
||||
vDetail: {},
|
||||
show: {
|
||||
desc: false,
|
||||
download: false
|
||||
}
|
||||
}
|
||||
},
|
||||
filters: {
|
||||
ftName (e) {
|
||||
const name = e.split('$')[0]
|
||||
return name
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
view: {
|
||||
get () {
|
||||
return this.$store.getters.getView
|
||||
},
|
||||
set (val) {
|
||||
this.SET_VIEW(val)
|
||||
}
|
||||
},
|
||||
video: {
|
||||
get () {
|
||||
return this.$store.getters.getVideo
|
||||
},
|
||||
set (val) {
|
||||
this.SET_VIDEO(val)
|
||||
}
|
||||
},
|
||||
detail: {
|
||||
get () {
|
||||
return this.$store.getters.getDetail
|
||||
},
|
||||
set (val) {
|
||||
this.SET_DETAIL(val)
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
...mapMutations(['SET_VIEW', 'SET_VIDEO', 'SET_DETAIL']),
|
||||
closeDetail () {
|
||||
this.detail.show = false
|
||||
},
|
||||
getDetail () {
|
||||
tools.detail_get(this.detail.v.site, this.detail.v.detail).then(res => {
|
||||
this.vDetail = res
|
||||
if (res.desc.length > 0) {
|
||||
this.show.desc = true
|
||||
}
|
||||
if (res.mp4_urls.length > 0) {
|
||||
this.show.download = true
|
||||
}
|
||||
this.$nextTick(() => {
|
||||
this.loading = false
|
||||
})
|
||||
})
|
||||
},
|
||||
playEvent (n) {
|
||||
const v = { ...this.detail.v }
|
||||
v.index = n
|
||||
this.video = v
|
||||
this.detail.show = false
|
||||
this.view = 'Play'
|
||||
},
|
||||
download (e) {
|
||||
const name = e.split('$')[0]
|
||||
const txt = encodeURI(e.split('$')[1])
|
||||
clipboard.writeText(txt)
|
||||
this.$m.success(name + this.$t('copy_success'))
|
||||
},
|
||||
allDownload () {
|
||||
const urls = [...this.vDetail.mp4_urls]
|
||||
let txt = ''
|
||||
for (const i of urls) {
|
||||
const url = encodeURI(i.split('$')[1])
|
||||
txt += (url + '\n')
|
||||
}
|
||||
clipboard.writeText(txt)
|
||||
this.$m.success(this.$t('copy_success'))
|
||||
}
|
||||
},
|
||||
created () {
|
||||
this.getDetail()
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss">
|
||||
.detail{
|
||||
position: absolute;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
height: 680px;
|
||||
z-index: 999;
|
||||
.detail-content{
|
||||
height: 680px;
|
||||
padding: 0 60px;
|
||||
position: relative;
|
||||
.detail-header{
|
||||
width: 100%;
|
||||
height: 40px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 0 -40px;
|
||||
.detail-title{
|
||||
font-size: 16px;
|
||||
}
|
||||
.detail-close{
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
.detail-body{
|
||||
height: 630px;
|
||||
overflow-y: auto;
|
||||
.info{
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
align-items: flex-start;
|
||||
flex-wrap: wrap;
|
||||
width: 955px;
|
||||
padding: 10px;
|
||||
border: 1px solid;
|
||||
border-radius: 2px;
|
||||
margin-bottom: 10px;
|
||||
.vodImg{
|
||||
width: 200px;
|
||||
img{
|
||||
width: 100%;
|
||||
height: auto;
|
||||
}
|
||||
}
|
||||
.vodAd{
|
||||
display: none;
|
||||
}
|
||||
.vodInfo{
|
||||
flex: 1;
|
||||
margin-left: 20px;
|
||||
overflow: hidden;
|
||||
.vodh{
|
||||
margin-bottom: 6px;
|
||||
h2{
|
||||
display: inline-block;
|
||||
margin: 0;
|
||||
}
|
||||
span{
|
||||
font-size: 12px;
|
||||
margin-left: 10px;
|
||||
}
|
||||
label{
|
||||
font-size: 20px;
|
||||
font-weight: bold;
|
||||
margin-left: 20px;
|
||||
}
|
||||
}
|
||||
.cont, .tags{
|
||||
display: none;
|
||||
}
|
||||
ul{
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
a{
|
||||
display: none;
|
||||
pointer-events: none;
|
||||
}
|
||||
li{
|
||||
list-style: none;
|
||||
font-size: 14px;
|
||||
line-height: 18px;
|
||||
height: 18px;
|
||||
overflow: hidden;
|
||||
span{
|
||||
word-wrap: nowrap;
|
||||
}
|
||||
}
|
||||
}
|
||||
.whitetitle{
|
||||
width: 100%;
|
||||
font-size: 22px;
|
||||
font-weight: bold;
|
||||
margin: 4px 0;
|
||||
}
|
||||
.people{
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
align-items: flex-start;
|
||||
flex-wrap: wrap;
|
||||
.left{
|
||||
width: 200px;
|
||||
img{
|
||||
width: 100%;
|
||||
height: auto;
|
||||
}
|
||||
}
|
||||
.right{
|
||||
flex: 1;
|
||||
margin-left: 20px;
|
||||
overflow: hidden;
|
||||
p{
|
||||
font-size: 14px;
|
||||
}
|
||||
a{
|
||||
pointer-events: none;
|
||||
text-decoration: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.desc{
|
||||
border: 1px solid;
|
||||
padding: 10px;
|
||||
width: 955px;
|
||||
margin-bottom: 10px;
|
||||
border-radius: 2px;
|
||||
font-size: 14px;
|
||||
line-height: 20px;
|
||||
}
|
||||
.m3u8_urls, .mp4_urls{
|
||||
border: 1px solid;
|
||||
padding: 10px;
|
||||
width: 955px;
|
||||
margin-bottom: 10px;
|
||||
border-radius: 2px;
|
||||
.title{
|
||||
font-size: 16px;
|
||||
}
|
||||
.box{
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
flex-wrap: wrap;
|
||||
span{
|
||||
font-size: 12px;
|
||||
border: 1px solid;
|
||||
border-radius: 2px;
|
||||
cursor: pointer;
|
||||
margin: 6px 6px 0px 0px;
|
||||
padding: 8px 22px;
|
||||
}
|
||||
&::after {
|
||||
content: '';
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
.mp4_urls{
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
}
|
||||
.detail-mask{
|
||||
width: 980px;
|
||||
height: 600px;
|
||||
position: absolute;
|
||||
top: 50px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
.loader {
|
||||
font-size: 8px;
|
||||
width: 1em;
|
||||
height: 1em;
|
||||
border-radius: 50%;
|
||||
position: relative;
|
||||
text-indent: -9999em;
|
||||
animation: load4 1.3s infinite linear;
|
||||
transform: translateZ(0);
|
||||
}
|
||||
@keyframes load4 {
|
||||
0%,
|
||||
100% {
|
||||
box-shadow: 0 -3em 0 0.2em, 2em -2em 0 0em, 3em 0 0 -1em, 2em 2em 0 -1em, 0 3em 0 -1em, -2em 2em 0 -1em, -3em 0 0 -1em, -2em -2em 0 0;
|
||||
}
|
||||
12.5% {
|
||||
box-shadow: 0 -3em 0 0, 2em -2em 0 0.2em, 3em 0 0 0, 2em 2em 0 -1em, 0 3em 0 -1em, -2em 2em 0 -1em, -3em 0 0 -1em, -2em -2em 0 -1em;
|
||||
}
|
||||
25% {
|
||||
box-shadow: 0 -3em 0 -0.5em, 2em -2em 0 0, 3em 0 0 0.2em, 2em 2em 0 0, 0 3em 0 -1em, -2em 2em 0 -1em, -3em 0 0 -1em, -2em -2em 0 -1em;
|
||||
}
|
||||
37.5% {
|
||||
box-shadow: 0 -3em 0 -1em, 2em -2em 0 -1em, 3em 0em 0 0, 2em 2em 0 0.2em, 0 3em 0 0em, -2em 2em 0 -1em, -3em 0em 0 -1em, -2em -2em 0 -1em;
|
||||
}
|
||||
50% {
|
||||
box-shadow: 0 -3em 0 -1em, 2em -2em 0 -1em, 3em 0 0 -1em, 2em 2em 0 0em, 0 3em 0 0.2em, -2em 2em 0 0, -3em 0em 0 -1em, -2em -2em 0 -1em;
|
||||
}
|
||||
62.5% {
|
||||
box-shadow: 0 -3em 0 -1em, 2em -2em 0 -1em, 3em 0 0 -1em, 2em 2em 0 -1em, 0 3em 0 0, -2em 2em 0 0.2em, -3em 0 0 0, -2em -2em 0 -1em;
|
||||
}
|
||||
75% {
|
||||
box-shadow: 0em -3em 0 -1em, 2em -2em 0 -1em, 3em 0em 0 -1em, 2em 2em 0 -1em, 0 3em 0 -1em, -2em 2em 0 0, -3em 0em 0 0.2em, -2em -2em 0 0;
|
||||
}
|
||||
87.5% {
|
||||
box-shadow: 0em -3em 0 0, 2em -2em 0 -1em, 3em 0 0 -1em, 2em 2em 0 -1em, 0 3em 0 -1em, -2em 2em 0 0, -3em 0em 0 0, -2em -2em 0 0.2em;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
333
src/components/Film.vue
Normal file
@@ -0,0 +1,333 @@
|
||||
<template>
|
||||
<div class="film">
|
||||
<div class="top" v-if="top">
|
||||
<!-- site -->
|
||||
<div class="zy-select" @mouseleave="show.site = false">
|
||||
<div class="vs-placeholder" @click="show.site = true">{{site.name}}</div>
|
||||
<div class="vs-options" v-show="show.site">
|
||||
<ul>
|
||||
<li :class="site === j ? 'active' : ''" v-for="(i, j) in sites" :key="j" @click="siteClick(i)">{{ i.name }}</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<!-- tags -->
|
||||
<div class="zy-select" @mouseleave="show.tags = false" v-if="site.tags.length > 0 && keywords.length <= 0">
|
||||
<div class="vs-placeholder" @click="show.tags = true">{{site.tags[tag].title}}</div>
|
||||
<div class="vs-options" v-show="show.tags">
|
||||
<ul>
|
||||
<li :class="tag === j ? 'active' : ''" v-for="(i, j) in site.tags" :key="j" @click="tagClick(i, j)">{{ i.title }}</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<!-- type -->
|
||||
<div class="zy-select" @mouseleave="show.type = false" v-if="site.tags[tag].children.length > 0 && keywords.length <= 0">
|
||||
<div class="vs-placeholder" @click="show.type = true">{{typeName}}</div>
|
||||
<div class="vs-options" v-show="show.type">
|
||||
<ul>
|
||||
<li :class="type === j ? 'active' : ''" v-for="(i, j) in site.tags[tag].children" :key="j" @click="typeClick(i, j)">{{ i.title }}</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div :class="[inputFocus ? 'active ': ''] + 'search'" @mouseover="inputFocus = true" @mouseleave="inputFocus = false">
|
||||
<div class="search-icon">
|
||||
<span class="zy-svg">
|
||||
<svg role="img" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" aria-labelledby="searchIconTitle">
|
||||
<title id="searchIconTitle">Search</title>
|
||||
<path d="M14.4121122,14.4121122 L20,20"></path>
|
||||
<circle cx="10" cy="10" r="6"></circle>
|
||||
</svg>
|
||||
</span>
|
||||
</div>
|
||||
<input type="text" class="search-box" v-model="keywords" @keypress.enter="searchEvent">
|
||||
</div>
|
||||
</div>
|
||||
<div class="middle">
|
||||
<div class="zy-table">
|
||||
<div class="tHead">
|
||||
<span class="name">{{$t('videoName')}}</span>
|
||||
<span class="type">{{$t('type')}}</span>
|
||||
<span class="time">{{$t('time')}}</span>
|
||||
<span class="operate">{{$t('operate')}}</span>
|
||||
</div>
|
||||
<div class="tBody zy-scroll">
|
||||
<ul v-show="!tb.loading">
|
||||
<li v-for="(i, j) in tb.list" :key="j" @click="detailEvent(i)">
|
||||
<span class="name">{{i.name}}</span>
|
||||
<span class="type">{{i.type}}</span>
|
||||
<span class="time">{{i.time}}</span>
|
||||
<span class="operate">
|
||||
<span class="btn" @click.stop="playEvent(i)">{{$t('play')}}</span>
|
||||
<span class="btn" @click.stop="starEvent(i)">{{$t('star')}}</span>
|
||||
<span class="btn" @click.stop="shareEvent(i)">{{$t('share')}}</span>
|
||||
</span>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="tBody-mask zy-loading" v-show="tb.loading">
|
||||
<div class="loader"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="tFooter">
|
||||
<span class="tFooter-span">今日更新: {{ tb.update }} 条</span>
|
||||
<el-pagination small :page-size="tb.size" :total="tb.total" :current-page="tb.page" @current-change="tbPageChange" layout="total, prev, pager, next, jumper"></el-pagination>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import { mapMutations } from 'vuex'
|
||||
import { sites, getSite } from '../lib/site/sites'
|
||||
import tools from '../lib/site/tools'
|
||||
import video from '../lib/dexie/video'
|
||||
import setting from '../lib/dexie/setting'
|
||||
export default {
|
||||
name: 'film',
|
||||
data () {
|
||||
return {
|
||||
sites: sites,
|
||||
site: {},
|
||||
top: false,
|
||||
tag: 0,
|
||||
type: 0,
|
||||
typeName: '',
|
||||
keywords: '',
|
||||
id: '',
|
||||
show: {
|
||||
site: false,
|
||||
tags: false,
|
||||
type: false
|
||||
},
|
||||
inputFocus: false,
|
||||
tb: {
|
||||
list: [],
|
||||
page: 1,
|
||||
size: 50,
|
||||
total: 0,
|
||||
update: 0,
|
||||
loading: true
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
view: {
|
||||
get () {
|
||||
return this.$store.getters.getView
|
||||
},
|
||||
set (val) {
|
||||
this.SET_VIEW(val)
|
||||
}
|
||||
},
|
||||
gSite: {
|
||||
get () {
|
||||
return this.$store.getters.getSite
|
||||
},
|
||||
set (val) {
|
||||
this.SET_SITE(val)
|
||||
}
|
||||
},
|
||||
detail: {
|
||||
get () {
|
||||
return this.$store.getters.getDetail
|
||||
},
|
||||
set (val) {
|
||||
this.SET_DETAIL(val)
|
||||
}
|
||||
},
|
||||
video: {
|
||||
get () {
|
||||
return this.$store.getters.getVideo
|
||||
},
|
||||
set (val) {
|
||||
this.SET_VIDEO(val)
|
||||
}
|
||||
},
|
||||
share: {
|
||||
get () {
|
||||
return this.$store.getters.getShare
|
||||
},
|
||||
set (val) {
|
||||
this.SET_SHARE(val)
|
||||
}
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
gSite (n, o) {
|
||||
const s = getSite(n)
|
||||
this.siteClick(s)
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
...mapMutations(['SET_VIEW', 'SET_SITE', 'SET_DETAIL', 'SET_VIDEO', 'SET_SHARE']),
|
||||
init () {
|
||||
setting.find().then(res => {
|
||||
this.site = getSite(res.site)
|
||||
this.top = true
|
||||
tools.film_get(res.site).then(tRes => {
|
||||
this.tb.list = tRes.list
|
||||
this.tb.total = tRes.total
|
||||
this.tb.update = tRes.update
|
||||
this.tb.loading = false
|
||||
})
|
||||
})
|
||||
},
|
||||
siteClick (e) {
|
||||
this.site = e
|
||||
this.tag = 0
|
||||
this.id = e.tags[0].id
|
||||
this.show.site = false
|
||||
if (this.keywords.length > 0) {
|
||||
this.searchEvent()
|
||||
} else {
|
||||
this.tb.update = 0
|
||||
this.tb.total = 0
|
||||
this.tb.loading = true
|
||||
tools.film_get(e.key, this.id).then(res => {
|
||||
this.tb.list = res.list
|
||||
this.tb.total = res.total
|
||||
this.tb.update = res.update
|
||||
this.tb.loading = false
|
||||
})
|
||||
}
|
||||
},
|
||||
tagClick (e, n) {
|
||||
this.tb.update = 0
|
||||
this.tb.total = 0
|
||||
this.tag = n
|
||||
this.id = e.id
|
||||
this.typeName = 'All'
|
||||
this.tb.loading = true
|
||||
this.show.tags = false
|
||||
tools.film_get(this.site.key, this.id).then(res => {
|
||||
this.tb.list = res.list
|
||||
this.tb.total = res.total
|
||||
this.tb.update = res.update
|
||||
this.tb.loading = false
|
||||
})
|
||||
},
|
||||
typeClick (e, n) {
|
||||
this.tb.update = 0
|
||||
this.tb.total = 0
|
||||
this.type = n
|
||||
this.typeName = e.title
|
||||
this.id = e.id
|
||||
this.tb.loading = true
|
||||
this.show.type = false
|
||||
tools.film_get(this.site.key, this.id).then(res => {
|
||||
this.tb.list = res.list
|
||||
this.tb.total = res.total
|
||||
this.tb.update = res.update
|
||||
this.tb.loading = false
|
||||
})
|
||||
},
|
||||
searchEvent () {
|
||||
const flag = this.site.search
|
||||
if (flag === '') {
|
||||
this.$m.warning(this.$t('not_support_search'))
|
||||
return false
|
||||
}
|
||||
this.tb.loading = true
|
||||
this.tb.update = 0
|
||||
this.tb.total = 0
|
||||
tools.search_get(this.site.key, this.keywords).then(res => {
|
||||
this.tb.list = res.list
|
||||
this.tb.total = res.total
|
||||
this.tb.loading = false
|
||||
})
|
||||
},
|
||||
detailEvent (e) {
|
||||
this.detail = {
|
||||
show: true,
|
||||
v: e
|
||||
}
|
||||
},
|
||||
playEvent (e) {
|
||||
this.video = e
|
||||
this.view = 'Play'
|
||||
},
|
||||
starEvent (e) {
|
||||
video.find({ detail: e.detail }).then(res => {
|
||||
if (res) {
|
||||
this.$m.warning(this.$t('exists'))
|
||||
} else {
|
||||
video.add(e).then(res => {
|
||||
this.$m.success(this.$t('star_success'))
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
shareEvent (e) {
|
||||
this.share = {
|
||||
show: true,
|
||||
v: e
|
||||
}
|
||||
},
|
||||
tbPageChange (e) {
|
||||
this.tb.loading = true
|
||||
this.tb.page = e
|
||||
tools.film_get(this.site.key, this.id, this.tb.page).then(res => {
|
||||
this.tb.list = res.list
|
||||
this.tb.loading = false
|
||||
})
|
||||
}
|
||||
},
|
||||
created () {
|
||||
this.init()
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.film{
|
||||
height: 670px;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
animation: viewFadeIn 1s ease-in both;
|
||||
.top{
|
||||
width: 100%;
|
||||
height: 30px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
.search{
|
||||
width: 200px;
|
||||
height: 30px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
border-radius: 15px;
|
||||
svg{
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
stroke-linecap: round;
|
||||
stroke-linejoin: round;
|
||||
}
|
||||
.search-icon{
|
||||
width: 40px;
|
||||
height: 30px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
.search-box{
|
||||
width: 160px;
|
||||
height: 30px;
|
||||
border-radius: 20px;
|
||||
border: none;
|
||||
text-indent: 2px;
|
||||
font-size: 14px;
|
||||
&:focus{
|
||||
outline: none;
|
||||
border: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.middle{
|
||||
height: 620px;
|
||||
width: 100%;
|
||||
margin-top: 10px;
|
||||
padding-bottom: 0px;
|
||||
border-radius: 5px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
65
src/components/Frame.vue
Normal file
@@ -0,0 +1,65 @@
|
||||
<template>
|
||||
<div class="frame">
|
||||
<span class="min" @click="frameClickEvent('min')"></span>
|
||||
<span class="close" @click="frameClickEvent('close')"></span>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
const ipc = require('electron').ipcRenderer
|
||||
export default {
|
||||
name: 'frame',
|
||||
methods: {
|
||||
frameClickEvent (e) {
|
||||
ipc.send(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.frame{
|
||||
width: 100%;
|
||||
height: 40px;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
align-items: center;
|
||||
user-select: none;
|
||||
-webkit-app-region: drag;
|
||||
span{
|
||||
-webkit-app-region: no-drag;
|
||||
display: inline-block;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
border-radius: 50%;
|
||||
margin-left: 10px;
|
||||
cursor: pointer;
|
||||
opacity: 0.5;
|
||||
&:hover{
|
||||
animation: heartbeat 3s ease-in-out infinite both;
|
||||
}
|
||||
@keyframes heartbeat {
|
||||
from {
|
||||
transform: scale(1);
|
||||
transform-origin: center center;
|
||||
animation-timing-function: ease-out;
|
||||
}
|
||||
10% {
|
||||
opacity: 1;
|
||||
transform: scale(0.91);
|
||||
animation-timing-function: ease-in;
|
||||
}
|
||||
17% {
|
||||
transform: scale(0.98);
|
||||
animation-timing-function: ease-out;
|
||||
}
|
||||
33% {
|
||||
transform: scale(0.87);
|
||||
animation-timing-function: ease-in;
|
||||
}
|
||||
45% {
|
||||
transform: scale(1);
|
||||
animation-timing-function: ease-out;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
513
src/components/Play.vue
Normal file
@@ -0,0 +1,513 @@
|
||||
<template>
|
||||
<div class="play">
|
||||
<div class="box">
|
||||
<div class="title">{{name}}</div>
|
||||
<div id="xg"></div>
|
||||
<div class="more" v-show="more">
|
||||
<span class="zy-svg" @click="nextEvent" v-show="showNext">
|
||||
<svg role="img" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" aria-labelledby="forwardIconTitle">
|
||||
<title id="forwardIconTitle">{{$t('next')}}</title>
|
||||
<path d="M10 14.74L3 19V5l7 4.26V5l12 7-12 7v-4.26z"></path>
|
||||
</svg>
|
||||
</span>
|
||||
<span class="zy-svg" @click="listEvent" :class="right.type === 'list' ? 'active' : ''" v-show="right.listData.length > 0">
|
||||
<svg role="img" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" aria-labelledby="dashboardIconTitle">
|
||||
<title id="dashboardIconTitle">{{$t('play_list')}}</title>
|
||||
<rect width="20" height="20" x="2" y="2"></rect>
|
||||
<path d="M11 7L17 7M11 12L17 12M11 17L17 17"></path>
|
||||
<line x1="7" y1="7" x2="7" y2="7"></line>
|
||||
<line x1="7" y1="12" x2="7" y2="12"></line>
|
||||
<line x1="7" y1="17" x2="7" y2="17"></line>
|
||||
</svg>
|
||||
</span>
|
||||
<span class="zy-svg" @click="historyEvent" :class="right.type === 'history' ? 'active' : ''">
|
||||
<svg role="img" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" aria-labelledby="timeIconTitle">
|
||||
<title id="timeIconTitle">{{$t('history')}}</title>
|
||||
<circle cx="12" cy="12" r="10"></circle>
|
||||
<polyline points="12 5 12 12 16 16"></polyline>
|
||||
</svg>
|
||||
</span>
|
||||
<span class="zy-svg" @click="starEvent" :class="isStar ? 'active' : ''" v-show="right.listData.length > 0">
|
||||
<svg role="img" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" aria-labelledby="favouriteIconTitle">
|
||||
<title id="favouriteIconTitle">{{$t('star')}}</title>
|
||||
<path d="M12,21 L10.55,19.7051771 C5.4,15.1242507 2,12.1029973 2,8.39509537 C2,5.37384196 4.42,3 7.5,3 C9.24,3 10.91,3.79455041 12,5.05013624 C13.09,3.79455041 14.76,3 16.5,3 C19.58,3 22,5.37384196 22,8.39509537 C22,12.1029973 18.6,15.1242507 13.45,19.7149864 L12,21 Z"></path>
|
||||
</svg>
|
||||
</span>
|
||||
<span class="zy-svg" @click="detailEvent" v-show="right.listData.length > 0">
|
||||
<svg role="img" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" aria-labelledby="feedIconTitle">
|
||||
<title id="feedIconTitle">{{$t('detail')}}</title>
|
||||
<circle cx="7.5" cy="7.5" r="2.5"></circle>
|
||||
<path d="M22 13H2"></path>
|
||||
<path d="M18 6h-5m5 3h-5"></path>
|
||||
<path d="M5 2h14a3 3 0 0 1 3 3v17H2V5a3 3 0 0 1 3-3z"></path>
|
||||
</svg>
|
||||
</span>
|
||||
<span class="zy-svg" @click="smallEvent" v-show="right.listData.length > 0">
|
||||
<svg role="img" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" aria-labelledby="tvIconTitle">
|
||||
<title id="tvIconTitle">{{$t('mini')}}</title>
|
||||
<polygon points="20 8 20 20 4 20 4 8"></polygon>
|
||||
<polyline stroke-linejoin="round" points="8 4 12 7.917 16 4"></polyline>
|
||||
</svg>
|
||||
</span>
|
||||
<span class="zy-svg" @click="shareEvent" v-show="right.listData.length > 0">
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" aria-labelledby="qrIconTitle">
|
||||
<title id="qrIconTitle">{{$t('share')}}</title>
|
||||
<rect x="10" y="3" width="7" height="7" transform="rotate(90 10 3)"></rect>
|
||||
<rect width="1" height="1" transform="matrix(-1 0 0 1 7 6)"></rect>
|
||||
<rect x="10" y="14" width="7" height="7" transform="rotate(90 10 14)"></rect>
|
||||
<rect x="6" y="17" width="1" height="1"></rect>
|
||||
<rect x="14" y="20" width="1" height="1"></rect>
|
||||
<rect x="17" y="17" width="1" height="1"></rect>
|
||||
<rect x="14" y="14" width="1" height="1"></rect>
|
||||
<rect x="20" y="17" width="1" height="1"></rect>
|
||||
<rect x="20" y="14" width="1" height="1"></rect>
|
||||
<rect x="20" y="20" width="1" height="1"></rect>
|
||||
<rect x="21" y="3" width="7" height="7" transform="rotate(90 21 3)"></rect>
|
||||
<rect x="17" y="6" width="1" height="1"></rect>
|
||||
</svg>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<transition name="slideX">
|
||||
<div v-if="right.show" class="list">
|
||||
<div class="list-top">
|
||||
<span class="list-top-title">{{ right.type === 'list' ? $t('play_list') : $t('history') }}</span>
|
||||
<span class="list-top-close zy-svg" @click="closeEvent">
|
||||
<svg role="img" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" aria-labelledby="closeIconTitle">
|
||||
<title id="closeIconTitle">{{$t('close')}}</title>
|
||||
<path d="M6.34314575 6.34314575L17.6568542 17.6568542M6.34314575 17.6568542L17.6568542 6.34314575"></path>
|
||||
</svg>
|
||||
</span>
|
||||
</div>
|
||||
<div class="list-body zy-scroll" :style="{overflowY:scroll? 'auto' : 'hidden',paddingRight: scroll ? '0': '5px' }" @mouseenter="scroll = true" @mouseleave="scroll = false">
|
||||
<ul v-show="right.type === 'list'" class="list-item">
|
||||
<li v-show="right.listData.length === 0">{{$t('no_data')}}</li>
|
||||
<li @click="listItemEvent(j)" :class="video.index === j ? 'active' : ''" v-for="(i, j) in right.listData" :key="j">{{i | ftName}}</li>
|
||||
</ul>
|
||||
<ul v-show="right.type === 'history'" class="list-history">
|
||||
<li v-show="right.historyData.length > 1" @click="clearAll">{{$t('clear_data')}}</li>
|
||||
<li v-show="right.historyData.length === 0">{{$t('no_data')}}</li>
|
||||
<li @click="historyItemEvent(m)" :class="video.detail === m.detail ? 'active' : ''" v-for="(m, n) in right.historyData" :key="n"><span class="title">{{m.name}}</span><span @click.stop="removeItem(m)" class="detail-delete">{{$t('delete')}}</span></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</transition>
|
||||
<div class="play-mask" v-if="right.listData.length === 0 && right.historyData.length === 0">{{$t('no_history')}}</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import { mapMutations } from 'vuex'
|
||||
import tools from '../lib/site/tools'
|
||||
import history from '../lib/dexie/history'
|
||||
import video from '../lib/dexie/video'
|
||||
import mini from '../lib/dexie/mini'
|
||||
import 'xgplayer'
|
||||
import Hls from 'xgplayer-hls.js'
|
||||
const { ipcRenderer: ipc } = require('electron')
|
||||
export default {
|
||||
name: 'play',
|
||||
data () {
|
||||
return {
|
||||
xg: null,
|
||||
right: {
|
||||
show: false,
|
||||
type: '',
|
||||
listData: [],
|
||||
historyData: []
|
||||
},
|
||||
config: {
|
||||
id: 'xg',
|
||||
lang: 'zh-cn',
|
||||
url: '',
|
||||
fluid: true,
|
||||
autoplay: false,
|
||||
videoInit: true,
|
||||
screenShot: true,
|
||||
keyShortcut: 'on',
|
||||
crossOrigin: true,
|
||||
defaultPlaybackRate: 1,
|
||||
playbackRate: [0.25, 0.5, 0.75, 1, 1.25, 1.5, 1.75, 2, 3, 4, 5]
|
||||
},
|
||||
name: '',
|
||||
timer: null,
|
||||
scroll: false,
|
||||
more: true,
|
||||
showNext: false,
|
||||
isStar: false,
|
||||
isTop: false
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
view: {
|
||||
get () {
|
||||
return this.$store.getters.getView
|
||||
},
|
||||
set (val) {
|
||||
this.SET_VIEW(val)
|
||||
}
|
||||
},
|
||||
video: {
|
||||
get () {
|
||||
return this.$store.getters.getVideo
|
||||
},
|
||||
set (val) {
|
||||
this.SET_VIDEO(val)
|
||||
}
|
||||
},
|
||||
detail: {
|
||||
get () {
|
||||
return this.$store.getters.getDetail
|
||||
},
|
||||
set (val) {
|
||||
this.SET_DETAIL(val)
|
||||
}
|
||||
},
|
||||
share: {
|
||||
get () {
|
||||
return this.$store.getters.getShare
|
||||
},
|
||||
set (val) {
|
||||
this.SET_SHARE(val)
|
||||
}
|
||||
}
|
||||
},
|
||||
filters: {
|
||||
ftName (e) {
|
||||
return e.split('$')[0]
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
view () {
|
||||
this.right.show = false
|
||||
this.right.type = ''
|
||||
},
|
||||
video: {
|
||||
handler () {
|
||||
this.getUrls()
|
||||
},
|
||||
deep: true
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
...mapMutations(['SET_VIEW', 'SET_DETAIL', 'SET_VIDEO', 'SET_SHARE']),
|
||||
getUrls () {
|
||||
if (this.timer !== null) {
|
||||
clearInterval(this.timer)
|
||||
this.timer = null
|
||||
}
|
||||
if (this.xg) {
|
||||
this.xg.pause()
|
||||
}
|
||||
this.changeVideo()
|
||||
tools.detail_get(this.video.site, this.video.detail).then(res => {
|
||||
this.name = this.video.name
|
||||
this.right.listData = res.m3u8_urls
|
||||
if (res.m3u8_urls.length > 1) {
|
||||
const m3 = res.m3u8_urls
|
||||
const arr = []
|
||||
for (const i of m3) {
|
||||
arr.push(i.split('$')[1])
|
||||
}
|
||||
this.xg.src = arr[this.video.index]
|
||||
this.showNext = true
|
||||
} else {
|
||||
const link = res.m3u8_urls[this.video.index]
|
||||
const src = link.split('$')[1]
|
||||
this.xg.src = src
|
||||
this.showNext = false
|
||||
}
|
||||
const currentTime = this.video.currentTime
|
||||
if (currentTime !== '') {
|
||||
this.xg.play()
|
||||
this.xg.once('playing', () => {
|
||||
this.xg.currentTime = currentTime
|
||||
})
|
||||
} else {
|
||||
this.xg.play()
|
||||
}
|
||||
this.onPlayVideo()
|
||||
this.xg.once('ended', () => {
|
||||
if (res.m3u8_urls.length > 1 && (res.m3u8_urls.length - 1 > this.video.index)) {
|
||||
this.video.currentTime = 0
|
||||
this.video.index++
|
||||
}
|
||||
this.xg.off('ended')
|
||||
})
|
||||
}).catch(err => {
|
||||
this.$m.error(err)
|
||||
})
|
||||
},
|
||||
changeVideo () {
|
||||
this.checkStar()
|
||||
this.checkTop()
|
||||
this.name = ''
|
||||
},
|
||||
checkStar () {
|
||||
video.find({ detail: this.video.detail }).then(res => {
|
||||
if (res) {
|
||||
this.isStar = true
|
||||
} else {
|
||||
this.isStar = false
|
||||
}
|
||||
})
|
||||
},
|
||||
checkTop () {
|
||||
ipc.send('checkTop')
|
||||
ipc.on('isTop', (e, flag) => {
|
||||
this.isTop = flag
|
||||
})
|
||||
},
|
||||
onPlayVideo () {
|
||||
this.more = true
|
||||
const h = { ...this.video }
|
||||
history.find({ detail: h.detail }).then(res => {
|
||||
if (res) {
|
||||
h.id = res.id
|
||||
history.update(res.id, h)
|
||||
} else {
|
||||
h.currentTime = ''
|
||||
delete h.id
|
||||
history.add(h)
|
||||
}
|
||||
})
|
||||
this.timerEvent(h.detail)
|
||||
},
|
||||
timerEvent (d) {
|
||||
this.timer = setInterval(() => {
|
||||
history.find({ detail: d }).then(res => {
|
||||
if (res) {
|
||||
const h = { ...this.video }
|
||||
h.currentTime = this.xg.currentTime
|
||||
delete h.id
|
||||
history.update(res.id, h)
|
||||
}
|
||||
})
|
||||
}, 10000)
|
||||
},
|
||||
closeEvent () {
|
||||
this.right.show = false
|
||||
this.right.type = ''
|
||||
},
|
||||
nextEvent () {
|
||||
const v = { ...this.video }
|
||||
const i = v.index + 1
|
||||
if (i < this.right.listData.length) {
|
||||
this.video.index++
|
||||
} else {
|
||||
this.$m.warning(this.$t('last_video'))
|
||||
}
|
||||
},
|
||||
listEvent () {
|
||||
if (this.right.type === 'list') {
|
||||
this.right.show = false
|
||||
this.right.type = ''
|
||||
} else {
|
||||
this.right.show = true
|
||||
this.right.type = 'list'
|
||||
}
|
||||
},
|
||||
historyEvent () {
|
||||
if (this.right.type === 'history') {
|
||||
this.right.show = false
|
||||
this.right.type = ''
|
||||
} else {
|
||||
this.right.show = true
|
||||
this.right.type = 'history'
|
||||
}
|
||||
history.all().then(res => {
|
||||
this.right.historyData = res.reverse()
|
||||
})
|
||||
},
|
||||
starEvent () {
|
||||
video.find({ detail: this.video.detail }).then(res => {
|
||||
if (res !== undefined) {
|
||||
video.remove(res.id).then(r => {
|
||||
this.$m.info(this.$t('delete_success'))
|
||||
this.isStar = false
|
||||
})
|
||||
} else {
|
||||
const v = { ...this.video }
|
||||
if (v.id) {
|
||||
delete v.id
|
||||
}
|
||||
video.add(v).then(r => {
|
||||
this.$m.success(this.$t('star_success'))
|
||||
this.isStar = true
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
detailEvent () {
|
||||
this.detail = {
|
||||
show: true,
|
||||
v: this.video
|
||||
}
|
||||
},
|
||||
smallEvent () {
|
||||
this.xg.pause()
|
||||
mini.find().then(res => {
|
||||
const d = { ...this.video }
|
||||
d.currentTime = this.xg.currentTime
|
||||
d.id = 0
|
||||
if (res) {
|
||||
mini.update(d)
|
||||
} else {
|
||||
mini.add(d)
|
||||
}
|
||||
ipc.send('min')
|
||||
ipc.send('mini')
|
||||
})
|
||||
},
|
||||
shareEvent () {
|
||||
this.share = {
|
||||
show: true,
|
||||
v: this.video
|
||||
}
|
||||
},
|
||||
clearAll () {
|
||||
history.clear().then(res => {
|
||||
this.right.historyData = []
|
||||
})
|
||||
},
|
||||
listItemEvent (n) {
|
||||
this.video.index = n
|
||||
this.right.show = false
|
||||
this.right.type = ''
|
||||
},
|
||||
historyItemEvent (e) {
|
||||
this.video = e
|
||||
this.right.show = false
|
||||
this.right.type = ''
|
||||
},
|
||||
removeItem (e) {
|
||||
history.remove(e.id).then(res => {
|
||||
history.all().then(e => {
|
||||
this.right.historyData = e.reverse()
|
||||
})
|
||||
})
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
this.xg = new Hls(this.config)
|
||||
history.all().then(res => {
|
||||
this.right.historyData = res
|
||||
})
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.play{
|
||||
position: relative;
|
||||
height: 660px;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
border-radius: 5px;
|
||||
.box{
|
||||
width: 92%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
.title{
|
||||
width: 100%;
|
||||
height: 40px;
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
}
|
||||
.more{
|
||||
width: 100%;
|
||||
height: 60px;
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
span{
|
||||
display: flex;
|
||||
margin-right: 10px;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
}
|
||||
.list{
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
width: 300px;
|
||||
height: 100%;
|
||||
z-index: 555;
|
||||
border-radius: 3px;
|
||||
padding: 6px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
.list-top{
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
height: 30px;
|
||||
.list-top-title{
|
||||
font-size: 16px;
|
||||
}
|
||||
.list-top-close{
|
||||
display: inline-block;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
.list-body{
|
||||
flex: 1;
|
||||
overflow-y: auto;
|
||||
ul{
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
list-style: none;
|
||||
li{
|
||||
position: relative;
|
||||
height: 28px;
|
||||
width: 100%;
|
||||
line-height: 28px;
|
||||
padding-left: 10px;
|
||||
font-size: 14px;
|
||||
cursor: pointer;
|
||||
.title{
|
||||
display: inline-block;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
width: 231px;
|
||||
}
|
||||
.detail-delete{
|
||||
display: none;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
height: 28px;
|
||||
width: 50px;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.slideX-enter-active, .slideX-leave-active{
|
||||
transition: all .5s ease-in-out;
|
||||
}
|
||||
.slideX-enter, .slideX-leave-to{
|
||||
transform: translateX(100%);
|
||||
opacity: 0;
|
||||
}
|
||||
.play-mask{
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
z-index: 900;
|
||||
display: flex;
|
||||
font-size: 14px;
|
||||
border-radius: 5px;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
244
src/components/Setting.vue
Normal file
@@ -0,0 +1,244 @@
|
||||
<template>
|
||||
<div class="setting">
|
||||
<div class="setting-box zy-scroll" v-if="show.setting">
|
||||
<div class="logo"><img src="@/assets/image/logo.png"></div>
|
||||
<div class="info">
|
||||
<a @click="linkOpen('https://github.com/Hunlongyu/ZY-Player')">{{$t('website')}}</a>
|
||||
<a @click="linkOpen('https://github.com/Hunlongyu/ZY-Player/issues')">{{$t('issues')}}</a>
|
||||
</div>
|
||||
<div class="change">
|
||||
<div class="zy-select" @mouseleave="show.language = false">
|
||||
<div class="vs-placeholder" @click="show.language = true">{{$t('language')}}</div>
|
||||
<div class="vs-options" v-show="show.language">
|
||||
<ul>
|
||||
<li :class="s.language === i.key ? 'active' : ''" v-for="(i, j) in languages" :key="j" @click="languageClick(i.key)">{{ i.name }}</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="zy-select" @mouseleave="show.site = false">
|
||||
<div class="vs-placeholder" @click="show.site = true">{{$t('default_site')}}</div>
|
||||
<div class="vs-options" v-show="show.site">
|
||||
<ul>
|
||||
<li :class="s.site === i.key ? 'active' : ''" v-for="(i, j) in sites" :key="j" @click="siteClick(i.key)">{{ i.name }}</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="theme">
|
||||
<div class="title">{{$t('theme')}}</div>
|
||||
<div class="theme-box">
|
||||
<div @click="changeTheme('light')" class="theme-item light">
|
||||
<div class="theme-image">
|
||||
<img src="../assets/image/light.png" alt="">
|
||||
</div>
|
||||
<div class="theme-name">Light</div>
|
||||
</div>
|
||||
<div @click="changeTheme('dark')" class="theme-item dark">
|
||||
<div class="theme-image">
|
||||
<img src="../assets/image/dark.png" alt="">
|
||||
</div>
|
||||
<div class="theme-name">Dark</div>
|
||||
</div>
|
||||
<div @click="changeTheme('green')" class="theme-item green">
|
||||
<div class="theme-image">
|
||||
<img src="../assets/image/green.png" alt="">
|
||||
</div>
|
||||
<div class="theme-name">Green</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="qrcode">
|
||||
<div class="title">{{$t('donate')}}</div>
|
||||
<div class="qrcode-box">
|
||||
<img class="qrcode-item" src="../assets/image/alipay.png">
|
||||
<img class="qrcode-item" src="../assets/image/wepay.jpg">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import { mapMutations } from 'vuex'
|
||||
import setting from '../lib/dexie/setting'
|
||||
import { sites } from '../lib/site/sites'
|
||||
import '../lib/cloud/index.js'
|
||||
import { shell } from 'electron'
|
||||
export default {
|
||||
name: 'setting',
|
||||
data () {
|
||||
return {
|
||||
s: {},
|
||||
languages: [
|
||||
{
|
||||
key: 'zhCn',
|
||||
name: '中文'
|
||||
},
|
||||
{
|
||||
key: 'en',
|
||||
name: 'English'
|
||||
}
|
||||
],
|
||||
sites: sites,
|
||||
show: {
|
||||
setting: false,
|
||||
language: false,
|
||||
site: false
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
theme: {
|
||||
get () {
|
||||
return this.$store.getters.getTheme
|
||||
},
|
||||
set (val) {
|
||||
this.SET_THEME(val)
|
||||
}
|
||||
},
|
||||
language: {
|
||||
get () {
|
||||
return this.$store.getters.getLanguage
|
||||
},
|
||||
set (val) {
|
||||
this.SET_LANGUAGE(val)
|
||||
}
|
||||
},
|
||||
site: {
|
||||
get () {
|
||||
return this.$store.getters.getSite
|
||||
},
|
||||
set (val) {
|
||||
this.SET_SITE(val)
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
...mapMutations(['SET_THEME', 'SET_LANGUAGE', 'SET_SITE']),
|
||||
linkOpen (e) {
|
||||
shell.openExternal(e)
|
||||
},
|
||||
languageClick (e) {
|
||||
this.language = e
|
||||
this.show.language = false
|
||||
this.$i18n.locale = e
|
||||
this.s.language = e
|
||||
setting.update(this.s).then(res => {
|
||||
this.$m.success(this.$t('set_success'))
|
||||
})
|
||||
},
|
||||
siteClick (e) {
|
||||
this.site = e
|
||||
this.show.site = false
|
||||
this.s.site = e
|
||||
setting.update(this.s).then(res => {
|
||||
this.$m.success(this.$t('set_success'))
|
||||
})
|
||||
},
|
||||
changeTheme (e) {
|
||||
this.theme = e
|
||||
this.s.theme = e
|
||||
setting.update(this.s).then(res => {
|
||||
this.$m.success(this.$t('set_success'))
|
||||
})
|
||||
}
|
||||
},
|
||||
created () {
|
||||
setting.find().then(res => {
|
||||
this.s = res
|
||||
this.theme = res.theme
|
||||
this.$i18n.locale = this.s.language
|
||||
this.show.setting = true
|
||||
})
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.setting{
|
||||
height: 660px;
|
||||
width: 100%;
|
||||
padding: 20px 0;
|
||||
.setting-box{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
border-radius: 5px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
.logo{
|
||||
margin-top: 10px;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
img{
|
||||
width: 120px;
|
||||
height: auto;
|
||||
}
|
||||
}
|
||||
.info{
|
||||
width: 100%;
|
||||
margin-top: 20px;
|
||||
text-align: center;
|
||||
a{
|
||||
text-decoration: none;
|
||||
margin: 0 10px;
|
||||
font-size: 14px;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
.change{
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
padding-left: 20px;
|
||||
margin-top: 40px;
|
||||
.zy-select{
|
||||
margin-right: 20px;
|
||||
}
|
||||
}
|
||||
.theme{
|
||||
width: 100%;
|
||||
padding-left: 20px;
|
||||
margin-top: 20px;
|
||||
.theme-box{
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
margin-top: 10px;
|
||||
.theme-item{
|
||||
width: 200px;
|
||||
height: 180px;
|
||||
margin-right: 20px;
|
||||
cursor: pointer;
|
||||
border-radius: 2px;
|
||||
.theme-image{
|
||||
width: 180px;
|
||||
margin: 10px auto;
|
||||
img{
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
.theme-name{
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.qrcode{
|
||||
width: 100%;
|
||||
padding-left: 20px;
|
||||
margin-top: 20px;
|
||||
margin-bottom: 20px;
|
||||
.qrcode-box{
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
margin-top: 10px;
|
||||
.qrcode-item{
|
||||
width: auto;
|
||||
height: 300px;
|
||||
margin-right: 20px;
|
||||
border-radius: 2px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
197
src/components/Share.vue
Normal file
@@ -0,0 +1,197 @@
|
||||
<template>
|
||||
<div class="share" id="share" @click="shareClickEvent">
|
||||
<div class="left">
|
||||
<img :src="this.card.img" alt="">
|
||||
</div>
|
||||
<div class="right">
|
||||
<div class="title">{{ card.name }}</div>
|
||||
<qrcode-vue id="qr" :value="value" :size="160" level="L" />
|
||||
<div class="tips">
|
||||
<p>{{$t('qr_tips')}}</p>
|
||||
<p><img src="@/assets/image/logo.png"></p>
|
||||
<p class="zy">{{$t('zy_tips')}}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="share-mask" v-show="loading">
|
||||
<div class="loader"></div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import { mapMutations } from 'vuex'
|
||||
import tools from '../lib/site/tools'
|
||||
import QrcodeVue from 'qrcode.vue'
|
||||
import html2canvas from 'html2canvas'
|
||||
const { clipboard, nativeImage } = require('electron')
|
||||
export default {
|
||||
name: 'share',
|
||||
data () {
|
||||
return {
|
||||
card: {
|
||||
img: '',
|
||||
name: '',
|
||||
png: ''
|
||||
},
|
||||
value: 'https://www.baidu.com',
|
||||
loading: true
|
||||
}
|
||||
},
|
||||
components: {
|
||||
QrcodeVue
|
||||
},
|
||||
computed: {
|
||||
share: {
|
||||
get () {
|
||||
return this.$store.getters.getShare
|
||||
},
|
||||
set (val) {
|
||||
this.SET_SHARE(val)
|
||||
}
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
share: {
|
||||
handler () {
|
||||
this.getDetail()
|
||||
},
|
||||
deep: true
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
...mapMutations(['SET_SHARE']),
|
||||
getDetail () {
|
||||
this.loading = true
|
||||
tools.detail_get(this.share.v.site, this.share.v.detail).then(res => {
|
||||
const info = res.info
|
||||
const parser = new DOMParser()
|
||||
const html = parser.parseFromString(info, 'text/html')
|
||||
const img = html.querySelector('img').src
|
||||
this.card.img = img
|
||||
this.card.name = this.share.v.name
|
||||
const urls = res.m3u8_urls
|
||||
const url = urls[this.share.v.index].split('$')[1]
|
||||
this.value = 'http://zyplayer.fun/player/player.html?url=' + url + '&title=' + this.share.v.name
|
||||
this.loading = false
|
||||
this.$nextTick(() => {
|
||||
const dom = document.getElementById('share')
|
||||
html2canvas(dom, { allowTaint: true, useCORS: true }).then(res => {
|
||||
const png = res.toDataURL('image/png')
|
||||
const p = nativeImage.createFromDataURL(png)
|
||||
clipboard.writeImage(p)
|
||||
this.$m.success(this.$t('share_tips'))
|
||||
this.share.show = true
|
||||
})
|
||||
})
|
||||
})
|
||||
},
|
||||
shareClickEvent () {
|
||||
this.share = {
|
||||
show: false,
|
||||
v: {}
|
||||
}
|
||||
}
|
||||
},
|
||||
created () {
|
||||
this.getDetail()
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.share{
|
||||
position: absolute;
|
||||
bottom: 20px;
|
||||
right: 20px;
|
||||
width: 540px;
|
||||
height: 360px;
|
||||
border-radius: 2px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 20px;
|
||||
z-index: 888;
|
||||
.left, .right{
|
||||
width: 50%;
|
||||
height: 100%;
|
||||
}
|
||||
.left{
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
img{
|
||||
height: 320px;
|
||||
width: auto;
|
||||
max-width: 240px;
|
||||
}
|
||||
}
|
||||
.right{
|
||||
.title{
|
||||
font-size: 18px;
|
||||
margin-bottom: 10px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
#qr{
|
||||
text-align: center;
|
||||
}
|
||||
.tips{
|
||||
font-size: 14px;
|
||||
text-align: center;
|
||||
img{
|
||||
width: 50px;
|
||||
}
|
||||
.zy{
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
}
|
||||
.share-mask{
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
.loader {
|
||||
color: #823aa055;
|
||||
font-size: 8px;
|
||||
width: 1em;
|
||||
height: 1em;
|
||||
border-radius: 50%;
|
||||
position: relative;
|
||||
text-indent: -9999em;
|
||||
animation: load4 1.3s infinite linear;
|
||||
transform: translateZ(0);
|
||||
}
|
||||
@keyframes load4 {
|
||||
0%,
|
||||
100% {
|
||||
box-shadow: 0 -3em 0 0.2em, 2em -2em 0 0em, 3em 0 0 -1em, 2em 2em 0 -1em, 0 3em 0 -1em, -2em 2em 0 -1em, -3em 0 0 -1em, -2em -2em 0 0;
|
||||
}
|
||||
12.5% {
|
||||
box-shadow: 0 -3em 0 0, 2em -2em 0 0.2em, 3em 0 0 0, 2em 2em 0 -1em, 0 3em 0 -1em, -2em 2em 0 -1em, -3em 0 0 -1em, -2em -2em 0 -1em;
|
||||
}
|
||||
25% {
|
||||
box-shadow: 0 -3em 0 -0.5em, 2em -2em 0 0, 3em 0 0 0.2em, 2em 2em 0 0, 0 3em 0 -1em, -2em 2em 0 -1em, -3em 0 0 -1em, -2em -2em 0 -1em;
|
||||
}
|
||||
37.5% {
|
||||
box-shadow: 0 -3em 0 -1em, 2em -2em 0 -1em, 3em 0em 0 0, 2em 2em 0 0.2em, 0 3em 0 0em, -2em 2em 0 -1em, -3em 0em 0 -1em, -2em -2em 0 -1em;
|
||||
}
|
||||
50% {
|
||||
box-shadow: 0 -3em 0 -1em, 2em -2em 0 -1em, 3em 0 0 -1em, 2em 2em 0 0em, 0 3em 0 0.2em, -2em 2em 0 0, -3em 0em 0 -1em, -2em -2em 0 -1em;
|
||||
}
|
||||
62.5% {
|
||||
box-shadow: 0 -3em 0 -1em, 2em -2em 0 -1em, 3em 0 0 -1em, 2em 2em 0 -1em, 0 3em 0 0, -2em 2em 0 0.2em, -3em 0 0 0, -2em -2em 0 -1em;
|
||||
}
|
||||
75% {
|
||||
box-shadow: 0em -3em 0 -1em, 2em -2em 0 -1em, 3em 0em 0 -1em, 2em 2em 0 -1em, 0 3em 0 -1em, -2em 2em 0 0, -3em 0em 0 0.2em, -2em -2em 0 0;
|
||||
}
|
||||
87.5% {
|
||||
box-shadow: 0em -3em 0 0, 2em -2em 0 -1em, 3em 0 0 -1em, 2em 2em 0 -1em, 0 3em 0 -1em, -2em 2em 0 0, -3em 0em 0 0, -2em -2em 0 0.2em;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
159
src/components/Star.vue
Normal file
@@ -0,0 +1,159 @@
|
||||
<template>
|
||||
<div class="star">
|
||||
<div class="zy-table">
|
||||
<div class="tHead">
|
||||
<span class="name">{{$t('videoName')}}</span>
|
||||
<span class="type">{{$t('type')}}</span>
|
||||
<span class="time">{{$t('time')}}</span>
|
||||
<span class="from">{{$t('from')}}</span>
|
||||
<span class="operate" style="width: 170px">{{$t('operate')}}</span>
|
||||
</div>
|
||||
<div class="tBody zy-scroll">
|
||||
<ul v-show="!loading">
|
||||
<li v-for="(i, j) in data" :key="j" @click="detailEvent(i)">
|
||||
<span class="name">{{i.name}}</span>
|
||||
<span class="type">{{i.type}}</span>
|
||||
<span class="time">{{i.time}}</span>
|
||||
<span class="from">{{i.site | ftSite}}</span>
|
||||
<span class="operate" style="width: 170px">
|
||||
<span class="btn" @click.stop="playEvent(i)">{{$t('play')}}</span>
|
||||
<span class="btn" @click.stop="deleteEvent(i)">{{$t('delete')}}</span>
|
||||
<span class="btn" @click.stop="shareEvent(i)">{{$t('share')}}</span>
|
||||
<span class="btn" @click.stop="updateEvent(i)">{{$t('sync')}}</span>
|
||||
</span>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="tBody-mask" v-show="loading">
|
||||
<div class="loader"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="tFooter">
|
||||
<span class="tFooter-span">{{data.length}} {{$t('total')}}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import { mapMutations } from 'vuex'
|
||||
import tools from '../lib/site/tools'
|
||||
import video from '../lib/dexie/video'
|
||||
import { sites, getSite } from '../lib/site/sites'
|
||||
export default {
|
||||
name: 'star',
|
||||
data () {
|
||||
return {
|
||||
sites: sites,
|
||||
data: [],
|
||||
loading: true,
|
||||
checkFlag: false
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
view: {
|
||||
get () {
|
||||
return this.$store.getters.getView
|
||||
},
|
||||
set (val) {
|
||||
this.SET_VIEW(val)
|
||||
}
|
||||
},
|
||||
detail: {
|
||||
get () {
|
||||
return this.$store.getters.getDetail
|
||||
},
|
||||
set (val) {
|
||||
this.SET_DETAIL(val)
|
||||
}
|
||||
},
|
||||
video: {
|
||||
get () {
|
||||
return this.$store.getters.getVideo
|
||||
},
|
||||
set (val) {
|
||||
this.SET_VIDEO(val)
|
||||
}
|
||||
},
|
||||
share: {
|
||||
get () {
|
||||
return this.$store.getters.getShare
|
||||
},
|
||||
set (val) {
|
||||
this.SET_SHARE(val)
|
||||
}
|
||||
}
|
||||
},
|
||||
filters: {
|
||||
ftSite (e) {
|
||||
const name = getSite(e).name
|
||||
return name
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
view () {
|
||||
this.getAllStar()
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
...mapMutations(['SET_VIEW', 'SET_DETAIL', 'SET_VIDEO', 'SET_SHARE']),
|
||||
detailEvent (e) {
|
||||
this.detail = {
|
||||
show: true,
|
||||
v: e
|
||||
}
|
||||
},
|
||||
playEvent (e) {
|
||||
this.video = e
|
||||
this.view = 'Play'
|
||||
},
|
||||
deleteEvent (e) {
|
||||
video.remove(e.id).then(res => {
|
||||
if (res) {
|
||||
this.$m.warning(this.$t('delete_failed'))
|
||||
} else {
|
||||
this.$m.success(this.$t('delete_success'))
|
||||
}
|
||||
this.getAllStar()
|
||||
})
|
||||
},
|
||||
shareEvent (e) {
|
||||
this.share = {
|
||||
show: true,
|
||||
v: e
|
||||
}
|
||||
},
|
||||
updateEvent (e) {
|
||||
tools.detail_get(e.site, e.detail).then(res => {
|
||||
const nameOne = e.name.replace(/\s*/g, '')
|
||||
const nameTwo = res.name.replace(/\s*/g, '')
|
||||
if (nameOne === nameTwo) {
|
||||
this.$m.info(this.$t('async_failed'))
|
||||
} else {
|
||||
const h = e
|
||||
h.name = res.name
|
||||
video.update(h.id, h).then(res => {
|
||||
this.$m.success(this.$t('async_success'))
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
getAllStar () {
|
||||
video.all().then(res => {
|
||||
this.data = res.reverse()
|
||||
this.loading = false
|
||||
})
|
||||
}
|
||||
},
|
||||
created () {
|
||||
this.getAllStar()
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.star{
|
||||
height: 660px;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
border-radius: 5px;
|
||||
}
|
||||
</style>
|
||||
@@ -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()
|
||||
},
|
||||
mounted () {}
|
||||
})
|
||||
</script>
|
||||
<style lang="scss">
|
||||
.detail{
|
||||
box-sizing: border-box;
|
||||
padding: 0 60px;
|
||||
.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>
|
||||
22
src/components/register.js
Normal file
@@ -0,0 +1,22 @@
|
||||
import Vue from 'vue'
|
||||
import Aside from './Aside'
|
||||
import Detail from './Detail'
|
||||
import Film from './Film'
|
||||
import Frame from './Frame'
|
||||
import Play from './Play'
|
||||
import Setting from './Setting'
|
||||
import Share from './Share'
|
||||
import Star from './Star'
|
||||
|
||||
export default {
|
||||
registerComponents () {
|
||||
Vue.component('Aside', Aside)
|
||||
Vue.component('Detail', Detail)
|
||||
Vue.component('Film', Film)
|
||||
Vue.component('Frame', Frame)
|
||||
Vue.component('Play', Play)
|
||||
Vue.component('Setting', Setting)
|
||||
Vue.component('Share', Share)
|
||||
Vue.component('Star', Star)
|
||||
}
|
||||
}
|
||||
32
src/lib/cloud/index.js
Normal file
@@ -0,0 +1,32 @@
|
||||
import setting from '../dexie/setting'
|
||||
|
||||
const os = require('os')
|
||||
const macadress = require('macaddress')
|
||||
const AV = require('leancloud-storage')
|
||||
|
||||
setting.find().then(res => {
|
||||
const cloud = res.cloud
|
||||
if (!cloud) {
|
||||
macadress.one((err, mac) => {
|
||||
if (err) {
|
||||
return false
|
||||
}
|
||||
const system = os.hostname() + ' ' + os.type() + ' ' + os.arch()
|
||||
AV.init({
|
||||
appId: 'X6TRIcMjgOG7EJ0t1l5r9In1-gzGzoHsz',
|
||||
appKey: 'JmkGF9UqkWGQNYDcJ2g1QV1b',
|
||||
serverURL: 'https://x6tricmj.lc-cn-n1-shared.com'
|
||||
})
|
||||
const ZYPlayer = AV.Object.extend('ZYPlayer')
|
||||
const zyPlayer = new ZYPlayer()
|
||||
zyPlayer.set('os', system)
|
||||
zyPlayer.set('mac', mac)
|
||||
zyPlayer.save().then(e => {
|
||||
const id = e.id
|
||||
res.cloud = true
|
||||
res.cloudKey = id
|
||||
setting.update(res)
|
||||
})
|
||||
})
|
||||
}
|
||||
})
|
||||
22
src/lib/dexie/history.js
Normal file
@@ -0,0 +1,22 @@
|
||||
import db from './index'
|
||||
const { history } = db
|
||||
export default {
|
||||
async add (doc) {
|
||||
return await history.add(doc)
|
||||
},
|
||||
async find (doc) {
|
||||
return await history.get(doc)
|
||||
},
|
||||
async update (id, docs) {
|
||||
return await history.update(id, docs)
|
||||
},
|
||||
async all () {
|
||||
return await history.toArray()
|
||||
},
|
||||
async remove (id) {
|
||||
return await history.delete(id)
|
||||
},
|
||||
async clear () {
|
||||
return await history.clear()
|
||||
}
|
||||
}
|
||||
33
src/lib/dexie/index.js
Normal file
@@ -0,0 +1,33 @@
|
||||
import Dexie from 'dexie'
|
||||
|
||||
const db = new Dexie('ZYDB')
|
||||
|
||||
db.version(1).stores({
|
||||
theme: '++id, theme',
|
||||
site: '++id, site',
|
||||
video: '++id, name, type, time, detail, urls, index'
|
||||
})
|
||||
|
||||
db.version(2).stores({
|
||||
setting: 'id, theme, site, language, cloud, cloudKey',
|
||||
video: '++id, site, name, type, time, detail, index',
|
||||
history: '++id, site, name, type, time, detail, index, currentTime',
|
||||
mini: 'id, site, name, type, time, detail, index, currentTime'
|
||||
})
|
||||
|
||||
const initData = [{
|
||||
id: 0,
|
||||
theme: 'light',
|
||||
site: 'zuidazy',
|
||||
language: 'zhCn',
|
||||
cloud: false,
|
||||
cloudKey: ''
|
||||
}]
|
||||
|
||||
db.on('populate', () => {
|
||||
db.setting.bulkAdd(initData)
|
||||
})
|
||||
|
||||
db.open()
|
||||
|
||||
export default db
|
||||
13
src/lib/dexie/mini.js
Normal file
@@ -0,0 +1,13 @@
|
||||
import db from './index'
|
||||
const { mini } = db
|
||||
export default {
|
||||
async add (doc) {
|
||||
return await mini.add(doc)
|
||||
},
|
||||
async find () {
|
||||
return await mini.get({ id: 0 })
|
||||
},
|
||||
async update (docs) {
|
||||
return await mini.update(0, docs)
|
||||
}
|
||||
}
|
||||
10
src/lib/dexie/setting.js
Normal file
@@ -0,0 +1,10 @@
|
||||
import db from './index'
|
||||
const { setting } = db
|
||||
export default {
|
||||
async find () {
|
||||
return await setting.get({ id: 0 })
|
||||
},
|
||||
async update (docs) {
|
||||
return await setting.update(0, docs)
|
||||
}
|
||||
}
|
||||
19
src/lib/dexie/video.js
Normal file
@@ -0,0 +1,19 @@
|
||||
import db from './index'
|
||||
const { video } = db
|
||||
export default {
|
||||
async add (doc) {
|
||||
return await video.add(doc)
|
||||
},
|
||||
async find (doc) {
|
||||
return await video.get(doc)
|
||||
},
|
||||
async update (id, docs) {
|
||||
return await video.update(id, docs)
|
||||
},
|
||||
async all () {
|
||||
return await video.toArray()
|
||||
},
|
||||
async remove (id) {
|
||||
return await video.delete(id)
|
||||
}
|
||||
}
|
||||
6
src/lib/element/index.js
Normal file
@@ -0,0 +1,6 @@
|
||||
import Vue from 'vue'
|
||||
import { Message, Pagination } from 'element-ui'
|
||||
|
||||
Vue.use(Pagination)
|
||||
|
||||
Vue.prototype.$m = Message
|
||||
1232
src/lib/site/sites.js
Normal file
364
src/lib/site/tools.js
Normal file
@@ -0,0 +1,364 @@
|
||||
import axios from 'axios'
|
||||
import { getSite } from './sites'
|
||||
const zy = {
|
||||
key: 'zuidazy', // sites[n] 视频源
|
||||
id: 0, // 视频类型
|
||||
page: 1, // 第几页
|
||||
keywords: '', // 搜索关键字
|
||||
// 获取浏览列表
|
||||
film_get (key, id = 0, page = 1) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const site = getSite(key)
|
||||
let url = ''
|
||||
if (id === 0) {
|
||||
url = site.new.replace(/{page}/, page)
|
||||
} else {
|
||||
url = site.view.replace(/{id}/, id).replace(/{page}/, page)
|
||||
}
|
||||
const type = site.type
|
||||
axios.get(url).then(async res => {
|
||||
const data = res.data
|
||||
if (type === 0) {
|
||||
const zeroData = await this.film_get_type_zero(data, key)
|
||||
resolve(zeroData)
|
||||
}
|
||||
if (type === 1) {
|
||||
const oneData = await this.film_get_type_one(data, key)
|
||||
resolve(oneData)
|
||||
}
|
||||
if (type === 2) {
|
||||
const twoData = await this.film_get_type_two(data, key)
|
||||
resolve(twoData)
|
||||
}
|
||||
}).catch(err => {
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
film_get_type_zero (txt, key) {
|
||||
return new Promise((resolve, reject) => {
|
||||
try {
|
||||
const parser = new DOMParser()
|
||||
const html = parser.parseFromString(txt, 'text/html')
|
||||
const list = html.querySelectorAll('.xing_vb li')
|
||||
const d = { list: [], total: 0, update: 0 }
|
||||
const url = getSite(key).url
|
||||
for (let i = 1; i < list.length - 1; i++) {
|
||||
const info = {
|
||||
site: key,
|
||||
name: list[i].childNodes[1].innerText,
|
||||
type: list[i].childNodes[3].innerText,
|
||||
time: list[i].childNodes[5].innerText,
|
||||
detail: url + list[i].childNodes[1].querySelector('a').getAttribute('href'),
|
||||
index: 0
|
||||
}
|
||||
d.list.push(info)
|
||||
}
|
||||
d.update = parseInt(html.querySelectorAll('.xing_top_right li strong')[0].innerText)
|
||||
let t = html.querySelector('.pages').innerText
|
||||
t = t.split('条')[0]
|
||||
t = t.split('共')[1]
|
||||
d.total = parseInt(t)
|
||||
resolve(d)
|
||||
} catch (err) {
|
||||
reject(err)
|
||||
}
|
||||
})
|
||||
},
|
||||
film_get_type_one (txt, key) {
|
||||
return new Promise((resolve, reject) => {
|
||||
try {
|
||||
const parser = new DOMParser()
|
||||
const html = parser.parseFromString(txt, 'text/html')
|
||||
const list = html.querySelectorAll('.videoContent li')
|
||||
const d = { list: [], total: 0, update: 0 }
|
||||
const url = getSite(key).url
|
||||
for (let i = 0; i < list.length; i++) {
|
||||
const info = {
|
||||
site: key,
|
||||
name: list[i].querySelector('.videoName').innerText,
|
||||
type: list[i].querySelector('.category').innerText,
|
||||
time: list[i].querySelector('.time').innerText,
|
||||
detail: url + list[i].querySelector('.address').getAttribute('href'),
|
||||
index: 0
|
||||
}
|
||||
d.list.push(info)
|
||||
}
|
||||
d.update = parseInt(html.querySelectorAll('.header_list li span')[0].innerText)
|
||||
let t = html.querySelectorAll('.pagination li')
|
||||
t = t[t.length - 2].innerText
|
||||
d.total = parseInt(t) * 50
|
||||
resolve(d)
|
||||
} catch (err) {
|
||||
reject(err)
|
||||
}
|
||||
})
|
||||
},
|
||||
film_get_type_two (txt, key) {
|
||||
return new Promise((resolve, reject) => {
|
||||
try {
|
||||
const parser = new DOMParser()
|
||||
const html = parser.parseFromString(txt, 'text/html')
|
||||
const list = html.querySelectorAll('.nr')
|
||||
const d = { list: [], total: 0, update: 0 }
|
||||
const url = getSite(key).url
|
||||
for (let i = 0; i < list.length; i++) {
|
||||
const info = {
|
||||
site: key,
|
||||
name: '',
|
||||
type: list[i].querySelector('.btn_span').innerText,
|
||||
time: list[i].querySelector('.hours').innerText,
|
||||
detail: url + list[i].querySelector('.name').getAttribute('href'),
|
||||
index: 0
|
||||
}
|
||||
let name = list[i].querySelector('.name').innerText
|
||||
name = name.replace(/^\s*|\s*$/g, '')
|
||||
info.name = name
|
||||
d.list.push(info)
|
||||
}
|
||||
d.update = parseInt(html.querySelector('.kfs em').innerText)
|
||||
d.total = parseInt(html.querySelector('.date span').innerText)
|
||||
let t = html.querySelector('.pag2').innerText
|
||||
t = t.split('条')[0]
|
||||
t = t.split('共')[1]
|
||||
d.total = parseInt(t)
|
||||
resolve(d)
|
||||
} catch (err) {
|
||||
reject(err)
|
||||
}
|
||||
})
|
||||
},
|
||||
// 获取详情
|
||||
detail_get (key, url) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const type = getSite(key).type
|
||||
axios.get(url).then(async res => {
|
||||
if (type === 0) {
|
||||
const zeroData = await this.detail_get_type_zero(res.data, key)
|
||||
resolve(zeroData)
|
||||
}
|
||||
if (type === 1) {
|
||||
const oneData = await this.detail_get_type_one(res.data, key)
|
||||
resolve(oneData)
|
||||
}
|
||||
if (type === 2) {
|
||||
const twoData = await this.detail_get_type_two(res.data, key)
|
||||
resolve(twoData)
|
||||
}
|
||||
}).catch(err => {
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
detail_get_type_zero (txt, key) {
|
||||
return new Promise((resolve, reject) => {
|
||||
try {
|
||||
const parser = new DOMParser()
|
||||
const html = parser.parseFromString(txt, 'text/html')
|
||||
const data = {
|
||||
site: key,
|
||||
name: '',
|
||||
info: '',
|
||||
desc: '',
|
||||
m3u8_urls: [],
|
||||
mp4_urls: []
|
||||
}
|
||||
const vodBox = html.querySelector('.vodBox')
|
||||
data.info = vodBox.innerHTML
|
||||
const title = html.querySelector('.vodh h2').innerText
|
||||
const index = html.querySelector('.vodh span').innerText
|
||||
data.name = title + index
|
||||
const vodInfo = html.querySelectorAll('.playBox')
|
||||
for (let i = 0; i < vodInfo.length; i++) {
|
||||
const k = vodInfo[i].innerText
|
||||
if (k.indexOf('剧情介绍') >= 0) {
|
||||
data.desc = vodInfo[i].querySelector('.vodplayinfo').innerHTML
|
||||
}
|
||||
}
|
||||
const vodLi = html.querySelectorAll('.ibox .vodplayinfo li')
|
||||
const m3u8UrlArr = []
|
||||
const mp4UrlArr = []
|
||||
for (let i = 0; i < vodLi.length; i++) {
|
||||
const j = vodLi[i].innerText
|
||||
if (j.indexOf('.m3u8') >= 0) {
|
||||
m3u8UrlArr.push(j)
|
||||
}
|
||||
if (j.indexOf('.mp4') >= 0) {
|
||||
mp4UrlArr.push(j)
|
||||
}
|
||||
}
|
||||
data.m3u8_urls = m3u8UrlArr
|
||||
data.mp4_urls = mp4UrlArr
|
||||
resolve(data)
|
||||
} catch (err) {
|
||||
reject(err)
|
||||
}
|
||||
})
|
||||
},
|
||||
detail_get_type_one (txt, key) {
|
||||
return new Promise((resolve, reject) => {
|
||||
try {
|
||||
const parser = new DOMParser()
|
||||
const html = parser.parseFromString(txt, 'text/html')
|
||||
const data = {
|
||||
site: key,
|
||||
name: '',
|
||||
info: '',
|
||||
desc: '',
|
||||
m3u8_urls: [],
|
||||
mp4_urls: []
|
||||
}
|
||||
let name = html.querySelector('.whitetitle').innerText
|
||||
name = name.split(':')[1].replace(/^\s*|\s*$/g, '')
|
||||
data.name = name
|
||||
const vodBox = html.querySelector('.white').innerHTML
|
||||
data.info = vodBox
|
||||
const vodInfo = html.querySelectorAll('.white')
|
||||
for (let i = 0; i < vodInfo.length; i++) {
|
||||
const k = vodInfo[i].innerText
|
||||
if (k.indexOf('剧情介绍') >= 0) {
|
||||
data.desc = vodInfo[i].querySelector('div').innerText
|
||||
}
|
||||
}
|
||||
const vodLi = html.querySelectorAll('.playlist li #m3u8')
|
||||
const m3u8UrlArr = []
|
||||
const mp4UrlArr = []
|
||||
for (let i = 0; i < vodLi.length; i++) {
|
||||
const j = vodLi[i].value
|
||||
if (j.indexOf('.m3u8') >= 0) {
|
||||
m3u8UrlArr.push(j)
|
||||
}
|
||||
if (j.indexOf('.mp4') >= 0) {
|
||||
mp4UrlArr.push(j)
|
||||
}
|
||||
}
|
||||
data.m3u8_urls = m3u8UrlArr
|
||||
data.mp4_urls = mp4UrlArr
|
||||
resolve(data)
|
||||
} catch (err) {
|
||||
reject(err)
|
||||
}
|
||||
})
|
||||
},
|
||||
detail_get_type_two (txt, key) {
|
||||
return new Promise((resolve, reject) => {
|
||||
try {
|
||||
const parser = new DOMParser()
|
||||
const html = parser.parseFromString(txt, 'text/html')
|
||||
const data = {
|
||||
site: key,
|
||||
name: '',
|
||||
info: '',
|
||||
desc: '',
|
||||
m3u8_urls: [],
|
||||
mp4_urls: []
|
||||
}
|
||||
const title = html.querySelector('.vodh h2').innerText
|
||||
const index = html.querySelector('.vodh span').innerText
|
||||
data.name = title + index
|
||||
const vodBox = html.querySelector('.vodBox').innerHTML
|
||||
data.info = vodBox
|
||||
data.desc = html.querySelector('.vodplayinfo').innerText
|
||||
const vodLi = html.querySelectorAll('.vodplayinfo li')
|
||||
const m3u8UrlArr = []
|
||||
const mp4UrlArr = []
|
||||
for (let i = 0; i < vodLi.length; i++) {
|
||||
const j = vodLi[i].innerText
|
||||
if (j.indexOf('.m3u8') >= 0) {
|
||||
m3u8UrlArr.push(j)
|
||||
}
|
||||
if (j.indexOf('.mp4') >= 0) {
|
||||
mp4UrlArr.push(j)
|
||||
}
|
||||
}
|
||||
data.m3u8_urls = m3u8UrlArr
|
||||
data.mp4_urls = mp4UrlArr
|
||||
resolve(data)
|
||||
} catch (err) {
|
||||
reject(err)
|
||||
}
|
||||
})
|
||||
},
|
||||
// 搜索列表
|
||||
search_get (key, keywords = '', page = 1) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const site = getSite(key)
|
||||
const type = site.type
|
||||
let url = null
|
||||
if (type === 0) {
|
||||
url = site.search.replace(/{page}/, page).replace(/{keywords}/, keywords)
|
||||
}
|
||||
if (type === 1) {
|
||||
url = site.search.replace(/{keywords}/, keywords)
|
||||
}
|
||||
axios.get(url).then(async res => {
|
||||
const data = res.data
|
||||
if (type === 0) {
|
||||
const zeroData = await this.search_get_type_zero(data, key)
|
||||
resolve(zeroData)
|
||||
}
|
||||
if (type === 1) {
|
||||
const oneData = await this.search_get_type_one(data, key)
|
||||
resolve(oneData)
|
||||
}
|
||||
}).catch(err => {
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
search_get_type_zero (txt, key) {
|
||||
return new Promise((resolve, reject) => {
|
||||
try {
|
||||
const parser = new DOMParser()
|
||||
const html = parser.parseFromString(txt, 'text/html')
|
||||
const list = html.querySelectorAll('.xing_vb li')
|
||||
const d = { list: [], total: 0 }
|
||||
const url = getSite(key).url
|
||||
for (let i = 1; i < list.length - 1; i++) {
|
||||
const info = {
|
||||
site: key,
|
||||
name: list[i].childNodes[1].innerText,
|
||||
type: list[i].childNodes[3].innerText,
|
||||
time: list[i].childNodes[5].innerText,
|
||||
detail: url + list[i].childNodes[1].querySelector('a').getAttribute('href'),
|
||||
index: 0
|
||||
}
|
||||
d.list.push(info)
|
||||
}
|
||||
const t = html.querySelector('.nvc dd').innerText.replace(/[^\d]/g, '')
|
||||
d.total = parseInt(t)
|
||||
resolve(d)
|
||||
} catch (err) {
|
||||
reject(err)
|
||||
}
|
||||
})
|
||||
},
|
||||
search_get_type_one (txt, key) {
|
||||
return new Promise((resolve, reject) => {
|
||||
try {
|
||||
const parser = new DOMParser()
|
||||
const html = parser.parseFromString(txt, 'text/html')
|
||||
const list = html.querySelectorAll('.videoContent li')
|
||||
const d = { list: [], total: 0 }
|
||||
const url = getSite(key).url
|
||||
for (let i = 0; i < list.length; i++) {
|
||||
const info = {
|
||||
site: key,
|
||||
name: list[i].querySelector('.videoName').innerText,
|
||||
type: list[i].querySelector('.category').innerText,
|
||||
time: list[i].querySelector('.time').innerText,
|
||||
detail: url + list[i].querySelector('.address').getAttribute('href'),
|
||||
index: 0
|
||||
}
|
||||
d.list.push(info)
|
||||
}
|
||||
d.total = list.length
|
||||
resolve(d)
|
||||
} catch (err) {
|
||||
reject(err)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
export default zy
|
||||
@@ -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
|
||||
@@ -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
|
||||
48
src/locales/en.json
Normal file
@@ -0,0 +1,48 @@
|
||||
{
|
||||
"zh": "Chinese",
|
||||
"en": "English",
|
||||
"language": "Language",
|
||||
"default_site": "Default Site",
|
||||
"view": "View",
|
||||
"play": "Play",
|
||||
"star": "Star",
|
||||
"setting": "Setting",
|
||||
"exists": "Already exists",
|
||||
"videoName": "Video Name",
|
||||
"type": "Type",
|
||||
"time": "Time",
|
||||
"operate": "Operate",
|
||||
"share": "Share",
|
||||
"detail": "Detail",
|
||||
"close": "Close",
|
||||
"download": "Download",
|
||||
"all_download": "All Download",
|
||||
"next": "Next",
|
||||
"play_list": "Play List",
|
||||
"history": "History",
|
||||
"top": "Top",
|
||||
"mini": "Mini",
|
||||
"no_data": "No Data",
|
||||
"clear_data": "Clear Data",
|
||||
"delete": "Delete",
|
||||
"from": "From",
|
||||
"sync": "Sync",
|
||||
"total": "Items",
|
||||
"website": "Official Website",
|
||||
"issues": "Issues",
|
||||
"theme": "Theme",
|
||||
"donate": "Donate",
|
||||
"set_success": "Set up successfully.",
|
||||
"delete_success": "Delete successful.",
|
||||
"delete_failed": "Delete failed.",
|
||||
"star_success": "Collection success.",
|
||||
"last_video": "This is the last episode.",
|
||||
"qr_tips": "Long click recognition.",
|
||||
"zy_tips": "Prohibit the dissemination of illegal resources.",
|
||||
"share_tips": "It has been copied to the clipboard. Please share it~",
|
||||
"not_support_search": "Search is not supported on this site.",
|
||||
"copy_success": "has been copied, Download it now",
|
||||
"async_failed": "Synchronization successful, no updates found.",
|
||||
"async_success": "Synchronization succeeded, update found.",
|
||||
"no_history": "No history data."
|
||||
}
|
||||
9
src/locales/index.js
Normal file
@@ -0,0 +1,9 @@
|
||||
import en from './en.json'
|
||||
import zhCn from './zh-cn'
|
||||
|
||||
export const defaultLocal = 'zhCn'
|
||||
|
||||
export const languages = {
|
||||
en: en,
|
||||
zhCn: zhCn
|
||||
}
|
||||
48
src/locales/zh-cn.json
Normal file
@@ -0,0 +1,48 @@
|
||||
{
|
||||
"zh": "中文",
|
||||
"en": "英文",
|
||||
"language": "语言",
|
||||
"default_site": "默认源",
|
||||
"view": "浏览",
|
||||
"play": "播放",
|
||||
"star": "收藏",
|
||||
"setting": "设置",
|
||||
"exists": "已存在",
|
||||
"videoName": "视频名称",
|
||||
"type": "类型",
|
||||
"time": "时间",
|
||||
"operate": "操作",
|
||||
"share": "分享",
|
||||
"detail": "详情",
|
||||
"close": "关闭",
|
||||
"download": "下载",
|
||||
"all_download": "全集下载",
|
||||
"next": "下一集",
|
||||
"play_list": "播放列表",
|
||||
"history": "历史记录",
|
||||
"top": "置顶",
|
||||
"mini": "精简模式",
|
||||
"no_data": "无数据",
|
||||
"clear_data": "清空数据",
|
||||
"delete": "删除",
|
||||
"from": "来源",
|
||||
"sync": "同步",
|
||||
"total": "条数据",
|
||||
"website": "官网",
|
||||
"issues": "内测反馈",
|
||||
"theme": "主题",
|
||||
"donate": "捐赠",
|
||||
"set_success": "设置成功。",
|
||||
"delete_success": "删除成功。",
|
||||
"delete_failed": "删除失败。",
|
||||
"star_success": "收藏成功。",
|
||||
"last_video": "这已经是最后一集了。",
|
||||
"qr_tips": "长按二维码,识别播放。",
|
||||
"zy_tips": "『ZY Player』技术支持,严禁传播违法资源。",
|
||||
"share_tips": "已复制到剪贴板,快去分享吧~ 严禁传播违法资源!!!",
|
||||
"not_support_search": "这个网站不支持搜索。",
|
||||
"copy_success": "已复制,快去下载吧。",
|
||||
"async_failed": "同步成功, 未查询到更新。",
|
||||
"async_success": "同步成功, 查询到更新。",
|
||||
"no_history": "无历史记录"
|
||||
}
|
||||
26
src/main.js
Normal file
@@ -0,0 +1,26 @@
|
||||
import Vue from 'vue'
|
||||
import App from './App.vue'
|
||||
import store from './store'
|
||||
import 'modern-normalize'
|
||||
import Register from './components/register'
|
||||
import VueI18n from 'vue-i18n'
|
||||
import { languages, defaultLocal } from './locales/index'
|
||||
import './lib/element/index'
|
||||
|
||||
Vue.config.productionTip = false
|
||||
|
||||
Register.registerComponents()
|
||||
|
||||
Vue.use(VueI18n)
|
||||
const messages = Object.assign(languages)
|
||||
const i18n = new VueI18n({
|
||||
locale: defaultLocal,
|
||||
fallbackLocale: 'zhCn',
|
||||
messages
|
||||
})
|
||||
|
||||
new Vue({
|
||||
store,
|
||||
i18n,
|
||||
render: h => h(App)
|
||||
}).$mount('#app')
|
||||
14
src/main.ts
@@ -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')
|
||||
279
src/mini/Mini.vue
Normal file
@@ -0,0 +1,279 @@
|
||||
<template>
|
||||
<div class="mini">
|
||||
<div class="top">
|
||||
<div class="left">
|
||||
<span class="number" v-show="show.number">{{index + 1}} / {{length}}</span>
|
||||
<span class="zy-svg" @click="prevEvent" v-show="show.prev">
|
||||
<svg role="img" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" aria-labelledby="backIconTitle">
|
||||
<title id="backIconTitle">上一集</title>
|
||||
<path d="M14 14.74L21 19V5l-7 4.26V5L2 12l12 7v-4.26z"></path>
|
||||
</svg>
|
||||
</span>
|
||||
<span class="zy-svg" @click="nextEvent" v-show="show.next">
|
||||
<svg role="img" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" aria-labelledby="forwardIconTitle">
|
||||
<title id="forwardIconTitle">下一集</title>
|
||||
<path d="M10 14.74L3 19V5l7 4.26V5l12 7-12 7v-4.26z"></path>
|
||||
</svg>
|
||||
</span>
|
||||
<span class="opacity">
|
||||
<input type="number" min="5" max="100" v-model="opacity" @change="opacityChange"/>
|
||||
</span>
|
||||
</div>
|
||||
<div class="right">
|
||||
<span class="min" @click="frameClickEvent('miniMin')"></span>
|
||||
<span class="close" @click="frameClickEvent('miniClose')"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="bottom">
|
||||
<div id="xg"></div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import tools from '../lib/site/tools'
|
||||
import mini from '../lib/dexie/mini'
|
||||
import history from '../lib/dexie/history'
|
||||
import 'xgplayer'
|
||||
import Hls from 'xgplayer-hls.js'
|
||||
const ipc = require('electron').ipcRenderer
|
||||
export default {
|
||||
name: 'mini',
|
||||
data () {
|
||||
return {
|
||||
xg: null,
|
||||
config: {
|
||||
id: 'xg',
|
||||
lang: 'zh-cn',
|
||||
url: '',
|
||||
fluid: true,
|
||||
autoplay: false,
|
||||
videoInit: true,
|
||||
screenShot: true,
|
||||
keyShortcut: 'on',
|
||||
crossOrigin: true,
|
||||
defaultPlaybackRate: 1,
|
||||
playbackRate: [0.25, 0.5, 0.75, 1, 1.25, 1.5, 1.75, 2, 3, 4, 5]
|
||||
},
|
||||
opacity: 100,
|
||||
video: {},
|
||||
d: {},
|
||||
show: {
|
||||
prev: false,
|
||||
next: false,
|
||||
number: false
|
||||
},
|
||||
index: 0,
|
||||
length: 0
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
frameClickEvent (e) {
|
||||
ipc.send(e)
|
||||
},
|
||||
opacityChange (e) {
|
||||
ipc.send('mini-opacity', this.opacity / 100)
|
||||
},
|
||||
getUrls () {
|
||||
mini.find().then(res => {
|
||||
const v = res
|
||||
if (v.index > 0) {
|
||||
this.show.next = true
|
||||
this.show.number = true
|
||||
}
|
||||
this.video = res
|
||||
tools.detail_get(v.site, v.detail).then(res => {
|
||||
this.d = res
|
||||
if (v.index >= this.d.m3u8_urls.length) {
|
||||
this.show.next = false
|
||||
}
|
||||
this.index = v.index
|
||||
this.length = this.d.m3u8_urls.length
|
||||
const link = res.m3u8_urls[v.index]
|
||||
const src = link.split('$')[1]
|
||||
this.xg.src = src
|
||||
const currentTime = v.currentTime
|
||||
if (currentTime !== '') {
|
||||
this.xg.play()
|
||||
this.xg.once('playing', () => {
|
||||
this.xg.currentTime = currentTime
|
||||
})
|
||||
} else {
|
||||
this.xg.play()
|
||||
}
|
||||
this.onPlayVideo()
|
||||
})
|
||||
})
|
||||
},
|
||||
onPlayVideo () {
|
||||
const h = { ...this.video }
|
||||
history.find({ detail: h.detail }).then(res => {
|
||||
if (res) {
|
||||
h.id = res.id
|
||||
history.update(res.id, h)
|
||||
} else {
|
||||
h.currentTime = ''
|
||||
delete h.id
|
||||
history.add(h)
|
||||
}
|
||||
})
|
||||
this.timerEvent(h.detail)
|
||||
},
|
||||
timerEvent (d) {
|
||||
this.timer = setInterval(() => {
|
||||
history.find({ detail: d }).then(res => {
|
||||
if (res) {
|
||||
const h = { ...this.video }
|
||||
h.currentTime = this.xg.currentTime
|
||||
h.id = res.id
|
||||
history.update(res.id, h)
|
||||
}
|
||||
})
|
||||
}, 10000)
|
||||
},
|
||||
prevEvent () {
|
||||
if (this.index > 0) {
|
||||
this.index--
|
||||
let src = this.d.m3u8_urls[this.index]
|
||||
src = src.split('$')[1]
|
||||
this.xg.src = src
|
||||
this.show.next = true
|
||||
}
|
||||
if (this.index === 0) {
|
||||
this.show.prev = false
|
||||
}
|
||||
},
|
||||
nextEvent () {
|
||||
if (this.index < this.d.m3u8_urls.length - 1) {
|
||||
this.index++
|
||||
let src = this.d.m3u8_urls[this.index]
|
||||
src = src.split('$')[1]
|
||||
this.xg.src = src
|
||||
this.show.prev = true
|
||||
}
|
||||
if (this.index === this.d.m3u8_urls.length - 1) {
|
||||
this.show.next = false
|
||||
}
|
||||
}
|
||||
},
|
||||
created () {
|
||||
this.getUrls()
|
||||
},
|
||||
mounted () {
|
||||
this.xg = new Hls(this.config)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss">
|
||||
html,body{
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
background-color: #000;
|
||||
}
|
||||
.mini{
|
||||
box-sizing: border-box;
|
||||
.top{
|
||||
-webkit-app-region: drag;
|
||||
width: 100%;
|
||||
height: 30px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
user-select: none;
|
||||
.zy-svg{
|
||||
-webkit-app-region: no-drag;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
cursor: pointer;
|
||||
svg{
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
stroke: #fff;
|
||||
stroke-width: 1;
|
||||
stroke-linecap: round;
|
||||
stroke-linejoin: round;
|
||||
fill: none;
|
||||
}
|
||||
}
|
||||
.left{
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
height: 100%;
|
||||
flex: 1;
|
||||
.number{
|
||||
color: #fff;
|
||||
margin: 0 10px;
|
||||
font-size: 12px;
|
||||
}
|
||||
.opacity{
|
||||
-webkit-app-region: no-drag;
|
||||
margin-left: 10px;
|
||||
input{
|
||||
text-indent: 4px;
|
||||
background-color: #000;
|
||||
color: #fff;
|
||||
border: 1px solid #aaa;
|
||||
}
|
||||
}
|
||||
}
|
||||
.right{
|
||||
width: 80px;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
align-items: center;
|
||||
span{
|
||||
-webkit-app-region: no-drag;
|
||||
display: inline-block;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
border-radius: 50%;
|
||||
margin-right: 10px;
|
||||
cursor: pointer;
|
||||
opacity: 0.5;
|
||||
&.min{
|
||||
background-color: #ffbe2a;
|
||||
}
|
||||
&.close{
|
||||
background-color: #ff5f56;
|
||||
}
|
||||
&:hover{
|
||||
animation: heartbeat 3s ease-in-out infinite both;
|
||||
}
|
||||
@keyframes heartbeat {
|
||||
from {
|
||||
transform: scale(1);
|
||||
transform-origin: center center;
|
||||
animation-timing-function: ease-out;
|
||||
}
|
||||
10% {
|
||||
opacity: 1;
|
||||
transform: scale(0.91);
|
||||
animation-timing-function: ease-in;
|
||||
}
|
||||
17% {
|
||||
transform: scale(0.98);
|
||||
animation-timing-function: ease-out;
|
||||
}
|
||||
33% {
|
||||
transform: scale(0.87);
|
||||
animation-timing-function: ease-in;
|
||||
}
|
||||
45% {
|
||||
transform: scale(1);
|
||||
animation-timing-function: ease-out;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.bottom{
|
||||
width: 100%;
|
||||
height: 305px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
7
src/mini/main.js
Normal file
@@ -0,0 +1,7 @@
|
||||
import Vue from 'vue'
|
||||
import Mini from './Mini'
|
||||
Vue.config.productionTip = false
|
||||
|
||||
new Vue({
|
||||
render: h => h(Mini)
|
||||
}).$mount('#app')
|
||||
@@ -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>
|
||||
@@ -1,270 +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-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 } = 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
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
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)
|
||||
}
|
||||
},
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
</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>
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
@@ -1,200 +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
|
||||
}
|
||||
}
|
||||
},
|
||||
created () {}
|
||||
})
|
||||
</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>
|
||||
@@ -1,195 +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-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('http://zy.hly120506.top')">官网: 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>
|
||||
</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: 96,
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,128 +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">
|
||||
<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 { mapMutations } from 'vuex'
|
||||
export default Vue.extend({
|
||||
data () {
|
||||
return {
|
||||
filmData: [],
|
||||
filmPage: 1,
|
||||
filmTotal: 0
|
||||
}
|
||||
},
|
||||
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>
|
||||
@@ -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()
|
||||
@@ -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)
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -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)
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -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)
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -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
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||