From 61032b65fb1fe4fefb400f34e00fec3963f09ae0 Mon Sep 17 00:00:00 2001 From: 7red4 Date: Tue, 20 Jul 2021 20:48:49 +0800 Subject: [PATCH] fix lowdb permission, drawer; add youtube-dl method in select --- src/App.vue | 89 +++++++++++++++++---------- src/GlobalComponentsInject.js | 7 +++ src/background.js | 44 +++++++++++--- src/components/Globals/Async.vue | 72 ++++++++++++++++++++++ src/components/Globals/SizeBox.vue | 77 +++++++++++++++++++++++ src/components/QueTracker.vue | 98 ++++++++++++++++++++++-------- src/main.js | 2 + src/plugins/database.js | 4 +- src/views/Downloader.vue | 62 ++++++++++++------- vue.config.js | 8 +-- 10 files changed, 369 insertions(+), 94 deletions(-) create mode 100644 src/GlobalComponentsInject.js create mode 100644 src/components/Globals/Async.vue create mode 100644 src/components/Globals/SizeBox.vue diff --git a/src/App.vue b/src/App.vue index e171426..02597be 100644 --- a/src/App.vue +++ b/src/App.vue @@ -52,52 +52,55 @@ + + + + + + + + - + + 下載中的影片 - 全部開始 +
+
+ + +
+
-
-
-
- - -
-
- - - - - - - + + + 全部開始 + 全部刪除 + 全部停止 + + + @@ -119,7 +122,11 @@ export default { return { platform: '', isMaximized: false, - isDrawer: false + isDrawer: false, + + isMenuShow: false, + x: 0, + y: 0 }; }, @@ -209,8 +216,26 @@ export default { ipcRenderer.send('close-window'); }, + showMenu(e) { + e.preventDefault(); + this.isMenuShow = false; + this.x = e.clientX; + this.y = e.clientY; + this.$nextTick(() => { + this.isMenuShow = true; + }); + }, + startAll() { ipcRenderer.send('start-ques'); + }, + + deleteAll() { + ipcRenderer.send('delete-ques'); + }, + + stopAll() { + ipcRenderer.send('stop-ques'); } } }; diff --git a/src/GlobalComponentsInject.js b/src/GlobalComponentsInject.js new file mode 100644 index 0000000..80c1ff9 --- /dev/null +++ b/src/GlobalComponentsInject.js @@ -0,0 +1,7 @@ +import Vue from 'vue'; + +import Async from '@/components/Globals/Async.vue'; +import SizeBox from '@/components/Globals/SizeBox.vue'; + +Vue.component('Async', Async); +Vue.component('SizeBox', SizeBox); diff --git a/src/background.js b/src/background.js index 72f9420..0440552 100644 --- a/src/background.js +++ b/src/background.js @@ -2,7 +2,7 @@ import fs from 'fs'; import https from 'https'; import os from 'os'; -import { app, protocol, BrowserWindow, ipcMain, dialog } from 'electron'; +import { app, protocol, BrowserWindow, ipcMain, dialog, shell } from 'electron'; import { createProtocol } from 'vue-cli-plugin-electron-builder/lib'; import installExtension, { VUEJS_DEVTOOLS } from 'electron-devtools-installer'; import { getInfo } from './controller/ytdl.js'; @@ -139,6 +139,19 @@ ipcMain.on('delete-que', async (event, queId) => { } }); +ipcMain.on('delete-ques', async (event) => { + queMap.forEach(({ id, stopProcess }) => { + try { + stopProcess(); + queMap.delete(id); + event.reply('delete-que-reply', id); + } catch (error) { + event.reply('delete-fail', id); + consola.error(error); + } + }); +}); + ipcMain.on('start-que-by-id', async (event, queId) => { const que = queMap.get(queId); try { @@ -151,14 +164,14 @@ ipcMain.on('start-que-by-id', async (event, queId) => { }); ipcMain.on('start-ques', async (event, req) => { - try { - queMap.forEach((que) => { + queMap.forEach((que) => { + try { que.startProcess({ event }); - }); - } catch (error) { - // event.reply('start-fail', que.id); - consola.error(error); - } + } catch (error) { + // event.reply('start-fail', que.id); + consola.error(error); + } + }); }); ipcMain.on('stop-que', async (event, queId) => { @@ -170,6 +183,17 @@ ipcMain.on('stop-que', async (event, queId) => { } }); +ipcMain.on('stop-que', async (event) => { + queMap.forEach(({ id, stopProcess }) => { + try { + stopProcess(); + } catch (error) { + event.reply('stoped-error', id); + consola.error(error); + } + }); +}); + ipcMain.on('edit-que', (event, tracker) => { try { queMap.get(tracker.id).updateQue(tracker); @@ -227,3 +251,7 @@ ipcMain.on('export-list', async (event, { exporting, path }) => { consola.error(error); } }); + +ipcMain.on('show-item-in-folder', (event, path) => { + shell.openPath(path); +}); diff --git a/src/components/Globals/Async.vue b/src/components/Globals/Async.vue new file mode 100644 index 0000000..1bfecbf --- /dev/null +++ b/src/components/Globals/Async.vue @@ -0,0 +1,72 @@ + + + diff --git a/src/components/Globals/SizeBox.vue b/src/components/Globals/SizeBox.vue new file mode 100644 index 0000000..b61c5b5 --- /dev/null +++ b/src/components/Globals/SizeBox.vue @@ -0,0 +1,77 @@ + diff --git a/src/components/QueTracker.vue b/src/components/QueTracker.vue index 273e138..e1c8704 100644 --- a/src/components/QueTracker.vue +++ b/src/components/QueTracker.vue @@ -62,31 +62,70 @@

- - 從佇列移除 - - - 終止 - - - {{ isLive ? '錄製' : '下載' }} - + + + + 打開檔案位置 + + + + + + 從佇列移除 + + + + + + 終止 + + + + + + + {{ isLive ? '錄製' : downloadComplete ? '重新下載' : '下載' }} + + @@ -128,6 +167,12 @@ export default { set(v) { this.editQue({ path: v }); } + }, + downloadComplete() { + return ( + this.tracker.audio.downloaded / this.tracker.audio.total === 1 || + this.tracker.video.downloaded / this.tracker.video.total === 1 + ); } }, @@ -159,6 +204,9 @@ export default { }, editQue({ title, path } = {}) { ipcRenderer.send('edit-que', { id: this.tracker.id, title, path }); + }, + showItemInFolder() { + ipcRenderer.send('show-item-in-folder', this.tracker.path); } } }; diff --git a/src/main.js b/src/main.js index f88970b..17863ba 100644 --- a/src/main.js +++ b/src/main.js @@ -7,6 +7,8 @@ import DB from './plugins/database'; import '@/assets/style/main.scss'; +import './GlobalComponentsInject.js'; + function parseYtId(url) { var regExp = /^.*((youtu.be\/)|(v\/)|(\/u\/\w\/)|(embed\/)|(watch\?))\??v?=?([^#&?]*).*/; diff --git a/src/plugins/database.js b/src/plugins/database.js index 78f2eec..cb3e5d2 100644 --- a/src/plugins/database.js +++ b/src/plugins/database.js @@ -1,10 +1,12 @@ import lowdb from 'lowdb'; import FileSync from 'lowdb/adapters/FileSync'; +const appRootDir = require('app-root-dir').get(); +import PATH from 'path'; const DB = { install(Vue, options) { if (!options) { - options = { name: 'db.json' }; + options = { name: PATH.join(appRootDir, 'db.json') }; } const dbPath = options.name; diff --git a/src/views/Downloader.vue b/src/views/Downloader.vue index fa461b6..d894a52 100644 --- a/src/views/Downloader.vue +++ b/src/views/Downloader.vue @@ -62,6 +62,26 @@ > + + + + + + - - - 最高畫質 - + @@ -120,18 +128,12 @@ > - - - 最高音質 - + @@ -188,6 +190,7 @@ export default { path: this.$db.get('dl_path').value() || '', tumbnailPath: '', thumbnailURL: '', + dlMethod: 'ytdl', title: '', loading: false, snack: false, @@ -208,7 +211,10 @@ export default { vQualities() { return this.videoInfo ? this.videoInfo.formats - .filter(({ mimeType }) => /video/.test(mimeType)) + .filter( + ({ mimeType }) => + /video/.test(mimeType) && !/av01/g.test(mimeType) + ) .sort((a, b) => Number(a.qualityLabel.replace('p', '')) < Number(b.qualityLabel.replace('p', '')) @@ -242,6 +248,14 @@ export default { watch: { videoInfo(v) { v && (this.title = filenamify(v.videoDetails.title)); + this.$nextTick(() => { + if (this.vQualities.length) { + this.vQuality = this.vQualities[0]; + } + if (this.aQualities.length) { + this.aQuality = this.aQualities[0]; + } + }); }, path(v) { this.$db.set('dl_path', v).write(); @@ -295,6 +309,7 @@ export default { path: this.$db.get('dl_path').value() || '', tumbnailPath: '', thumbnailURL: '', + dlMethod: 'ytdl', title: '', loading: false, videoInfo: null, @@ -345,6 +360,7 @@ export default { title: this.title, url: this.ytUrl, path: this.path, + dlMethod: this.dlMethod, quality: { audio: this.aQuality ? this.aQuality.itag || 'highestaudio' diff --git a/vue.config.js b/vue.config.js index 05c7297..2e3bd22 100644 --- a/vue.config.js +++ b/vue.config.js @@ -1,15 +1,13 @@ module.exports = { - configureWebpack: { - // Webpack configuration applied to web builds and the electron renderer process - }, + transpileDependencies: ['vuetify'], pluginOptions: { electronBuilder: { nodeIntegration: true, builderOptions: { extraFiles: [ { - from: 'node_modules/ffmpeg-static', - to: './resources/node_modules/ffmpeg-static/' + from: 'src/binaries', + to: './resources/' } ] }