diff --git a/package.json b/package.json index 5ace955..149ec18 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "top.yutent.sonist", - "version": "2.0.0-alpha-1", + "version": "2.0.0-alpha-2", "description": "Music Player", "main": "src/main.js", "scripts": { @@ -15,7 +15,8 @@ "license": "MIT", "dependencies": { "crypto.js": "^2.0.2", - "iofs": "^1.5.1" + "iofs": "^1.5.1", + "sqlite3": "^5.0.0" }, "devDependencies": { "electron": "^10.0.0", @@ -33,7 +34,12 @@ "version": "10.1.5", "mirror": "https://npm.taobao.org/mirrors/electron/" }, - "files": ["src/**/*", "node_modules/iofs/*", "node_modules/crypto.js/*"], + "files": [ + "src/**/*", + "node_modules/iofs/*", + "node_modules/sqlite3/*", + "node_modules/crypto.js/*" + ], "mac": { "category": "public.app-category.music", "target": "dmg", diff --git a/src/css/app.css b/src/css/app.css index 0f139eb..5cbaaea 100644 --- a/src/css/app.css +++ b/src/css/app.css @@ -1 +1 @@ -.app{position:relative;display:flex;flex-direction:column;width:100%;height:100%;background:rgba(0,0,0,0.2)}.app .title-bar{position:relative;display:flex;align-items:center;z-index:9;height:26px}.app .title-bar .btn-box{display:inline-flex;width:auto;height:12px;padding:0 8px}.app .title-bar .btn-box .item{display:inline-flex;width:12px;height:12px;margin:0 3px;background:url(/images/btn-grey.svg) no-repeat;background-size:cover}.app .title-bar .btn-box.focus .quit{background-image:url(/images/btn-close.svg)}.app .title-bar .btn-box.focus .min{background-image:url(/images/btn-mini.svg)}.app .title-bar .btn-box:hover .quit{background-image:url(/images/btn-close_a.svg)}.app .title-bar .btn-box:hover .min{background-image:url(/images/btn-mini_a.svg)}.app .main-body{overflow:hidden;flex:1;display:flex;justify-content:space-between}.app .main-body .aside{width:180px;height:100%;padding:0 16px;line-height:2}.app .main-body .aside fieldset{border:0;color:#ebebeb;font-size:12px}.app .main-body .aside fieldset legend{font-size:18px;background:linear-gradient(to bottom, #58ffdf 50%, #459888);-webkit-background-clip:text;background-clip:text;color:transparent}.app .main-body .aside fieldset .item{padding-left:12px;line-height:1.75}.app .main-body .aside fieldset button{width:42px;height:16px;margin-left:12px;font-size:10px;border:0;border-radius:9px;background:#64b5f6;color:#fff}.app .main-body .song-box{width:618px}.app .main-body .song-box .preview{position:relative;display:flex;align-items:center;width:100%;height:99px;padding-bottom:16px;border-bottom:1px solid rgba(200,200,200,0.1)}.app .main-body .song-box .preview .album{width:80px;height:80px}.app .main-body .song-box .preview .album img{width:100%;height:100%}.app .main-body .song-box .preview .info{display:flex;flex-direction:column;justify-content:center;width:320px;margin-left:32px}.app .main-body .song-box .preview .info strong{height:36px;font-size:18px;font-weight:normal}.app .main-body .song-box .preview .info cite{font-size:12px;font-style:normal}.app .main-body .song-box .preview .info p{font-size:12px;color:#bdbdbd}.app .main-body .song-box .preview .duration{position:absolute;right:32px;top:16px;font-size:12px;color:#bdbdbd}.app .main-body .song-box .preview .total{position:absolute;right:32px;bottom:16px;font-size:16px;font-weight:bold;font-family:Raleway}.app .main-body .song-box .scroll-box{width:100%;height:269px;padding:16px 6px;border-top:1px solid rgba(32,32,32,0.1)}.app .main-body .song-box .list{height:237px;font-size:12px}.app .main-body .song-box .list .item{display:flex;align-items:center;height:26px;padding:0 12px;border-radius:13px}.app .main-body .song-box .list .item .idx{position:relative;width:64px;padding-left:16px;font-size:12px;font-family:Raleway}.app .main-body .song-box .list .item .name{overflow:hidden;flex:1}.app .main-body .song-box .list .item .artist{overflow:hidden;width:128px;margin-left:12px}.app .main-body .song-box .list .item .duration{width:42px;margin-left:12px}.app .main-body .song-box .list .item.on{color:#feac23;font-size:14px}.app .main-body .song-box .list .item.on .idx::before{position:absolute;left:0;top:3px;font-size:10px;content:"▶ "}.app .main-body .song-box .list .item.active,.app .main-body .song-box .list .item:hover{color:#58ffdf;background:rgba(29,77,68,0.15)}.app .play-bar{height:66px;width:100%;background:rgba(255,255,255,0.25);color:#fff}.app .play-bar .stat-bar{display:flex;align-items:center;justify-content:space-between;height:20px;color:#ebebeb}.app .play-bar .stat-bar .time{width:42px;margin:0 6px;text-align:center;font-size:12px}.app .play-bar .stat-bar .progress{flex:1;display:flex;align-items:flex-start;height:3px;background:#b2cfe3}.app .play-bar .stat-bar .thumb{width:8%;height:3px;background:#58ffdf}.app .play-bar .ctrl-box{display:flex;align-items:center;height:42px}.app .play-bar .ctrl-box .holder{flex:1}.app .play-bar .ctrl-box .info{display:flex;flex-direction:column;justify-content:center;width:320px;height:42px;padding-left:12px;line-height:1.25}.app .play-bar .ctrl-box .info strong{font-size:14px;font-weight:500}.app .play-bar .ctrl-box .info cite{font-size:12px;font-style:normal;color:#aeaeae}.app .play-bar .ctrl-box .play-btn{display:flex;align-items:center;justify-content:space-between;width:120px;height:42px;margin-left:32px}.app .play-bar .ctrl-box .play-btn .item{width:22px;height:22px;background-repeat:no-repeat;background-size:cover;transition:background .1s ease-in-out;cursor:pointer}.app .play-bar .ctrl-box .play-btn .item.prev{background-image:url(/images/ctrl/prev.png)}.app .play-bar .ctrl-box .play-btn .item.prev:hover,.app .play-bar .ctrl-box .play-btn .item.prev:active{background-image:url(/images/ctrl/prev_a.png)}.app .play-bar .ctrl-box .play-btn .item.on,.app .play-bar .ctrl-box .play-btn .item.off{width:42px;height:42px}.app .play-bar .ctrl-box .play-btn .item.on{background-image:url(/images/ctrl/play.png);-webkit-animation:round 2s linear infinite;animation:round 2s linear infinite}.app .play-bar .ctrl-box .play-btn .item.on:hover,.app .play-bar .ctrl-box .play-btn .item.on:active{background-image:url(/images/ctrl/play_a.png)}.app .play-bar .ctrl-box .play-btn .item.off{background-image:url(/images/ctrl/pause.png)}.app .play-bar .ctrl-box .play-btn .item.off:hover,.app .play-bar .ctrl-box .play-btn .item.off:active{background-image:url(/images/ctrl/pause_a.png)}.app .play-bar .ctrl-box .play-btn .item.next{background-image:url(/images/ctrl/next.png)}.app .play-bar .ctrl-box .play-btn .item.next:hover,.app .play-bar .ctrl-box .play-btn .item.next:active{background-image:url(/images/ctrl/next_a.png)}.app .play-bar .ctrl-box .play-action{display:flex;align-items:center;justify-content:space-between;width:64px;height:22px;margin-right:16px}.app .play-bar .ctrl-box .play-action .item{width:22px;height:22px;background-repeat:no-repeat;background-size:cover;transition:background .1s ease-in-out;cursor:pointer}.app .play-bar .ctrl-box .play-action .item.volume{background-image:url(/images/ctrl/volume.png)}.app .play-bar .ctrl-box .play-action .item.volume:hover,.app .play-bar .ctrl-box .play-action .item.volume:active{background-image:url(/images/ctrl/volume_a.png)}.app .play-bar .ctrl-box .play-action .item.mute{background-image:url(/images/ctrl/mute.png)}.app .play-bar .ctrl-box .play-action .item.mute:hover,.app .play-bar .ctrl-box .play-action .item.mute:active{background-image:url(/images/ctrl/mute_a.png)}.app .play-bar .ctrl-box .play-action .item.single{background-image:url(/images/ctrl/single.png)}.app .play-bar .ctrl-box .play-action .item.single:hover,.app .play-bar .ctrl-box .play-action .item.single:active{background-image:url(/images/ctrl/single_a.png)}.app .play-bar .ctrl-box .play-action .item.all{background-image:url(/images/ctrl/all.png)}.app .play-bar .ctrl-box .play-action .item.all:hover,.app .play-bar .ctrl-box .play-action .item.all:active{background-image:url(/images/ctrl/all_a.png)}.app .play-bar .ctrl-box .play-action .item.rand{background-image:url(/images/ctrl/rand.png)}.app .play-bar .ctrl-box .play-action .item.rand:hover,.app .play-bar .ctrl-box .play-action .item.rand:active{background-image:url(/images/ctrl/rand_a.png)}@-webkit-keyframes round{from{-webkit-transform:rotate(0);transform:rotate(0)}to{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes round{from{-webkit-transform:rotate(0);transform:rotate(0)}to{-webkit-transform:rotate(360deg);transform:rotate(360deg)}} +.app{position:relative;display:flex;flex-direction:column;width:100%;height:100%;background:rgba(0,0,0,0.3)}.app .title-bar{position:relative;display:flex;align-items:center;z-index:9;height:26px}.app .title-bar .btn-box{display:inline-flex;width:auto;height:12px;padding:0 8px}.app .title-bar .btn-box .item{display:inline-flex;width:12px;height:12px;margin:0 3px;background:url(/images/btn-grey.svg) no-repeat;background-size:cover}.app .title-bar .btn-box.focus .quit{background-image:url(/images/btn-close.svg)}.app .title-bar .btn-box.focus .min{background-image:url(/images/btn-mini.svg)}.app .title-bar .btn-box:hover .quit{background-image:url(/images/btn-close_a.svg)}.app .title-bar .btn-box:hover .min{background-image:url(/images/btn-mini_a.svg)}.app .main-body{overflow:hidden;flex:1;display:flex;justify-content:space-between}.app .main-body .aside{width:180px;height:100%;padding:0 16px;line-height:2}.app .main-body .aside fieldset{border:0;color:#ebebeb;font-size:12px}.app .main-body .aside fieldset legend{font-size:18px;background:linear-gradient(to bottom, #58ffdf 50%, #459888);-webkit-background-clip:text;background-clip:text;color:transparent}.app .main-body .aside fieldset .item{padding-left:12px;line-height:1.75}.app .main-body .aside fieldset button{width:42px;height:16px;margin-left:12px;font-size:10px;border:0;border-radius:9px;background:#64b5f6;color:#fff}.app .main-body .song-box{width:618px}.app .main-body .song-box .preview{position:relative;display:flex;align-items:center;width:100%;height:99px;padding-bottom:16px;border-bottom:1px solid rgba(200,200,200,0.1)}.app .main-body .song-box .preview .album{width:80px;height:80px}.app .main-body .song-box .preview .album img{width:100%;height:100%}.app .main-body .song-box .preview .info{display:flex;flex-direction:column;justify-content:center;width:320px;margin-left:32px}.app .main-body .song-box .preview .info strong{height:36px;font-size:18px;font-weight:normal}.app .main-body .song-box .preview .info cite{font-size:12px;font-style:normal}.app .main-body .song-box .preview .info p{font-size:12px;color:#bdbdbd}.app .main-body .song-box .preview .duration{position:absolute;right:32px;top:16px;font-size:12px;color:#bdbdbd}.app .main-body .song-box .preview .total{position:absolute;right:32px;bottom:16px;font-size:16px;font-weight:bold;font-family:Raleway}.app .main-body .song-box .scroll-box{width:100%;height:269px;padding:16px 6px;border-top:1px solid rgba(32,32,32,0.1)}.app .main-body .song-box .list{height:237px;font-size:12px}.app .main-body .song-box .list .item{display:flex;align-items:center;height:26px;padding:0 12px;border-radius:13px}.app .main-body .song-box .list .item .idx{position:relative;width:64px;padding-left:16px;font-size:12px;font-family:Raleway}.app .main-body .song-box .list .item .name{overflow:hidden;flex:1}.app .main-body .song-box .list .item .artist{overflow:hidden;width:128px;margin-left:12px}.app .main-body .song-box .list .item .duration{width:42px;margin-left:12px}.app .main-body .song-box .list .item.on{color:#feac23;font-size:14px}.app .main-body .song-box .list .item.on .idx::before{position:absolute;left:0;top:3px;font-size:10px;content:"▶ "}.app .main-body .song-box .list .item.active,.app .main-body .song-box .list .item:hover{color:#58ffdf;background:rgba(29,77,68,0.15)}.app .play-bar{height:66px;width:100%;background:rgba(255,255,255,0.25);color:#fff}.app .play-bar .stat-bar{display:flex;align-items:center;justify-content:space-between;height:20px;color:#ebebeb}.app .play-bar .stat-bar .time{width:42px;margin:0 6px;text-align:center;font-size:12px}.app .play-bar .stat-bar .progress{flex:1;display:flex;align-items:flex-start;height:3px;background:#b2cfe3}.app .play-bar .stat-bar .thumb{width:8%;height:3px;background:#58ffdf}.app .play-bar .ctrl-box{display:flex;align-items:center;height:42px}.app .play-bar .ctrl-box .holder{flex:1}.app .play-bar .ctrl-box .info{display:flex;flex-direction:column;justify-content:center;width:320px;height:42px;padding-left:12px;line-height:1.25}.app .play-bar .ctrl-box .info strong{font-size:14px;font-weight:500}.app .play-bar .ctrl-box .info cite{font-size:12px;font-style:normal;color:#aeaeae}.app .play-bar .ctrl-box .play-btn{display:flex;align-items:center;justify-content:space-between;width:120px;height:42px;margin-left:32px}.app .play-bar .ctrl-box .play-btn .item{width:22px;height:22px;background-repeat:no-repeat;background-size:cover;transition:background .1s ease-in-out;cursor:pointer}.app .play-bar .ctrl-box .play-btn .item.prev{background-image:url(/images/ctrl/prev.png)}.app .play-bar .ctrl-box .play-btn .item.prev:hover,.app .play-bar .ctrl-box .play-btn .item.prev:active{background-image:url(/images/ctrl/prev_a.png)}.app .play-bar .ctrl-box .play-btn .item.on,.app .play-bar .ctrl-box .play-btn .item.off{width:42px;height:42px}.app .play-bar .ctrl-box .play-btn .item.on{background-image:url(/images/ctrl/play.png);-webkit-animation:round 2s linear infinite;animation:round 2s linear infinite}.app .play-bar .ctrl-box .play-btn .item.on:hover,.app .play-bar .ctrl-box .play-btn .item.on:active{background-image:url(/images/ctrl/play_a.png)}.app .play-bar .ctrl-box .play-btn .item.off{background-image:url(/images/ctrl/pause.png)}.app .play-bar .ctrl-box .play-btn .item.off:hover,.app .play-bar .ctrl-box .play-btn .item.off:active{background-image:url(/images/ctrl/pause_a.png)}.app .play-bar .ctrl-box .play-btn .item.next{background-image:url(/images/ctrl/next.png)}.app .play-bar .ctrl-box .play-btn .item.next:hover,.app .play-bar .ctrl-box .play-btn .item.next:active{background-image:url(/images/ctrl/next_a.png)}.app .play-bar .ctrl-box .play-action{display:flex;align-items:center;justify-content:space-between;width:64px;height:22px;margin-right:16px}.app .play-bar .ctrl-box .play-action .item{width:22px;height:22px;background-repeat:no-repeat;background-size:cover;transition:background .1s ease-in-out;cursor:pointer}.app .play-bar .ctrl-box .play-action .item.volume{background-image:url(/images/ctrl/volume.png)}.app .play-bar .ctrl-box .play-action .item.volume:hover,.app .play-bar .ctrl-box .play-action .item.volume:active{background-image:url(/images/ctrl/volume_a.png)}.app .play-bar .ctrl-box .play-action .item.mute{background-image:url(/images/ctrl/mute.png)}.app .play-bar .ctrl-box .play-action .item.mute:hover,.app .play-bar .ctrl-box .play-action .item.mute:active{background-image:url(/images/ctrl/mute_a.png)}.app .play-bar .ctrl-box .play-action .item.single{background-image:url(/images/ctrl/single.png)}.app .play-bar .ctrl-box .play-action .item.single:hover,.app .play-bar .ctrl-box .play-action .item.single:active{background-image:url(/images/ctrl/single_a.png)}.app .play-bar .ctrl-box .play-action .item.all{background-image:url(/images/ctrl/all.png)}.app .play-bar .ctrl-box .play-action .item.all:hover,.app .play-bar .ctrl-box .play-action .item.all:active{background-image:url(/images/ctrl/all_a.png)}.app .play-bar .ctrl-box .play-action .item.rand{background-image:url(/images/ctrl/rand.png)}.app .play-bar .ctrl-box .play-action .item.rand:hover,.app .play-bar .ctrl-box .play-action .item.rand:active{background-image:url(/images/ctrl/rand_a.png)}@-webkit-keyframes round{from{-webkit-transform:rotate(0);transform:rotate(0)}to{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes round{from{-webkit-transform:rotate(0);transform:rotate(0)}to{-webkit-transform:rotate(360deg);transform:rotate(360deg)}} diff --git a/src/css/app.scss b/src/css/app.scss index 766345b..a533977 100644 --- a/src/css/app.scss +++ b/src/css/app.scss @@ -12,7 +12,7 @@ position:relative; display:flex;flex-direction:column; width:100%;height:100%; - background:rgba(0, 0, 0, .2); + background:rgba(0, 0, 0, .3); // 标题栏样式 .title-bar { diff --git a/src/images/load1.png b/src/images/load1.png deleted file mode 100644 index eea26a7..0000000 Binary files a/src/images/load1.png and /dev/null differ diff --git a/src/images/load2.png b/src/images/load2.png deleted file mode 100755 index 43ea4d4..0000000 Binary files a/src/images/load2.png and /dev/null differ diff --git a/src/index.html b/src/index.html index 4fc8027..9786e79 100644 --- a/src/index.html +++ b/src/index.html @@ -53,71 +53,11 @@
-
- 01 - 情是何物 - 周深 - 04:23 -
-
- 02 - 情是何物 - 周深 - 04:23 -
-
- 03 - 情是何物 - 周深 - 04:23 -
-
- 04 - 情是何物 - 周深 - 04:23 -
-
- 05 - 情是何物 - 周深 - 04:23 -
-
- 06 - 情是何物 - 周深 - 04:23 -
-
- 07 - 情是何物 - 周深 - 04:23 -
-
- 08 - 情是何物 - 周深 - 04:23 -
-
- 09 - 情是何物 - 周深 - 04:23 -
-
- 10 - 情是何物 - 周深 - 04:23 -
-
- 11 - 情是何物 - 周深 - 04:23 +
+ + + +
diff --git a/src/js/app.js b/src/js/app.js index 4c4842f..ccdbb41 100644 --- a/src/js/app.js +++ b/src/js/app.js @@ -6,13 +6,23 @@ import Anot from '/js/lib/anot.js' import '/js/lib/scroll/index.js' +import app from '/js/lib/socket.js' + +// const {} from '' Anot({ $id: 'app', state: { isplaying: true, playmode: 1, - mute: false + mute: false, + list: [] + }, + mounted() { + var list = app.dispatch('scan-dir', { path: '/Volumes/extends/music' }) + + this.list = list + console.log(list) }, methods: { play() { diff --git a/src/js/lib/socket.js b/src/js/lib/socket.js new file mode 100644 index 0000000..e6dd883 --- /dev/null +++ b/src/js/lib/socket.js @@ -0,0 +1,13 @@ +/** + * 与主进程的通讯 + * @author yutent + * @date 2020/07/14 11:42:02 + */ + +const { ipcRenderer } = require('electron') + +export default { + dispatch(type = '', params = {}) { + return ipcRenderer.sendSync('app', Object.assign(params, { type })) + } +} diff --git a/src/main.js b/src/main.js index 26fffa4..92351f4 100644 --- a/src/main.js +++ b/src/main.js @@ -1,16 +1,19 @@ /** * 主入口 - * @author yutent - * @date 2019/12/13 00:37:04 + * @author yutent + * @date 2020/11/18 09:27:09 */ -'use strict' - const { app, session, protocol, globalShortcut } = require('electron') const path = require('path') const fs = require('iofs') -const { exec } = require('child_process') -const log = console.log +// const {exec} = require('child_process') + +require('./tools/init.js') +const { createAppTray, createLrcTray } = require('./tools/tray.js') +const createMenu = require('./tools/menu.js') +const { createMainWindow, createMiniWindow } = require('./tools/windows.js') + const MIME_TYPES = { '.js': 'text/javascript', '.html': 'text/html', @@ -23,14 +26,6 @@ const MIME_TYPES = { '.ico': 'image/ico' } -require('./tools/init') -const createTray = require('./tools/tray') -const createMenu = require('./tools/menu') - -const { createMainWindow, createErrorWindow } = require('./tools/windows') - -const ROOT = __dirname - /* ----------------------------------------------------- */ app.commandLine.appendSwitch('--lang', 'zh-CN') app.commandLine.appendSwitch('--autoplay-policy', 'no-user-gesture-required') @@ -47,7 +42,7 @@ app.once('ready', () => { protocol.registerBufferProtocol('app', (req, cb) => { let file = req.url.replace(/^app:\/\/local\//, '') let ext = path.extname(req.url) - let buff = fs.cat(path.resolve(ROOT, file)) + let buff = fs.cat(path.resolve(__dirname, file)) cb({ data: buff, mimeType: MIME_TYPES[ext] }) }) // 修改app的UA @@ -55,13 +50,12 @@ app.once('ready', () => { 'KugouMusic/2.9.5 (Mac OS X Version 10.15.7 (Build 19H2))' ) - let win = createMainWindow(path.resolve(ROOT, './images/app.png')) + let win = createMainWindow(path.resolve(__dirname, './images/app.png')) - createTray(win) + createAppTray(win) + createLrcTray(win) createMenu(win) - app.__MAIN__ = win - // mac专属事件,点击dock栏图标,可激活窗口 app.on('activate', _ => { if (win) { diff --git a/src/tools/db/index.js b/src/tools/db/index.js new file mode 100644 index 0000000..49e0a2f --- /dev/null +++ b/src/tools/db/index.js @@ -0,0 +1,63 @@ +/** + * + * @authors yutent (yutent.io@gmail.com) + * @date 2018-08-06 15:55:54 + */ + +Promise.defer = function() { + var obj = {} + obj.promise = new Promise((resolve, reject) => { + obj.resolve = resolve + obj.reject = reject + }) + return obj +} + +const sqlite3 = require('sqlite3').verbose() + +class Sqlite { + constructor(db) { + this.db = new sqlite3.Database(db) + } + + query(sql, ...param) { + let defer = Promise.defer() + param.unshift(sql) + param.push(err => { + if (err) { + return defer.reject(err) + } + defer.resolve(true) + }) + this.db.run.apply(this.db, param) + return defer.promise + } + + getAll(sql, ...param) { + let defer = Promise.defer() + param.unshift(sql) + param.push((err, row) => { + if (err) { + return defer.reject(err) + } + defer.resolve(row) + }) + this.db.all.apply(this.db, param) + return defer.promise + } + + get(sql, ...param) { + let defer = Promise.defer() + param.unshift(sql) + param.push((err, row) => { + if (err) { + return defer.reject(err) + } + defer.resolve(row) + }) + this.db.get.apply(this.db, param) + return defer.promise + } +} + +module.exports = Sqlite diff --git a/src/tools/db/init.js b/src/tools/db/init.js new file mode 100644 index 0000000..73fa4eb --- /dev/null +++ b/src/tools/db/init.js @@ -0,0 +1,53 @@ +/** + * 初始化数据库 + * @author yutent + * @date 2020/07/14 18:17:59 + */ + +const TABLE_PLAYLIST = ` +CREATE TABLE IF NOT EXISTS "playlist" ( + "id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, + "name" char(128) NOT NULL +) +` + +const TABLE_SONGS = ` +CREATE TABLE IF NOT EXISTS "songs" ( + "id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, + "pid" integer NOT NULL, + "aid" integer NOT NULL, + "name" char(128) NOT NULL, + "album" char(128) NOT NULL, + "cover" char(256) NOT NULL, + "lrc" text NOT NULL, +) +` +// 歌曲和播放列表的关系表(多对多) +const TABLE_RELATIONS = ` +CREATE TABLE IF NOT EXISTS "relations" ( + "id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, + "sid" integer NOT NULL, + "pid" integer NOT NULL, +) +` + +const TABLE_ARTISTS = ` +CREATE TABLE IF NOT EXISTS "artists" ( + "id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, + "name" integer NOT NULL, + "avatar" char(256) NOT NULL +) +` + +function error(err) { + console.log('----------------------------------------') + console.error(err) + console.log('----------------------------------------') +} + +module.exports = function(db) { + db.query(TABLE_PLAYLIST).catch(error) + db.query(TABLE_SONGS).catch(error) + db.query(TABLE_RELATIONS).catch(error) + db.query(TABLE_ARTISTS).catch(error) +} diff --git a/src/tools/init.js b/src/tools/init.js index e956a4a..490082e 100644 --- a/src/tools/init.js +++ b/src/tools/init.js @@ -4,12 +4,15 @@ * @date 2019/01/26 18:11:26 */ -'use strict' - const { app, ipcMain, globalShortcut: GS } = require('electron') const path = require('path') const fs = require('iofs') + const Shortcut = require('./shortcut') +const Sqlite = require('./db') +const dbinit = require('./db/init') + +const HOME = path.resolve(app.getPath('userData')) /* ********** 修复环境变量 start *********** */ let PATH_SET = new Set() @@ -24,105 +27,75 @@ PATH_SET = null /* ********** 修复环境变量 end *********** */ -const HOME = app.getPath('home') - -const APP_ROOT = path.resolve(HOME, '.sonist/') -const LRC_DIR = path.join(APP_ROOT, 'lyrics') -const CACHE_DIR = path.join(APP_ROOT, 'cache') -const INIT_FILE = path.join(APP_ROOT, 'app.ini') -const DB_FILE = path.join(APP_ROOT, 'music.db') -const TEMP_DB = path.join(APP_ROOT, 'temp.db') - -if (!fs.exists(APP_ROOT)) { - fs.mkdir(APP_ROOT) - fs.mkdir(LRC_DIR) - fs.mkdir(CACHE_DIR) - fs.echo('{}', INIT_FILE) - fs.echo('[]', TEMP_DB) - fs.echo('[]', DB_FILE) -} +const DB_FILE = path.join(HOME, 'sqlite3.cache') +const INIT_FILE = path.join(HOME, 'app.ini') +const CACHE_DIR = path.join(HOME, 'other_cache') const SUPPORTED_EXTS = ['.mp3', '.webm', '.ogg', '.flac', '.m4a', '.aac'] -const DB = { - read(file) { - let cache = (fs.cat(file) || '[]').toString('utf-8') - try { - return JSON.parse(cache) - } catch (err) { - return cache - } - }, - save(file, data) { - fs.echo(JSON.stringify(data), file) - } +var isFirstTimeLaunch = false +var db = null + +if (!fs.exists(DB_FILE)) { + fs.echo('{}', INIT_FILE) + fs.mkdir(CACHE_DIR) + isFirstTimeLaunch = true } + +db = new Sqlite(DB_FILE) + +if (isFirstTimeLaunch) { + dbinit(db) +} + /* ----------------------------------------------------------------- */ /* --------------------- 事件开始 ------------------------- */ /* ---------------------------------------------------------------- */ -ipcMain.on('sonist', (ev, conn) => { +ipcMain.on('app', (ev, conn) => { switch (conn.type) { + // 获取所有书籍 + case 'get-playlist': + db.getAll('SELECT * FROM `playlist`') + .then(res => { + ev.returnValue = res + }) + .catch(err => { + ev.returnValue = err + }) + break // 获取应用配置 case 'get-init': - ev.returnValue = DB.read(INIT_FILE) + var ini = fs.cat(INIT_FILE).toString('') + ev.returnValue = JSON.parse(ini) break // 设置应用配置 case 'set-init': - DB.save(INIT_FILE, conn.data) - break - // 获取音乐数据库 - case 'get-music': - ev.returnValue = DB.read(DB_FILE) - break - // 更新音乐数据库 - case 'set-music': - DB.save(DB_FILE, conn.data) - break - // 获取临时音乐数据库 - case 'get-temp': - ev.returnValue = DB.read(TEMP_DB) - break - // 更新临时音乐数据库 - case 'set-temp': - DB.save(TEMP_DB, conn.data) - break - // 读取歌词文件 - case 'read-lrc': - let lrc = path.join(LRC_DIR, `${conn.id}.lrc`) - if (fs.exists(lrc)) { - ev.returnValue = DB.read(lrc) - } else { - ev.returnValue = null - } - break - // 保存歌词文件 - case 'save-lrc': - fs.echo(conn.data, path.join(LRC_DIR, `${conn.id}.lrc`)) - break - // 保存音乐文件 - case 'save-cache': - let file = path.join(CACHE_DIR, conn.file) - fs.echo(conn.data, file) - ev.returnValue = `file://${file}` + fs.echo(JSON.stringify(conn.data, null, 2), INIT_FILE) break // 扫描目录 case 'scan-dir': if (fs.isdir(conn.path)) { - let list = fs.ls(conn.path, true).filter(_ => { - if (fs.isdir(_)) { - return false - } else { - let { ext, name } = path.parse(_) - if (!ext || name.startsWith('.')) { + let list = fs + .ls(conn.path, true) + .filter(it => { + if (fs.isdir(it)) { return false + } else { + let { ext, name } = path.parse(it) + if (!ext || name.startsWith('.')) { + return false + } + return SUPPORTED_EXTS.includes(ext) } - return SUPPORTED_EXTS.includes(ext) - } - }) + }) + .map(it => { + var { ext, name } = path.parse(it) + return { uuid: '', ext, name, path: it } + }) ev.returnValue = list } else { - ev.returnValue = null + ev.returnValue = [] } break diff --git a/src/tools/tray.js b/src/tools/tray.js index d04c944..e606daa 100644 --- a/src/tools/tray.js +++ b/src/tools/tray.js @@ -6,31 +6,44 @@ 'use strict' -const { app, Tray, Menu } = require('electron') +const { ipcMain, Tray, Menu, nativeImage } = require('electron') const path = require('path') -const ROOT = __dirname -module.exports = function(win) { - app.__TRAY__ = new Tray(path.join(ROOT, '../images/trays/trayTemplate.png')) - let menuList = Menu.buildFromTemplate([ - { - label: '显示主窗口', - click() { - win.webContents.send('dock-click') - } - }, - { type: 'separator' }, - { label: '退出', role: 'quit' } - ]) - - if (process.platform === 'darwin') { - app.__TRAY__.on('click', _ => { - win.webContents.send('dock-click') - }) - app.__TRAY__.on('right-click', _ => { - app.__TRAY__.popUpContextMenu(menuList) - }) - } else { - app.__TRAY__.setContextMenu(menuList) - } +function ctrlTrayBtn() { + var prev = new Tray(path.join(__dirname, '../images/ctrl/prev.png')) + var next = new Tray(path.join(__dirname, '../images/ctrl/next.png')) +} + +exports.createAppTray = function(win) { + var tray = new Tray(path.join(__dirname, '../images/trays/trayTemplate.png')) + tray.setIgnoreDoubleClickEvents(true) + // let menuList = Menu.buildFromTemplate([ + // { + // label: '显示主窗口', + // click() { + // win.webContents.send('dock-click') + // } + // }, + // { type: 'separator' }, + // { label: '退出', role: 'quit' } + // ]) + // if (process.platform === 'darwin') { + // tray.on('click', _ => { + // win.webContents.send('dock-click') + // }) + // tray.on('right-click', _ => { + // tray.popUpContextMenu(menuList) + // }) + // } else { + // tray.setContextMenu(menuList) + // } +} + +exports.createLrcTray = function(win) { + var nullImage = nativeImage.createEmpty() + var topbarLrc = new Tray(nullImage) + topbarLrc.setTitle('这是顶栏歌词, blablablabla...') + topbarLrc.setIgnoreDoubleClickEvents(true) + + // ctrlTrayBtn() } diff --git a/src/tools/windows.js b/src/tools/windows.js index 8901e04..676029e 100644 --- a/src/tools/windows.js +++ b/src/tools/windows.js @@ -4,8 +4,6 @@ * @date 2019/01/26 18:28:22 */ -'use strict' - const { BrowserWindow } = require('electron') /** @@ -45,55 +43,6 @@ exports.createMainWindow = function(icon) { return win } -/** - * 依赖异常显示窗口 - */ -exports.createErrorWindow = function() { - let win = new BrowserWindow({ - width: 600, - height: 360, - skipTaskbar: true, - maximizable: false, - minimizable: false, - resizable: false, - webPreferences: { - devTools: false - } - }) - win.setMenuBarVisibility(false) - win.loadURL('app://local/depends.html') - win.on('closed', _ => { - app.exit() - }) -} - -/** - * 桌面歌词窗口 - */ -exports.createDesktopLrcWindow = function(screen) { - let win = new BrowserWindow({ - title: '', - width: 1000, - height: 100, - frame: false, - resizable: false, - alwaysOnTop: true, - skipTaskbar: true, - x: (screen.width - 1024) / 2, - y: screen.height - 100, - transparent: true, - hasShadow: false, - thickFrame: false, - show: false, - webPreferences: { - nodeIntegration: true - } - }) - - win.loadURL('app://local/desktop-lrc.html') - return win -} - /** * 应用迷你窗口 */ @@ -108,9 +57,10 @@ exports.createMiniWindow = function(screen) { skipTaskbar: true, x: screen.width - 320, y: 0, - thickFrame: false, show: false, webPreferences: { + webSecurity: false, + experimentalFeatures: true, nodeIntegration: true } })