Compare commits

...

30 Commits

Author SHA1 Message Date
haiyangcui
add2bedb61 v2.4.2 2020-08-25 16:59:59 +02:00
haiyangcui
3dc970e198 更新已存在的收藏 2020-08-25 15:54:07 +02:00
haiyangcui
3f2def4455 添加第三方播放器路径设置 2020-08-25 14:38:46 +02:00
haiyangcui
5b8d883af4 Format JSON string 2020-08-25 13:48:33 +02:00
haiyangcui
7113567475 可以使用PotPlayer打开视频 2020-08-25 00:31:34 +02:00
haiyangcui
e30da35e72 Import sites from file 2020-08-24 13:10:30 +02:00
haiyangcui
55b7396a2e Export sites to file 2020-08-24 12:54:31 +02:00
haiyangcui
83568fa499 No need to copy to clipboard 2020-08-24 12:32:51 +02:00
haiyangcui
838d3a64cd v2.4.1 2020-08-23 17:48:10 +02:00
haiyangcui
506be03e3e 从文件中导入收藏 2020-08-23 17:45:19 +02:00
haiyangcui
cfdb561473 加入取消操作识别 2020-08-23 15:03:47 +02:00
haiyangcui
ab2f45189f 导出收藏到文件 2020-08-23 14:33:59 +02:00
haiyangcui
f4b9a73b18 Simple favorites export import 2020-08-22 17:55:10 +02:00
haiyangcui
6f99d789f4 2.4.0 2020-08-22 16:08:38 +02:00
haiyangcui
e71090dad2 Wrap the items in Settings theme-box 2020-08-22 15:54:39 +02:00
haiyangcui
afe3351837 Add left margin to name 2020-08-22 15:35:28 +02:00
haiyangcui
5dc0613aeb 列表自适应 2020-08-22 15:06:10 +02:00
haiyangcui
1c6385ae6c 使用v-show显示隐藏class element,这样可以保持其占位 2020-08-22 10:58:47 +02:00
haiyangcui
88a95a8bfb 保存搜索选项设置 2020-08-22 00:20:18 +02:00
haiyangcui
951e6ffa37 更好的修复bug#183 2020-08-21 23:49:00 +02:00
haiyangcui
b83aed0a97 解决bug #183 2020-08-21 23:36:17 +02:00
haiyangcui
67ce537039 Add search style 2020-08-21 23:00:21 +02:00
haiyangcui
975562a66b Fix a bug in Detail.vue 2020-08-19 23:31:20 +02:00
haiyangcui
8e7015c9d6 调整"搜索所有资源"位置 2020-08-19 23:09:42 +02:00
haiyangcui
b841552dc7 转移"搜索所有资源"到设置页面 2020-08-19 18:07:37 +02:00
haiyangcui
0a9b939dc3 v2.3.8 2020-08-19 11:36:08 +02:00
haiyangcui
14ff252cce 定义--highlight-color 2020-08-19 08:30:18 +02:00
haiyangcui
afd016be93 取消“搜索所有资源”的边框 2020-08-18 23:00:05 +02:00
haiyangcui
9cd7f7d267 高亮有更新的收藏项 2020-08-18 22:51:03 +02:00
haiyangcui
8a76ec4e87 Null check on site 2020-08-18 17:39:39 +02:00
14 changed files with 256 additions and 94 deletions

View File

@@ -1,6 +1,6 @@
{
"name": "zy",
"version": "2.3.7",
"version": "2.4.2",
"private": true,
"scripts": {
"serve": "vue-cli-service serve",
@@ -18,6 +18,7 @@
"main": "background.js",
"dependencies": {
"axios": "^0.19.2",
"child_process": "^1.0.2",
"core-js": "^3.6.5",
"cors": "^2.8.5",
"dexie": "^3.0.1",

View File

@@ -83,13 +83,15 @@
display: flex;
width: 200px;
height: 30px;
border-radius: 3px;
vertical-align: middle;
align-items: center;
.search-all-check-input{
cursor: pointer;
}
}
.zy-highlighted{
color: var(--highlight-color);
}
// table
.zy-table{
display: flex;
@@ -129,34 +131,36 @@
cursor: pointer;
span{
display: flex;
width: 180px;
font-size: 13px;
height: 50px;
line-height: 50px;
overflow: hidden;
margin-right: 5px;
&.name{
flex: 1;
padding-left: 15px;
overflow: hidden;
text-overflow: ellipsis;
min-width: 100px;
white-space: nowrap;
}
&.note{
width: 180px;
margin-left: 10px;
}
&.type{
width: 120px;
}
&.last{
width: 160px;
width: 10%;
}
&.time{
width: 60px;
width: 10%;
}
&.from{
width: 120px;
&.last{
width: 10%;
}
&.site{
width: 10%;
}
&.note{
width: 10%;
}
&.operate{
width: 170px;
.btn{
width: 40px;
}
}
}
}

View File

@@ -1,4 +1,6 @@
:root{
// general
--highlight-color: #38dd77;
// light
--l-c-0: #823aa0;
--l-c-1: #823aa011;

View File

@@ -34,12 +34,7 @@
}
.zy-checkbox{
color: var(--d-fc-1);
background-color: var(--d-bgc-1);
box-shadow: var(--d-bsc);
transition: all 0.3s cubic-bezier(.25,.8,.25,1);
&:hover{
box-shadow: var(--d-bsc-hover);
}
}
.zy-table{
color: var(--d-fc-2);
@@ -295,7 +290,7 @@
}
}
}
.view, .shortcut, .site{
.view, .search, .shortcut, .site{
.title{
color: var(--d-fc-1);
}

View File

@@ -34,12 +34,6 @@
}
.zy-checkbox{
color: var(--g-fc-1);
background-color: var(--g-bgc-1);
box-shadow: var(--g-bsc);
transition: all 0.3s cubic-bezier(.25,.8,.25,1);
&:hover{
box-shadow: var(--g-bsc-hover);
}
}
.zy-table{
color: var(--g-fc-2);
@@ -295,7 +289,7 @@
}
}
}
.view, .shortcut, .site{
.view, .search, .shortcut, .site{
.title{
color: var(--g-fc-1);
}

View File

@@ -34,12 +34,6 @@
}
.zy-checkbox{
color: var(--l-fc-1);
background-color: var(--l-bgc-1);
box-shadow: var(--l-bsc);
transition: all 0.3s cubic-bezier(.25,.8,.25,1);
&:hover{
box-shadow: var(--l-bsc-hover);
}
}
.zy-table{
color: var(--l-fc-2);
@@ -295,7 +289,7 @@
}
}
}
.view, .shortcut, .site{
.view, .search, .shortcut, .site{
.title{
color: var(--l-fc-1);
}

View File

@@ -34,12 +34,6 @@
}
.zy-checkbox{
color: var(--p-fc-1);
background-color: var(--p-bgc-1);
box-shadow: var(--p-bsc);
transition: all 0.3s cubic-bezier(.25,.8,.25,1);
&:hover{
box-shadow: var(--p-bsc-hover);
}
}
.zy-table{
color: var(--p-fc-2);
@@ -295,7 +289,7 @@
}
}
}
.view, .shortcut, .site{
.view, .search, .shortcut, .site{
.title{
color: var(--p-fc-1);
}

View File

@@ -131,20 +131,22 @@ export default {
this.detail.show = false
},
starEvent () {
star.find({ key: this.detail.site.key, ids: this.info.id }).then(res => {
star.find({ key: this.detail.key, ids: this.info.id }).then(res => {
const docs = {
key: this.detail.site.key,
site: this.detail.site,
ids: this.info.id,
name: this.info.name,
type: this.info.type,
year: this.info.year,
last: this.info.last,
note: this.info.note
}
if (res) {
this.$message.info('已存在')
star.update(res.id, docs).then(res => {
this.$message.success('已存在,更新成功')
})
} else {
const docs = {
key: this.detail.site.key,
site: this.detail.site,
ids: this.info.id,
name: this.info.name,
type: this.info.type,
year: this.info.year,
last: this.info.last,
note: this.info.note
}
star.add(docs).then(res => {
this.$message.success('收藏成功')
})

View File

@@ -9,7 +9,7 @@
</ul>
</div>
</div>
<div class="zy-select" @mouseleave="show.classList = false" v-if="show.class">
<div class="zy-select" @mouseleave="show.classList = false" v-show="show.class">
<div class="vs-placeholder" @click="show.classList = true">{{type.name}}</div>
<div class="vs-options" v-show="show.classList">
<ul class="zy-scroll" style="max-height: 600px;">
@@ -26,9 +26,6 @@
</ul>
</div>
</div>
<div class="zy-checkbox">
<input type="checkbox" v-model="searchAllSites" class="search-all-check-input" > 搜索所有资源
</div>
</div>
<div class="body zy-scroll" infinite-wrapper>
<div class="body-box" v-show="!show.find">
@@ -84,12 +81,11 @@
<div class="body-box" v-show="show.find">
<div class="show-table">
<div class="zy-table">
<div class="tBody">
<div class="tBody zy-scroll">
<ul>
<li v-for="(i, j) in searchContents" :key="j" @click="detailEvent(i.site, i)">
<span class="name">{{i.name}}</span>
<span class="type">{{i.type}}</span>
<span class="time">{{i.year}}</span>
<span class="last">{{i.last}}</span>
<span class="site">{{i.site.name}}</span>
<span class="note">{{i.note}}</span>
@@ -138,8 +134,7 @@ export default {
infiniteId: +new Date(),
searchList: [],
searchTxt: '',
searchContents: [],
searchAllSites: false
searchContents: []
}
},
components: {
@@ -205,7 +200,7 @@ export default {
this.show.site = false
this.show.class = false
if (this.searchTxt.length > 0) {
this.searchEvent()
this.searchSingleSiteEvent(this.site, this.searchTxt)
} else {
this.classList = []
this.type = {}
@@ -426,12 +421,15 @@ export default {
}
},
searchEvent (wd) {
var sites = []
if (this.searchAllSites) {
sites.push(...this.sites)
if (this.setting.searchAllSites) {
this.searchAllSitesEvent(this.sites, wd)
} else {
sites.push(this.site)
this.searchSingleSiteEvent(this.site, wd)
}
},
searchSingleSiteEvent (site, wd) {
var sites = []
sites.push(this.site)
this.searchAllSitesEvent(sites, wd)
},
clearSearch () {

View File

@@ -11,8 +11,8 @@
<li v-for="(i, j) in history" :key="j" @click="historyItemEvent(i)">
<span class="name" @click.stop="playEvent(i)">{{i.name}}</span>
<span class="site">{{getSiteName(i.site)}}</span>
<span class="index">{{i.index+1}}</span>
<span class="operate" style="width: 220px">
<span class="note">{{i.index+1}}</span>
<span class="operate">
<span class="btn" @click.stop="playEvent(i)">播放</span>
<span class="btn" @click.stop="downloadEvent(i)">下载</span>
<span class="btn" @click.stop="removeHistoryItem(i)">删除</span>
@@ -144,7 +144,9 @@ export default {
},
getSiteName (key) {
var site = this.sites.find(e => e.key === key)
return site.name
if (site) {
return site.name
}
},
historyItemEvent (e) {
this.video = {

View File

@@ -3,6 +3,12 @@
<div class="box">
<div class="title">
<span v-if="this.right.list.length > 1"> {{(video.info.index + 1)}} </span>{{name}}
<span v-if="video.key" class="right" @click="playWithExternalPalyerEvent" title="使用第三方播放器">
<svg role="img" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
<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 v-if="video.key" class="right" @click="issueEvent" title="复制调试信息">
<svg t="1596338860607" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3127" width="24" height="24">
<path d="M503.803829 63.578014c-247.050676 0-447.328072 200.277396-447.328072 447.327048 0 247.054769 200.277396 447.333188 447.328072 447.333188 247.054769 0 447.332165-200.278419 447.332165-447.333188C951.13497 263.85541 750.858598 63.578014 503.803829 63.578014L503.803829 63.578014zM503.803829 894.313336c-211.749682 0-383.408273-171.659615-383.408273-383.408273 0-211.749682 171.659615-383.40725 383.408273-383.40725 211.753775 0 383.412366 171.658591 383.412366 383.40725C887.216195 722.653721 715.557604 894.313336 503.803829 894.313336L503.803829 894.313336zM447.745069 255.897158l127.914298 0L575.659367 383.576095 447.745069 383.576095 447.745069 255.897158 447.745069 255.897158zM447.745069 425.470251l127.914298 0 0 342.058516L447.745069 767.528767 447.745069 425.470251 447.745069 425.470251zM447.745069 425.470251" p-id="3128"></path>
@@ -535,6 +541,19 @@ export default {
clipboard.writeText(JSON.stringify(info, null, 4))
this.$message.success('视频信息复制成功')
},
playWithExternalPalyerEvent () {
this.fetchM3u8List().then(m3u8Arr => {
var m3u8Link = m3u8Arr[this.video.info.index]
const fs = require('fs')
var externalPlayer = this.setting.externalPlayer
if (fs.existsSync(externalPlayer)) {
var exec = require('child_process').execFile
exec(externalPlayer, [m3u8Link])
} else {
this.$message.error('请设置第三方播放器路径')
}
})
},
checkStar () {
star.find({ site: this.video.key, ids: this.video.info.id }).then(res => {
if (res) {

View File

@@ -44,6 +44,31 @@
</div>
</div>
</div>
<div class='site'>
<div class="title">收藏管理</div>
<div class="site-box">
<div class="zy-select">
<div class="vs-placeholder vs-noAfter" @click="exportFavorites">导出</div>
</div>
<div class="zy-select">
<div class="vs-placeholder vs-noAfter" @click="importFavorites">导入</div>
</div>
</div>
</div>
<div class='search'>
<div class="title">搜索</div>
<div class="zy-checkbox">
<input type="checkbox" v-model="setting.searchAllSites" @change="updateSearchOption($event)"> 搜索所有资源
</div>
</div>
<div class='site'>
<div class="title">第三方播放器</div>
<div class="site-box">
<div class="zy-select">
<div class="vs-placeholder vs-noAfter" @click="selectExternalPlayer">选择</div>
</div>
</div>
</div>
<div class="site">
<div class="title">源管理</div>
<div class="site-box">
@@ -115,9 +140,10 @@
<script>
import { mapMutations } from 'vuex'
import pkg from '../../package.json'
import { setting, sites, shortcut } from '../lib/dexie'
import { setting, sites, shortcut, star } from '../lib/dexie'
import { shell, clipboard, remote } from 'electron'
import db from '../lib/dexie/dexie'
import fs from 'fs'
export default {
name: 'setting',
data () {
@@ -125,6 +151,7 @@ export default {
pkg: pkg,
sitesList: [],
shortcutList: [],
favoritesList: [],
show: {
site: false,
shortcut: false,
@@ -135,7 +162,9 @@ export default {
site: '',
theme: '',
shortcut: true,
view: 'picture'
searchAllSites: true,
view: 'picture',
externalPlayer: ''
}
}
},
@@ -161,7 +190,9 @@ export default {
site: res.site,
theme: res.theme,
shortcut: res.shortcut,
view: res.view
view: res.view,
searchAllSites: res.searchAllSites,
externalPlayer: res.externalPlayer
}
this.setting = this.d
})
@@ -176,6 +207,11 @@ export default {
this.shortcutList = res
})
},
getFavorites () {
star.all().then(res => {
this.favoritesList = res
})
},
changeView (e) {
this.d.view = e
setting.update(this.d).then(res => {
@@ -192,25 +228,123 @@ export default {
this.show.site = false
})
},
expSites () {
const arr = [...this.sitesList]
const str = JSON.stringify(arr)
clipboard.writeText(str)
this.$message.success('已复制到剪贴板')
updateSearchOption (e) {
this.d.searchAllSites = this.setting.searchAllSites
setting.update(this.d).then(res => {
this.setting = this.d
})
},
impSites () {
const str = clipboard.readText()
const json = JSON.parse(str)
sites.clear().then(res => {
this.$message.info('已清空原数据')
sites.add(json).then(e => {
this.$message.success('已添加成功')
this.getSites()
this.d.site = json[0].key
exportFavorites () {
const arr = [...this.favoritesList]
const str = JSON.stringify(arr, null, 4)
const options = {
filters: [
{ name: 'JSON file', extensions: ['json'] },
{ name: 'Normal text file', extensions: ['txt'] },
{ name: 'All types', extensions: ['*'] }
]
}
remote.dialog.showSaveDialog(options).then(result => {
if (!result.canceled) {
fs.writeFileSync(result.filePath, str)
this.$message.success('已保存成功')
}
}).catch(err => {
this.$message.error(err)
})
},
importFavorites () {
const options = {
filters: [
{ name: 'JSON file', extensions: ['json'] },
{ name: 'Normal text file', extensions: ['txt'] },
{ name: 'All types', extensions: ['*'] }
],
properties: ['openFile', 'multiSelections']
}
remote.dialog.showOpenDialog(options).then(result => {
if (!result.canceled) {
result.filePaths.forEach(file => {
var str = fs.readFileSync(file)
const json = JSON.parse(str)
star.bulkAdd(json).then(e => {
this.getFavorites()
})
})
this.$message.success('导入收藏成功')
}
}).catch(err => {
this.$message.error(err)
})
},
selectExternalPlayer () {
const options = {
filters: [
{ name: 'Executable file', extensions: ['exe'] },
{ name: 'All types', extensions: ['*'] }
],
properties: ['openFile']
}
remote.dialog.showOpenDialog(options).then(result => {
if (!result.canceled) {
var playerPath = result.filePaths[0].replace(/\\/g, '/')
this.$message.success(result.filePaths[0])
this.$message.success('设定第三方播放器路径为:' + result.filePaths[0])
this.d.externalPlayer = playerPath
setting.update(this.d).then(res => {
this.setting = this.d
})
})
}
}).catch(err => {
this.$message.error(err)
})
},
expSites () {
const arr = [...this.sitesList]
const str = JSON.stringify(arr, null, 4)
const options = {
filters: [
{ name: 'JSON file', extensions: ['json'] },
{ name: 'Normal text file', extensions: ['txt'] },
{ name: 'All types', extensions: ['*'] }
]
}
remote.dialog.showSaveDialog(options).then(result => {
if (!result.canceled) {
fs.writeFileSync(result.filePath, str)
this.$message.success('已保存成功')
}
}).catch(err => {
this.$message.error(err)
})
},
impSites () {
const options = {
filters: [
{ name: 'JSON file', extensions: ['json'] },
{ name: 'Normal text file', extensions: ['txt'] },
{ name: 'All types', extensions: ['*'] }
],
properties: ['openFile']
}
remote.dialog.showOpenDialog(options).then(result => {
if (!result.canceled) {
sites.clear()
result.filePaths.forEach(file => {
var str = fs.readFileSync(file)
const json = JSON.parse(str)
sites.add(json).then(e => {
this.getSites()
this.d.site = json[0].key
setting.update(this.d).then(res => {
this.setting = this.d
})
})
this.$message.success('导入成功')
}).catch(err => {
this.$message.error(err)
})
}
})
},
changeTheme (e) {
@@ -266,6 +400,7 @@ export default {
this.getSetting()
this.getSites()
this.getShortcut()
this.getFavorites()
}
}
</script>
@@ -313,6 +448,11 @@ export default {
}
}
}
.search{
width: 100%;
padding: 20px;
margin-top: 20px;
}
.site{
width: 100%;
padding: 20px;
@@ -341,6 +481,7 @@ export default {
margin-top: 20px;
.theme-box{
display: flex;
flex-wrap: wrap;
justify-content: flex-start;
margin-top: 10px;
.theme-item{

View File

@@ -7,13 +7,13 @@
</div>
<div class="tBody zy-scroll">
<ul>
<li v-for="(i, j) in list" :key="j" @click="detailEvent(i)">
<li v-for="(i, j) in list" :key="j" @click="detailEvent(i)" :class="[i.hasUpdate ? 'zy-highlighted': '']">
<span class="name">{{i.name}}</span>
<span class="type">{{i.type}}</span>
<span class="time">{{i.year}}</span>
<span class="from">{{i.site.name}}</span>
<span class="site">{{i.site.name}}</span>
<span class="note">{{i.note}}</span>
<span class="operate" style="width: 220px">
<span class="operate">
<span class="btn" @click.stop="playEvent(i)">播放</span>
<span class="btn" @click.stop="deleteEvent(i)">删除</span>
<span class="btn" @click.stop="shareEvent(i)">分享</span>
@@ -89,6 +89,7 @@ export default {
name: e.name
}
}
this.clearHasUpdateFlag(e)
},
playEvent (e) {
history.find({ site: e.site.key, ids: e.ids }).then(res => {
@@ -98,6 +99,7 @@ export default {
this.video = { key: e.site.key, info: { id: e.ids, name: e.name, index: 0, site: e.site } }
}
})
this.clearHasUpdateFlag(e)
this.view = 'Play'
},
deleteEvent (e) {
@@ -117,6 +119,13 @@ export default {
info: e
}
},
clearHasUpdateFlag (e) {
star.find({ id: e.id }).then(res => {
res.hasUpdate = false
star.update(e.id, res)
this.getStarList()
})
},
updateEvent (e) {
zy.detail(e.site.key, e.ids).then(res => {
if (e.last === res.last) {
@@ -131,7 +140,8 @@ export default {
site: e.site,
type: res.type,
year: res.year,
note: res.note
note: res.note,
hasUpdate: true
}
star.update(e.id, doc).then(res => {
var msg = `同步"${e.name}"成功, 检查到更新。`

View File

@@ -4,6 +4,9 @@ export default {
async add (doc) {
return await star.add(doc)
},
async bulkAdd (doc) {
return await star.bulkAdd(doc)
},
async find (doc) {
return await star.get(doc)
},
@@ -15,5 +18,8 @@ export default {
},
async remove (id) {
return await star.delete(id)
},
async clear () {
return await star.clear()
}
}