初始提交
This commit is contained in:
@@ -0,0 +1,14 @@
|
||||
// import api from 'api/connom'
|
||||
import { httpGet } from '../utils/request'
|
||||
import { author, name } from '../../../package.json'
|
||||
|
||||
export default {
|
||||
getVersionInfo() {
|
||||
return new Promise((resolve, reject) => {
|
||||
httpGet(`https://raw.githubusercontent.com/${author}/${name}/master/publish/version.json`, (err, resp, body) => {
|
||||
if (err) return reject(err)
|
||||
resolve(body)
|
||||
})
|
||||
})
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
import music from '../utils/music'
|
||||
|
||||
export default {
|
||||
theme(state) {
|
||||
return (state.themes[state.setting.themeId] && state.themes[state.setting.themeId].class) || ''
|
||||
},
|
||||
themes(state) {
|
||||
return {
|
||||
active: state.setting.themeId,
|
||||
list: state.themes,
|
||||
}
|
||||
},
|
||||
source(state) {
|
||||
return music.sources.find(s => s.id === state.setting.sourceId) || music.sources[0]
|
||||
},
|
||||
sources(state) {
|
||||
return {
|
||||
active: state.setting.sourceId,
|
||||
list: music.sources,
|
||||
}
|
||||
},
|
||||
userInfo(state) {
|
||||
return state.userInfo
|
||||
},
|
||||
setting(state) {
|
||||
return state.setting
|
||||
},
|
||||
electronStore(state) {
|
||||
return state.electronStore
|
||||
},
|
||||
version(state) {
|
||||
return state.version
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
import Vue from 'vue'
|
||||
import Vuex from 'vuex'
|
||||
// import { createPersistedState, createSharedMutations } from 'vuex-electron'
|
||||
|
||||
import defaultState from './state'
|
||||
import mutations from './mutations'
|
||||
import modules from './modules'
|
||||
import getters from './getters'
|
||||
import actions from './actions'
|
||||
|
||||
Vue.use(Vuex)
|
||||
|
||||
const isDev = process.env.NODE_ENV === 'development'
|
||||
|
||||
const store = new Vuex.Store({
|
||||
strict: isDev,
|
||||
state: defaultState,
|
||||
modules,
|
||||
mutations,
|
||||
getters,
|
||||
actions,
|
||||
// plugins: [createPersistedState(), createSharedMutations()],
|
||||
})
|
||||
|
||||
if (module.hot) {
|
||||
module.hot.accept([
|
||||
'./state',
|
||||
'./mutations',
|
||||
'./actions',
|
||||
'./getters',
|
||||
], () => {
|
||||
const newState = require('./state').default
|
||||
const newMutations = require('./mutations').default
|
||||
const newActions = require('./actions').default
|
||||
const newGetters = require('./getters').default
|
||||
|
||||
store.hotUpdate({
|
||||
state: newState,
|
||||
mutations: newMutations,
|
||||
getters: newGetters,
|
||||
actions: newActions,
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
export default store
|
||||
@@ -0,0 +1,274 @@
|
||||
import download from '../../utils/download'
|
||||
import fs from 'fs'
|
||||
import path from 'path'
|
||||
import music from '../../utils/music'
|
||||
|
||||
// state
|
||||
const state = {
|
||||
list: [],
|
||||
}
|
||||
|
||||
const dls = {}
|
||||
|
||||
// getters
|
||||
const getters = {
|
||||
list: state => state.list || [],
|
||||
dls: () => dls || {},
|
||||
}
|
||||
|
||||
const checkPath = path => {
|
||||
try {
|
||||
if (!fs.existsSync(path)) fs.mkdirSync(path, { recursive: true })
|
||||
} catch (error) {
|
||||
return error.message
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
const getExt = type => {
|
||||
switch (type) {
|
||||
case '128k':
|
||||
case '192k':
|
||||
case '320k':
|
||||
return 'mp3'
|
||||
case 'ape':
|
||||
return 'ape'
|
||||
case 'flac':
|
||||
return 'flac'
|
||||
}
|
||||
}
|
||||
|
||||
const checkList = (list, musicInfo, type) => list.some(s => s.musicInfo.songmid === musicInfo.songmid && s.type === type)
|
||||
|
||||
const refreshUrl = downloadInfo => {
|
||||
return music[downloadInfo.musicInfo.source].getMusicUrl(downloadInfo.musicInfo, downloadInfo.type)
|
||||
}
|
||||
|
||||
// actions
|
||||
const actions = {
|
||||
createDownload({ state, rootState }, { musicInfo, type }) {
|
||||
if (checkList(state.list, musicInfo, type)) return
|
||||
let ext = getExt(type)
|
||||
const downloadInfo = {
|
||||
isComplate: false,
|
||||
isDownloading: false,
|
||||
statusText: '任务初始化中',
|
||||
url: null,
|
||||
fileName: `${rootState.setting.download.fileName
|
||||
.replace('歌名', musicInfo.name)
|
||||
.replace('歌手', musicInfo.singer)}.${ext}`,
|
||||
progress: {
|
||||
downloaded: 0,
|
||||
total: 0,
|
||||
progress: 0,
|
||||
},
|
||||
type,
|
||||
ext,
|
||||
musicInfo,
|
||||
key: `${musicInfo.songmid}${ext}`,
|
||||
}
|
||||
downloadInfo.filePath = path.join(rootState.setting.download.savePath, downloadInfo.fileName)
|
||||
if (dls[downloadInfo.key]) {
|
||||
dls[downloadInfo.key].stop().finally(() => {
|
||||
this.dispatch('download/addTask', downloadInfo)
|
||||
})
|
||||
} else {
|
||||
// console.log(downloadInfo)
|
||||
this.dispatch('download/addTask', downloadInfo)
|
||||
}
|
||||
},
|
||||
addTask({ commit, rootState }, downloadInfo) {
|
||||
commit('addTask', downloadInfo)
|
||||
let msg = checkPath(rootState.setting.download.savePath)
|
||||
if (msg) return commit('setStatusText', '检查下载目录出错: ' + msg)
|
||||
const options = {
|
||||
url: downloadInfo.url,
|
||||
path: rootState.setting.download.savePath,
|
||||
fileName: downloadInfo.fileName,
|
||||
method: 'get',
|
||||
override: true,
|
||||
onEnd() {
|
||||
commit('onEnd', downloadInfo)
|
||||
console.log('on complate')
|
||||
},
|
||||
onError(err) {
|
||||
console.log(err)
|
||||
if (err.message.includes('Response status was')) {
|
||||
const code = err.message.replace(/Response status was (\d+)$/, '$1')
|
||||
switch (code) {
|
||||
case '401':
|
||||
case '403':
|
||||
case '410':
|
||||
commit('setStatusText', { downloadInfo, text: '链接失效,正在刷新链接' })
|
||||
refreshUrl(downloadInfo).then(result => {
|
||||
commit('updateUrl', { downloadInfo, url: result.url })
|
||||
commit('setStatusText', { downloadInfo, text: '链接刷新成功' })
|
||||
dls[downloadInfo.key].url = dls[downloadInfo.key].requestURL = result.url
|
||||
dls[downloadInfo.key].__initProtocol(result.url)
|
||||
dls[downloadInfo.key].resume()
|
||||
}).catch(err => {
|
||||
console.log(err)
|
||||
})
|
||||
return
|
||||
|
||||
default:
|
||||
break
|
||||
}
|
||||
}
|
||||
commit('onError', downloadInfo)
|
||||
},
|
||||
onStateChanged(state) {
|
||||
console.log(state)
|
||||
},
|
||||
onDownload() {
|
||||
commit('onDownload', downloadInfo)
|
||||
console.log('on download')
|
||||
},
|
||||
onProgress(status) {
|
||||
commit('onProgress', { downloadInfo, status })
|
||||
console.log(status)
|
||||
},
|
||||
onPause() {
|
||||
commit('pauseTask', downloadInfo)
|
||||
},
|
||||
onResume() {
|
||||
commit('resumeTask', downloadInfo)
|
||||
},
|
||||
}
|
||||
let p = options.url ? Promise.resolve() : refreshUrl(downloadInfo).then(result => {
|
||||
commit('updateUrl', { downloadInfo, url: result.url })
|
||||
options.url = result.url
|
||||
})
|
||||
p.then(() => {
|
||||
dls[downloadInfo.key] = download(options)
|
||||
})
|
||||
},
|
||||
removeTask({ commit, state }, index) {
|
||||
let info = state.list[index]
|
||||
if (state.list[index].isDownloading) {
|
||||
dls[info.key].stop().finally(() => {
|
||||
delete dls[info.key]
|
||||
})
|
||||
}
|
||||
commit('removeTask', index)
|
||||
if (dls[info.key]) delete dls[info.key]
|
||||
},
|
||||
resumeTask({ commit, rootState }, downloadInfo) {
|
||||
let msg = checkPath(rootState.setting.download.savePath)
|
||||
if (msg) return commit('setStatusText', '检查下载目录出错: ' + msg)
|
||||
const options = {
|
||||
url: downloadInfo.url,
|
||||
path: rootState.setting.download.savePath,
|
||||
fileName: downloadInfo.fileName,
|
||||
method: 'get',
|
||||
override: true,
|
||||
onEnd() {
|
||||
commit('onEnd', downloadInfo)
|
||||
console.log('on complate')
|
||||
},
|
||||
onError(err) {
|
||||
commit('onError', downloadInfo)
|
||||
commit('setStatusText', { downloadInfo, text: '链接失效,正在刷新链接' })
|
||||
refreshUrl(downloadInfo).then(result => {
|
||||
commit('updateUrl', { downloadInfo, url: result.url })
|
||||
commit('setStatusText', { downloadInfo, text: '链接刷新成功' })
|
||||
dls[downloadInfo.key].url = dls[downloadInfo.key].requestURL = result.url
|
||||
dls[downloadInfo.key].__initProtocol(result.url)
|
||||
dls[downloadInfo.key].resume()
|
||||
}).catch(err => {
|
||||
console.log(err)
|
||||
})
|
||||
console.log(err)
|
||||
},
|
||||
onStateChanged(state) {
|
||||
console.log(state)
|
||||
},
|
||||
onDownload() {
|
||||
commit('onDownload', downloadInfo)
|
||||
console.log('on download')
|
||||
},
|
||||
onProgress(status) {
|
||||
commit('onProgress', { downloadInfo, status })
|
||||
console.log(status)
|
||||
},
|
||||
onPause() {
|
||||
commit('pauseTask', downloadInfo)
|
||||
},
|
||||
onResume() {
|
||||
commit('resumeTask', downloadInfo)
|
||||
},
|
||||
}
|
||||
|
||||
let p = options.url ? Promise.resolve() : refreshUrl(downloadInfo).then(result => {
|
||||
commit('updateUrl', { downloadInfo, url: result.url })
|
||||
options.url = result.url
|
||||
})
|
||||
|
||||
if (fs.existsSync(downloadInfo.filePath)) {
|
||||
options.resumeInfo = {
|
||||
totalFileSize: downloadInfo.progress.total,
|
||||
}
|
||||
}
|
||||
p.then(() => {
|
||||
dls[downloadInfo.key] = download(options)
|
||||
})
|
||||
},
|
||||
}
|
||||
|
||||
// mitations
|
||||
const mutations = {
|
||||
addTask(state, downloadInfo) {
|
||||
state.list.push(downloadInfo)
|
||||
},
|
||||
removeTask(state, index) {
|
||||
state.list.splice(index, 1)
|
||||
},
|
||||
pauseTask(state, downloadInfo) {
|
||||
downloadInfo.isDownloading = false
|
||||
},
|
||||
resumeTask(state, downloadInfo) {
|
||||
downloadInfo.statusText = '恢复下载'
|
||||
},
|
||||
setStatusText(state, { downloadInfo, index, text }) {
|
||||
if (downloadInfo) {
|
||||
downloadInfo.statusText = text
|
||||
} else {
|
||||
state.list[index].statusText = text
|
||||
}
|
||||
},
|
||||
onEnd(state, downloadInfo) {
|
||||
downloadInfo.isComplate = true
|
||||
downloadInfo.isDownloading = false
|
||||
downloadInfo.statusText = '下载完成'
|
||||
},
|
||||
onError(state, downloadInfo) {
|
||||
downloadInfo.isDownloading = false
|
||||
downloadInfo.statusText = '任务出错'
|
||||
},
|
||||
onDownload(state, downloadInfo) {
|
||||
downloadInfo.isDownloading = true
|
||||
downloadInfo.statusText = '正在下载'
|
||||
},
|
||||
onProgress(state, { downloadInfo, status }) {
|
||||
downloadInfo.progress.progress = status.progress
|
||||
downloadInfo.progress.downloaded = status.downloaded
|
||||
downloadInfo.progress.total = status.total
|
||||
},
|
||||
setTotal(state, { order, downloadInfo }) {
|
||||
downloadInfo.order = order
|
||||
},
|
||||
updateDownloadList(state, list) {
|
||||
state.list = list
|
||||
},
|
||||
updateUrl(state, { downloadInfo, url }) {
|
||||
downloadInfo.url = url
|
||||
},
|
||||
}
|
||||
|
||||
export default {
|
||||
namespaced: true,
|
||||
state,
|
||||
getters,
|
||||
actions,
|
||||
mutations,
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
// https://vuex.vuejs.org/en/modules.html
|
||||
|
||||
const requireModule = require.context('./', true, /\.js$/)
|
||||
const modules = {}
|
||||
|
||||
requireModule.keys().forEach(fileName => {
|
||||
if (fileName === './index.js') return
|
||||
const path = fileName.replace(/(\.\/|\.js)/g, '')
|
||||
|
||||
if (/\//.test(path)) {
|
||||
// Replace ./ and .js
|
||||
const [moduleName, imported] = path.split('/')
|
||||
|
||||
if (!modules[moduleName]) {
|
||||
modules[moduleName] = {
|
||||
namespaced: true,
|
||||
}
|
||||
}
|
||||
|
||||
modules[moduleName][imported] = requireModule(fileName).default
|
||||
} else {
|
||||
modules[path] = requireModule(fileName).default
|
||||
}
|
||||
})
|
||||
|
||||
export default modules
|
||||
@@ -0,0 +1,63 @@
|
||||
import music from '../../utils/music'
|
||||
const sourceList = {}
|
||||
const sources = []
|
||||
for (const source of music.sources) {
|
||||
const leaderboard = music[source.id].leaderboard
|
||||
if (!leaderboard) continue
|
||||
sourceList[source.id] = leaderboard.list
|
||||
sources.push(source)
|
||||
}
|
||||
|
||||
// state
|
||||
const state = {
|
||||
list: [],
|
||||
total: 0,
|
||||
page: 1,
|
||||
limit: 30,
|
||||
key: null,
|
||||
}
|
||||
|
||||
// getters
|
||||
const getters = {
|
||||
sourceInfo: () => ({ sources, sourceList }),
|
||||
list(state) {
|
||||
return state.list
|
||||
},
|
||||
info(state) {
|
||||
return {
|
||||
total: state.total,
|
||||
limit: state.limit,
|
||||
page: state.page,
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
// actions
|
||||
const actions = {
|
||||
getList({ state, rootState, commit }, page) {
|
||||
let source = rootState.setting.leaderboard.source
|
||||
let tabId = rootState.setting.leaderboard.tabId
|
||||
let key = `${source}${tabId}${page}}`
|
||||
if (state.list.length && state.key == key) return true
|
||||
return music[source].leaderboard.getList(tabId, page).then(result => commit('setList', { result, key }))
|
||||
},
|
||||
}
|
||||
|
||||
// mitations
|
||||
const mutations = {
|
||||
setList(state, { result, key }) {
|
||||
state.list = result.list
|
||||
state.total = result.total
|
||||
state.limit = result.limit
|
||||
state.page = result.page
|
||||
state.key = key
|
||||
},
|
||||
}
|
||||
|
||||
export default {
|
||||
namespaced: true,
|
||||
state,
|
||||
getters,
|
||||
actions,
|
||||
mutations,
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
// state
|
||||
const state = {
|
||||
defaultList: {
|
||||
name: '试听列表',
|
||||
list: [],
|
||||
},
|
||||
userList: [],
|
||||
}
|
||||
|
||||
// getters
|
||||
const getters = {
|
||||
defaultList: state => state.defaultList || {},
|
||||
userList: state => state.userList,
|
||||
}
|
||||
|
||||
// actions
|
||||
const actions = {
|
||||
|
||||
}
|
||||
|
||||
// mitations
|
||||
const mutations = {
|
||||
initDefaultList(state, data) {
|
||||
state.defaultList = data
|
||||
},
|
||||
setDefaultList(state, list) {
|
||||
state.defaultList.list = list
|
||||
},
|
||||
defaultListAdd(state, musicInfo) {
|
||||
if (state.defaultList.list.some(s => s.songmid === musicInfo.songmid)) return
|
||||
state.defaultList.list.push(musicInfo)
|
||||
},
|
||||
defaultListRemove(state, index) {
|
||||
state.defaultList.list.splice(index, 1)
|
||||
},
|
||||
defaultListClear(state) {
|
||||
state.defaultList.list.length = 0
|
||||
},
|
||||
}
|
||||
|
||||
export default {
|
||||
namespaced: true,
|
||||
state,
|
||||
getters,
|
||||
actions,
|
||||
mutations,
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
import music from '../../utils/music'
|
||||
|
||||
// state
|
||||
const state = {
|
||||
list: [],
|
||||
listId: null,
|
||||
playIndex: -1,
|
||||
changePlay: false,
|
||||
}
|
||||
|
||||
// getters
|
||||
const getters = {
|
||||
list: state => state.list || [],
|
||||
listId: state => state.listId,
|
||||
changePlay: satte => satte.changePlay,
|
||||
playIndex: state => state.playIndex,
|
||||
}
|
||||
|
||||
// actions
|
||||
const actions = {
|
||||
getUrl({ commit, state }, { musicInfo, type }) {
|
||||
return music[musicInfo.source].getMusicUrl(musicInfo, type).then(result => commit('setUrl', { musicInfo, url: result.url, type }))
|
||||
},
|
||||
getPic({ commit, state }, musicInfo) {
|
||||
return music[musicInfo.source].getPic(musicInfo).then(url => commit('getPic', { musicInfo, url }))
|
||||
},
|
||||
getLrc({ commit, state }, musicInfo) {
|
||||
return music[musicInfo.source].getLyric(musicInfo).then(lrc => commit('setLrc', { musicInfo, lrc }))
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
// mitations
|
||||
const mutations = {
|
||||
setUrl(state, datas) {
|
||||
datas.musicInfo.typeUrl[datas.type] = datas.url
|
||||
},
|
||||
getPic(state, datas) {
|
||||
datas.musicInfo.img = datas.url
|
||||
},
|
||||
setLrc(state, datas) {
|
||||
datas.musicInfo.lyric = datas.lrc
|
||||
},
|
||||
setList(state, { list, listId, index }) {
|
||||
state.list = list
|
||||
state.listId = listId
|
||||
state.playIndex = index
|
||||
state.changePlay = true
|
||||
},
|
||||
setPlayIndex(state, index) {
|
||||
state.playIndex = index
|
||||
state.changePlay = true
|
||||
},
|
||||
fixPlayIndex(state, index) {
|
||||
state.playIndex = index
|
||||
},
|
||||
resetChangePlay(state) {
|
||||
state.changePlay = false
|
||||
},
|
||||
}
|
||||
|
||||
export default {
|
||||
namespaced: true,
|
||||
state,
|
||||
getters,
|
||||
actions,
|
||||
mutations,
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
import music from '../../utils/music'
|
||||
|
||||
// state
|
||||
const state = {
|
||||
list: [],
|
||||
text: '',
|
||||
page: 1,
|
||||
limit: 30,
|
||||
allPage: 1,
|
||||
total: 0,
|
||||
}
|
||||
|
||||
// getters
|
||||
const getters = {
|
||||
list: state => state.list || [],
|
||||
limit: state => state.limit,
|
||||
info: state => ({ page: state.page, text: state.text }),
|
||||
listInfo: state => ({ allPage: state.allPage, total: state.total }),
|
||||
}
|
||||
|
||||
// actions
|
||||
const actions = {
|
||||
search({ commit, rootState }, { text, page, limit }) {
|
||||
return music[rootState.setting.sourceId].musicSearch.search(text, page, limit)
|
||||
.then(data => commit('setList', { list: data.list, allPage: data.allPage, total: data.total, text, page }))
|
||||
},
|
||||
}
|
||||
|
||||
// mitations
|
||||
const mutations = {
|
||||
setList(state, datas) {
|
||||
state.list = datas.list
|
||||
state.total = datas.total
|
||||
state.allPage = datas.allPage
|
||||
state.page = datas.page
|
||||
state.text = datas.text
|
||||
},
|
||||
clearList(state) {
|
||||
state.list.length = 0
|
||||
state.page = 0
|
||||
state.allPage = 0
|
||||
state.total = 0
|
||||
state.text = ''
|
||||
},
|
||||
}
|
||||
|
||||
export default {
|
||||
namespaced: true,
|
||||
state,
|
||||
getters,
|
||||
actions,
|
||||
mutations,
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
export default {
|
||||
setTheme(state, val) {
|
||||
state.setting.themeId = val
|
||||
},
|
||||
setSource(state, val) {
|
||||
state.setting.sourceId = val
|
||||
},
|
||||
setSetting(state, val) {
|
||||
state.setting = val
|
||||
},
|
||||
setLeaderboard(state, { tabId, source }) {
|
||||
if (tabId != null) state.setting.leaderboard.tabId = tabId
|
||||
if (source != null) state.setting.leaderboard.source = source
|
||||
},
|
||||
setNewVersion(state, val) {
|
||||
val.history.forEach(ver => {
|
||||
ver.desc = ver.desc.replace(/\n/g, '<br>')
|
||||
})
|
||||
val.desc = val.desc.replace(/\n/g, '<br>')
|
||||
state.version.newVersion = val
|
||||
},
|
||||
setVersionVisible(state, val) {
|
||||
state.version.showModal = val
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
|
||||
// const isDev = process.env.NODE_ENV === 'development'
|
||||
import Store from 'electron-store'
|
||||
import { updateSetting } from '../utils'
|
||||
import { version } from '../../../package.json'
|
||||
let electronStore = new Store()
|
||||
const setting = updateSetting(electronStore.get('setting'))
|
||||
electronStore.set('setting', setting)
|
||||
|
||||
export default {
|
||||
themes: [
|
||||
{
|
||||
id: 0,
|
||||
name: '绿意盎然',
|
||||
class: 'green',
|
||||
},
|
||||
{
|
||||
id: 1,
|
||||
name: '蓝田生玉',
|
||||
class: 'blue',
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
name: '信口雌黄',
|
||||
class: 'yellow',
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
name: '橙黄橘绿',
|
||||
class: 'orange',
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
name: '热情似火',
|
||||
class: 'red',
|
||||
},
|
||||
{
|
||||
id: 5,
|
||||
name: '重斤球紫',
|
||||
class: 'purple',
|
||||
},
|
||||
{
|
||||
id: 6,
|
||||
name: '灰常美丽',
|
||||
class: 'grey',
|
||||
},
|
||||
],
|
||||
version: {
|
||||
version,
|
||||
newVersion: null,
|
||||
showModal: false,
|
||||
},
|
||||
userInfo: null,
|
||||
setting,
|
||||
electronStore,
|
||||
}
|
||||
Reference in New Issue
Block a user