初始提交

This commit is contained in:
lyswhut
2019-08-16 17:27:23 +08:00
parent 4dc34a48f4
commit 14f7bd10a3
112 changed files with 24294 additions and 2 deletions
+153
View File
@@ -0,0 +1,153 @@
<template lang="pug">
div(:class="$style.download")
//- transition
div(:class="$style.content" v-if="list.length")
div(:class="$style.thead")
table
thead
tr
th.nobreak(style="width: 30%;") 歌曲名
th.nobreak(style="width: 25%;") 进度
th.nobreak(style="width: 15%;") 状态
th.nobreak(style="width: 10%;") 品质
th.nobreak(style="width: 20%;") 操作
div.scroll(v-if="list.length" :class="$style.tbody")
table
tbody
tr(v-for='(item, index) in list' :key='item.key' @click="handleDoubleClick(index)" :class="isPlayList && playIndex === index ? $style.active : ''")
td.break(style="width: 30%;") {{item.musicInfo.name}} - {{item.musicInfo.singer}}
td.break(style="width: 25%;") {{item.progress.progress}}%
td.break(style="width: 15%;") {{item.statusText}}
td.break(style="width: 10%;") {{item.type.toUpperCase()}}
td(style="width: 20%; padding-left: 0; padding-right: 0;")
material-list-buttons(:index="index" :downloadBtn="false" @btn-click="handleBtnClick")
div(:class="$style.noItem" v-else)
</template>
<script>
import { mapGetters, mapActions, mapMutations } from 'vuex'
import { checkPath } from '../utils'
export default {
name: 'Download',
data() {
return {
clickTime: window.performance.now(),
clickIndex: -1,
}
},
computed: {
...mapGetters('download', ['list', 'dls']),
...mapGetters('player', ['listId', 'playIndex']),
isPlayList() {
return this.listId == 'download'
},
},
methods: {
...mapActions('download', ['removeTask', 'resumeTask']),
...mapMutations('player', ['setList']),
pauseTask(index) {
let info = this.list[index]
this.dls[info.key].pause()
},
startTask(index) {
let info = this.list[index]
let dl = this.dls[info.key]
dl ? dl.resume() : this.resumeTask(info)
},
handleDoubleClick(index) {
if (
window.performance.now() - this.clickTime > 400 ||
this.clickIndex !== index
) {
this.clickTime = window.performance.now()
this.clickIndex = index
return
}
this.handleClick(index)
this.clickTime = 0
this.clickIndex = -1
},
handleClick(index) {
let info = this.list[index]
if (info.isComplate) {
this.handlePlay(index)
} else if (info.isDownloading) {
this.pauseTask(index)
} else {
this.startTask(index)
}
},
handlePlay(index) {
if (!checkPath(this.list[index].filePath)) return
this.setList({ list: this.list, listId: 'download', index })
},
handleBtnClick(info) {
switch (info.action) {
case 'play':
this.handlePlay(info.index)
break
case 'remove':
this.removeTask(info.index)
break
}
},
},
}
</script>
<style lang="less" module>
@import '../assets/styles/layout.less';
.download {
overflow: hidden;
height: 100%;
// .noItem {
// }
}
.content {
height: 100%;
font-size: 14px;
display: flex;
flex-flow: column nowrap;
// table {
// position: relative;
// thead {
// position: fixed;
// width: 100%;
// th {
// width: 100%;
// }
// }
// }
}
.thead {
flex: none;
}
.tbody {
flex: auto;
overflow-y: auto;
td {
font-size: 12px;
}
tr {
&.active {
color: @color-theme;
}
}
}
each(@themes, {
:global(#container.@{value}) {
.tbody {
tr {
&.active {
color: ~'@{color-@{value}-theme}';
}
}
}
}
})
</style>
+228
View File
@@ -0,0 +1,228 @@
<template lang="pug">
div(:class="$style.leaderboard")
div(:class="$style.header")
material-tab(:class="$style.tab" :list="types" item-key="id" item-name="name" v-model="tabId")
material-select(:class="$style.select" :list="sourceInfo.sources" item-key="id" item-name="name" v-model="source")
div(:class="$style.content")
div(v-if="list.length" :class="$style.list")
div(:class="$style.thead")
table
thead
tr
th.nobreak(style="width: 27%;") 歌曲名
th.nobreak(style="width: 20%;") 歌手
th.nobreak(style="width: 25%;") 专辑
th.nobreak(style="width: 18%;") 操作
th.nobreak(style="width: 10%;") 时长
div.scroll(:class="$style.tbody" ref="dom_scrollContent")
table
tbody
tr(v-for='(item, index) in list' :key='item.songmid' @click="handleDoubleClick(index)")
td.break(style="width: 27%;")
| {{item.name}}
//- span.badge.badge-info(v-if="item._types['320k']") 高品质
//- span.badge.badge-success(v-if="item._types.ape || item._types.flac") 无损
td.break(style="width: 20%;") {{item.singer}}
td.break(style="width: 25%;") {{item.albumName}}
td(style="width: 18%;")
material-list-buttons(:index="index" :search-btn="true" :play-btn="item.source == 'kw'" :download-btn="item.source == 'kw'" :remove-btn="false" @btn-click="handleBtnClick")
//- button.btn-info(type='button' v-if="item._types['128k'] || item._types['192k'] || item._types['320k'] || item._types.flac" @click.stop='openDownloadModal(index)') 下载
//- button.btn-secondary(type='button' v-if="item._types['128k'] || item._types['192k'] || item._types['320k']" @click.stop='testPlay(index)') 试听
//- button.btn-success(type='button' v-if="(item._types['128k'] || item._types['192k'] || item._types['320k']) && userInfo" @click.stop='showListModal(index)') +
td(style="width: 10%;") {{item.interval}}
div(:class="$style.pagination")
material-pagination(:count="info.total" :limit="info.limit" :page="info.page" @btn-click="handleTogglePage")
material-download-modal(:show="showDownload" :musicInfo="musicInfo" @select="handleAddDownload" @close="showDownload = false")
</template>
<script>
import { mapGetters, mapMutations, mapActions } from 'vuex'
import { scrollTo } from '../utils'
// import music from '../utils/music'
export default {
name: 'Leaderboard',
data() {
return {
tabId: null,
source: null,
page: 1,
clickTime: 0,
clickIndex: -1,
showDownload: false,
musicInfo: null,
}
},
computed: {
...mapGetters(['setting']),
...mapGetters('leaderboard', ['sourceInfo', 'list', 'info']),
...mapGetters('list', ['defaultList']),
types() {
return this.source ? this.sourceInfo.sourceList[this.source] : []
},
},
watch: {
tabId(n, o) {
this.setLeaderboard({ tabId: n })
if (!o && this.page !== 1) return
this.getList(1).then(() => {
this.page = this.info.page
scrollTo(this.$refs.dom_scrollContent, 0)
})
},
source(n, o) {
this.setLeaderboard({ source: n })
if (o) this.tabId = this.types[0] && this.types[0].id
},
},
mounted() {
this.source = this.setting.leaderboard.source
this.tabId = this.setting.leaderboard.tabId
this.page = this.info.page
},
methods: {
...mapMutations(['setLeaderboard']),
...mapActions('leaderboard', ['getList']),
...mapActions('download', ['createDownload']),
...mapMutations('list', ['defaultListAdd']),
...mapMutations('player', ['setList']),
handleDoubleClick(index) {
if (
window.performance.now() - this.clickTime > 400 ||
this.clickIndex !== index
) {
this.clickTime = window.performance.now()
this.clickIndex = index
return
}
this.source == 'kw' ? this.testPlay(index) : this.handleSearch(index)
this.clickTime = 0
this.clickIndex = -1
},
handleBtnClick(info) {
switch (info.action) {
case 'download':
this.musicInfo = this.list[info.index]
this.$nextTick(() => {
this.showDownload = true
})
break
case 'play':
this.testPlay(info.index)
break
case 'search':
this.handleSearch(info.index)
break
// case 'add':
// break
}
},
testPlay(index) {
let targetSong = this.list[index]
this.defaultListAdd(targetSong)
let targetIndex = this.defaultList.list.findIndex(
s => s.songmid === targetSong.songmid
)
if (targetIndex > -1) {
this.setList({
list: this.defaultList.list,
listId: 'test',
index: targetIndex,
})
}
},
handleSearch(index) {
const info = this.list[index]
this.$router.push({
path: 'search',
query: {
text: `${info.name} - ${info.singer}`,
},
})
},
handleTogglePage(page) {
this.getList(page).then(() => {
this.page = this.info.page
this.$nextTick(() => {
scrollTo(this.$refs.dom_scrollContent, 0)
})
})
},
handleAddDownload(type) {
this.createDownload({ musicInfo: this.musicInfo, type })
this.showDownload = false
},
},
}
</script>
<style lang="less" module>
@import '../assets/styles/layout.less';
.leaderboard {
height: 100%;
display: flex;
flex-flow: column nowrap;
}
.header {
flex: none;
width: 100%;
display: flex;
flex-flow: row nowrap;
}
.tab {
flex: auto;
}
.select {
flex: none;
width: 80px;
}
.content {
flex: auto;
display: flex;
overflow: hidden;
flex-flow: column nowrap;
}
.list {
position: relative;
height: 100%;
font-size: 14px;
display: flex;
flex-flow: column nowrap;
// table {
// position: relative;
// thead {
// position: fixed;
// width: 100%;
// th {
// width: 100%;
// }
// }
// }
}
.thead {
flex: none;
}
.tbody {
flex: auto;
overflow-y: auto;
td {
font-size: 12px;
:global(.badge) {
margin-right: 3px;
&:first-child {
margin-left: 3px;
}
&:last-child {
margin-right: 0;
}
}
}
}
.pagination {
text-align: center;
padding: 15px 0;
// left: 50%;
// transform: translateX(-50%);
}
</style>
+192
View File
@@ -0,0 +1,192 @@
<template lang="pug">
div(:class="$style.list")
//- transition
div(v-if="list.length" :class="$style.content")
div(:class="$style.thead")
table
thead
tr
th.nobreak(style="width: 25%;") 歌曲名
th.nobreak(style="width: 20%;") 歌手
th.nobreak(style="width: 25%;" v-if="setting.list.isShowAlbumName") 专辑
th.nobreak(style="width: 20%;") 操作
th.nobreak(style="width: 10%;") 时长
div.scroll(:class="$style.tbody")
table
tbody
tr(v-for='(item, index) in list' :key='item.songmid' @click="handleDoubleClick(index)" :class="isPlayList && playIndex === index ? $style.active : ''")
td.break(style="width: 25%;") {{item.name}}
//- span.badge.badge-light(v-if="item._types['128k']") 128K
//- span.badge.badge-light(v-if="item._types['192k']") 192K
//- span.badge.badge-secondary(v-if="item._types['320k']") 320K
//- span.badge.badge-info(v-if="item._types.ape") APE
//- span.badge.badge-success(v-if="item._types.flac") FLAC
td.break(style="width: 20%;") {{item.singer}}
td.break(style="width: 25%;" v-if="setting.list.isShowAlbumName") {{item.albumName}}
td(style="width: 20%; padding-left: 0; padding-right: 0;")
material-list-buttons(:index="index" @btn-click="handleBtnClick")
//- button.btn-info(type='button' v-if="item._types['128k'] || item._types['192k'] || item._types['320k'] || item._types.flac" @click.stop='openDownloadModal(index)') 下载
//- button.btn-secondary(type='button' v-if="item._types['128k'] || item._types['192k'] || item._types['320k']" @click.stop='testPlay(index)') 试听
//- button.btn-secondary(type='button' @click.stop='handleRemove(index)') 删除
//- button.btn-success(type='button' v-if="(item._types['128k'] || item._types['192k'] || item._types['320k']) && userInfo" @click.stop='showListModal(index)') +
td(style="width: 10%;") {{item.interval}}
div(:class="$style.noItem" v-else)
material-download-modal(:show="showDownload" :musicInfo="musicInfo" @select="handleAddDownload" @close="showDownload = false")
</template>
<script>
import { mapMutations, mapGetters, mapActions } from 'vuex'
export default {
name: 'List',
data() {
return {
clickTime: window.performance.now(),
clickIndex: -1,
showDownload: false,
musicInfo: null,
}
},
computed: {
...mapGetters(['userInfo', 'setting']),
...mapGetters('list', ['defaultList', 'userList']),
...mapGetters('player', ['listId', 'playIndex']),
isPlayList() {
return this.listId != 'download' && (
((!this.$route.query.id || this.$route.query.id == 'test') && this.listId == 'test') ||
this.$route.query.id == this.listId
)
},
list() {
return !this.$route.query.id || this.$route.query.id == 'test'
? this.defaultList.list
: this.userList.find(l => l._id == this.$route.query.id) || []
},
},
// beforeRouteUpdate(to, from, next) {
// // if (to.query.id === undefined) return
// // if (to.query.text === '') {
// // this.clearList()
// // } else {
// // this.text = to.query.text
// // this.page = 1
// // this.handleSearch(this.text, this.page)
// // }
// next()
// },
// mounted() {
// console.log('mounted')
// if (this.$route.query.text === undefined) {
// let info = this.$store.getters['search/info']
// this.text = info.text
// this.page = info.page
// } else if (this.$route.query.text === '') {
// this.clearList()
// } else {
// this.text = this.$route.query.text
// this.page = 1
// this.handleSearch(this.text, this.page)
// }
// },
methods: {
...mapMutations('list', ['defaultListRemove']),
...mapMutations('player', ['setList']),
...mapActions('download', ['createDownload']),
handleDoubleClick(index) {
if (
window.performance.now() - this.clickTime > 400 ||
this.clickIndex !== index
) {
this.clickTime = window.performance.now()
this.clickIndex = index
return
}
this.testPlay(index)
this.clickTime = 0
this.clickIndex = -1
},
testPlay(index) {
this.setList({ list: this.list, listId: 'test', index })
},
handleRemove(index) {
this.defaultListRemove(index)
},
handleBtnClick(info) {
switch (info.action) {
case 'download':
this.musicInfo = this.list[info.index]
this.$nextTick(() => {
this.showDownload = true
})
break
case 'play':
this.testPlay(info.index)
break
case 'add':
break
case 'remove':
this.handleRemove(info.index)
break
}
},
handleAddDownload(type) {
this.createDownload({ musicInfo: this.musicInfo, type })
this.showDownload = false
},
},
}
</script>
<style lang="less" module>
@import '../assets/styles/layout.less';
.list {
overflow: hidden;
height: 100%;
// .noItem {
// }
}
.content {
height: 100%;
font-size: 14px;
display: flex;
flex-flow: column nowrap;
// table {
// position: relative;
// thead {
// position: fixed;
// width: 100%;
// th {
// width: 100%;
// }
// }
// }
}
.thead {
flex: none;
}
.tbody {
flex: auto;
overflow-y: auto;
td {
font-size: 12px;
}
tr {
&.active {
color: @color-theme;
}
}
}
each(@themes, {
:global(#container.@{value}) {
.tbody {
tr {
&.active {
color: ~'@{color-@{value}-theme}';
}
}
}
}
})
</style>
+20
View File
@@ -0,0 +1,20 @@
<template lang="pug">
div
h2 推荐
</template>
<script>
export default {
name: 'About',
data() {
return {
count: 0,
}
},
methods: {
add() {
this.count++
},
},
}
</script>
+189
View File
@@ -0,0 +1,189 @@
<template lang="pug">
div(:class="$style.search")
//- transition
div(v-if="list.length" :class="$style.list")
div(:class="$style.thead")
table
thead
tr
th.nobreak(style="width: 30%;") 歌曲名
th.nobreak(style="width: 20%;") 歌手
th.nobreak(style="width: 25%;") 专辑
th.nobreak(style="width: 15%;") 操作
th.nobreak(style="width: 10%;") 时长
div.scroll(:class="$style.tbody" ref="dom_scrollContent")
table
tbody
tr(v-for='(item, index) in list' :key='item.songmid' @click="handleDoubleClick(index)")
td.break(style="width: 30%;")
| {{item.name}}
span.badge.badge-info(v-if="item._types['320k']") 高品质
span.badge.badge-success(v-if="item._types.ape || item._types.flac") 无损
td.break(style="width: 20%;") {{item.singer}}
td.break(style="width: 25%;") {{item.albumName}}
td(style="width: 15%;")
material-list-buttons(:index="index" :remove-btn="false" @btn-click="handleBtnClick")
td(style="width: 10%;") {{item.interval}}
div(:class="$style.pagination")
material-pagination(:count="listInfo.total" :limit="limit" :page="page" @btn-click="handleTogglePage")
div(v-else :class="$style.noItem")
material-download-modal(:show="showDownload" :musicInfo="musicInfo" @select="handleAddDownload" @close="showDownload = false")
</template>
<script>
import { mapGetters, mapActions, mapMutations } from 'vuex'
import { scrollTo } from '../utils'
// import music from '../utils/music'
export default {
name: 'Search',
data() {
return {
page: 0,
text: '',
clickTime: 0,
clickIndex: -1,
showDownload: false,
musicInfo: null,
}
},
beforeRouteUpdate(to, from, next) {
if (to.query.text === undefined) return
if (to.query.text === '') {
this.clearList()
} else {
this.text = to.query.text
this.page = 1
this.handleSearch(this.text, this.page)
}
next()
},
mounted() {
// console.log('mounted')
if (this.$route.query.text === undefined) {
let info = this.$store.getters['search/info']
this.text = info.text
this.page = info.page
} else if (this.$route.query.text === '') {
this.clearList()
} else {
this.text = this.$route.query.text
this.page = 1
this.handleSearch(this.text, this.page)
}
},
computed: {
...mapGetters(['userInfo']),
...mapGetters('search', ['list', 'limit', 'listInfo']),
...mapGetters('list', ['defaultList']),
},
methods: {
...mapActions('search', ['search']),
...mapActions('download', ['createDownload']),
...mapMutations('search', ['clearList', 'setPage']),
...mapMutations('list', ['defaultListAdd']),
...mapMutations('player', ['setList']),
handleSearch(text, page) {
this.search({ text, page, limit: this.limit }).then(data => {
this.page = page
this.$nextTick(() => {
scrollTo(this.$refs.dom_scrollContent, 0)
})
})
},
handleDoubleClick(index) {
if (
window.performance.now() - this.clickTime > 400 ||
this.clickIndex !== index
) {
this.clickTime = window.performance.now()
this.clickIndex = index
return
}
this.testPlay(index)
this.clickTime = 0
this.clickIndex = -1
},
handleBtnClick(info) {
switch (info.action) {
case 'download':
this.musicInfo = this.list[info.index]
this.$nextTick(() => {
this.showDownload = true
})
break
case 'play':
this.testPlay(info.index)
break
case 'add':
break
}
},
openDownloadModal() {},
testPlay(index) {
let targetSong = this.list[index]
this.defaultListAdd(targetSong)
let targetIndex = this.defaultList.list.findIndex(
s => s.songmid === targetSong.songmid
)
if (targetIndex > -1) {
this.setList({
list: this.defaultList.list,
listId: 'test',
index: targetIndex,
})
}
},
handleTogglePage(page) {
this.handleSearch(this.text, page)
},
handleAddDownload(type) {
this.createDownload({ musicInfo: this.musicInfo, type })
this.showDownload = false
},
},
}
</script>
<style lang="less" module>
@import '../assets/styles/layout.less';
.search {
overflow: hidden;
height: 100%;
}
.list {
position: relative;
height: 100%;
font-size: 14px;
display: flex;
flex-flow: column nowrap;
}
.thead {
flex: none;
}
.tbody {
flex: auto;
overflow-y: auto;
td {
font-size: 12px;
:global(.badge) {
margin-right: 3px;
&:first-child {
margin-left: 3px;
}
&:last-child {
margin-right: 0;
}
}
}
}
.pagination {
text-align: center;
padding: 15px 0;
// left: 50%;
// transform: translateX(-50%);
}
// .noItem {
// }
</style>
+445
View File
@@ -0,0 +1,445 @@
<template lang="pug">
div.scroll(:class="$style.setting")
dl
dt 基本设置
dd
h3 主题颜色
div
ul(:class="$style.theme")
li(v-for="theme in themes.list" :key="theme.id" @click="current_setting.themeId = theme.id" :class="[theme.class, themes.active == theme.id ? $style.active : '']")
span
| {{theme.name}}
dd(title='弹出层的动画效果')
h3 弹出层随机动画
div
material-checkbox(id="setting_animate" v-model="current_setting.randomAnimate") 是否启用
dt 播放设置
dd(title="都不选时播放完当前歌曲就停止播放")
h3 歌曲切换方式
div
material-checkbox(:id="`setting_player_togglePlay_${item.value}`" :class="$style.gap" :target="item.value" :key="item.value"
v-model="current_setting.player.togglePlayMethod" v-for="item in togglePlayMethods") {{item.name}}
dd(title='启用时将优先播放320K品质的歌曲')
h3 优先播放高品质音乐
div
material-checkbox(id="setting_player_highQuality" v-model="current_setting.player.highQuality") 是否启用
dt 下载设置
dd(title='下载歌曲保存的路径')
h3 下载路径
div
p
| 当前下载路径:
span.auto-hidden.hover(title="点击打开当前路径" :class="$style.savePath" @click="handleOpenDir(current_setting.download.savePath)") {{current_setting.download.savePath}}
p
material-btn(:class="$style.btn" min @click="handleChangeSavePath") 更改
dd(title='下载歌曲时的命名方式')
h3 文件命名方式
div
material-checkbox(:id="`setting_download_musicName_${item.value}`" :class="$style.gap" name="setting_download_musicName" :target="item.value" :key="item.value" need
v-model="current_setting.download.fileName" v-for="item in musicNames") {{item.name}}
dt 列表设置
dd(title='播放列表是否显示专辑栏')
h3 专辑栏
div
material-checkbox(id="setting_list_showalbum" v-model="current_setting.list.isShowAlbumName") 是否显示专辑栏
dt 备份与恢复
dd
h3 部分数据
div
material-btn(:class="[$style.btn, $style.gap]" min @click="handleImportPlayList") 导入列表
material-btn(:class="[$style.btn, $style.gap]" min @click="handleExportPlayList") 导出列表
material-btn(:class="[$style.btn, $style.gap]" min @click="handleImportSetting") 导入设置
material-btn(:class="[$style.btn, $style.gap]" min @click="handleExportSetting") 导出设置
dd
h3 所有数据(设置与试听列表)
div
material-btn(:class="[$style.btn, $style.gap]" min @click="handleImportAllData") 导入
material-btn(:class="[$style.btn, $style.gap]" min @click="handleExportAllData") 导出
dt 关于洛雪音乐
dd
p
small 当前版本:
| {{version.version}}
p
small By:
| 落雪无痕
p
small
| 本软件仅用于学习交流使用,禁止将本软件用于
strong 非法用途
| 或
strong 商业用途
| 。
p
small
| 使用本软件造成的一切后果由
strong 使用者
| 承担!
p
small
| 本软件的部分接口使用自 https://github.com/messoer ,非常感谢
strong @messoer
| !
p
small 若有问题可 mail to:lyswhut@qq.com
</template>
<script>
import { mapGetters, mapMutations } from 'vuex'
import { openDirInExplorer, openSelectDir, openSaveDir, updateSetting } from '../utils'
import fs from 'fs'
export default {
name: 'Setting',
computed: {
...mapGetters(['setting', 'themes', 'version']),
...mapGetters('list', ['defaultList']),
},
data() {
return {
current_setting: {
version: null,
player: {
togglePlayMethod: 'random',
highQuality: false,
},
list: {
isShowAlbumName: true,
},
download: {
savePath: 'C:\\',
fileName: '歌名 - 歌手',
},
themeId: 0,
sourceId: 0,
randomAnimate: true,
},
togglePlayMethods: [
{
name: '列表循环',
value: 'listLoop',
},
{
name: '列表随机',
value: 'random',
},
{
name: '顺序播放',
value: 'list',
},
{
name: '单曲循环',
value: 'singleLoop',
},
],
musicNames: [
{
name: '歌名 - 歌手',
value: '歌名 - 歌手',
},
{
name: '歌手 - 歌名',
value: '歌手 - 歌名',
},
{
name: '歌名',
value: '歌名',
},
],
}
},
watch: {
current_setting: {
handler(n, o) {
if (!o.version) return
this.setSetting(JSON.parse(JSON.stringify(n)))
},
deep: true,
},
},
mounted() {
this.init()
},
methods: {
...mapMutations(['setSetting']),
...mapMutations('list', ['setDefaultList']),
init() {
this.current_setting = JSON.parse(JSON.stringify(this.setting))
},
handleChangeSavePath() {
openSelectDir({
title: '选择歌曲保存路径',
defaultPath: this.current_setting.download.savePath,
properties: ['openDirectory'],
}).then(result => {
if (result.canceled) return
this.current_setting.download.savePath = result.filePaths[0]
})
},
handleOpenDir(dir) {
openDirInExplorer(dir)
},
importSetting(path) {
let setting
try {
setting = JSON.parse(fs.readFileSync(path, 'utf8'))
} catch (error) {
return
}
if (setting.type !== 'setting') return
this.setSetting(updateSetting(setting.data))
this.init()
},
exportSetting(path) {
console.log(path)
const data = {
type: 'setting',
data: this.setting,
}
fs.writeFile(path, JSON.stringify(data, null, 2), 'utf8', err => {
console.log(err)
})
},
importPlayList(path) {
let defautlList
try {
defautlList = JSON.parse(fs.readFileSync(path, 'utf8'))
} catch (error) {
return
}
if (defautlList.type !== 'defautlList') return
this.setDefaultList(defautlList.data.list)
},
exportPlayList(path) {
const data = {
type: 'defautlList',
data: this.defaultList,
}
fs.writeFile(path, JSON.stringify(data, null, 2), 'utf8', err => {
console.log(err)
})
},
importAllData(path) {
let allData
try {
allData = JSON.parse(fs.readFileSync(path, 'utf8'))
} catch (error) {
return
}
if (allData.type !== 'allData') return
this.setSetting(updateSetting(allData.setting))
this.init()
this.setDefaultList(allData.defaultList.list)
},
exportAllData(path) {
let allData = {
type: 'allData',
setting: this.setting,
defaultList: this.defaultList,
}
fs.writeFile(path, JSON.stringify(allData, null, 2), 'utf8', err => {
console.log(err)
})
},
handleImportAllData() {
openSelectDir({
title: '选择备份文件',
properties: ['openFile'],
filters: [
{ name: 'Setting', extensions: ['json'] },
{ name: 'All Files', extensions: ['*'] },
],
}).then(result => {
if (result.canceled) return
this.importAllData(result.filePaths[0])
})
},
handleExportAllData() {
openSaveDir({
title: '选择备份保存位置',
defaultPath: 'lx_datas.json',
}).then(result => {
if (result.canceled) return
this.exportAllData(result.filePath)
})
},
handleImportSetting() {
openSelectDir({
title: '选择配置文件',
properties: ['openFile'],
filters: [
{ name: 'Setting', extensions: ['json'] },
{ name: 'All Files', extensions: ['*'] },
],
}).then(result => {
if (result.canceled) return
this.importSetting(result.filePaths[0])
})
},
handleExportSetting() {
openSaveDir({
title: '选择设置保存位置',
defaultPath: 'lx_setting.json',
}).then(result => {
if (result.canceled) return
this.exportSetting(result.filePath)
})
},
handleImportPlayList() {
openSelectDir({
title: '选择列表文件',
properties: ['openFile'],
filters: [
{ name: 'Play List', extensions: ['json'] },
{ name: 'All Files', extensions: ['*'] },
],
}).then(result => {
if (result.canceled) return
this.importPlayList(result.filePaths[0])
})
},
handleExportPlayList() {
openSaveDir({
title: '选择设置保存位置',
defaultPath: 'lx_list.json',
}).then(result => {
if (result.canceled) return
this.exportPlayList(result.filePath)
})
},
},
}
</script>
<style lang="less" module>
@import '../assets/styles/layout.less';
.setting {
padding: 0 15px 30px 15px;
font-size: 14px;
box-sizing: border-box;
overflow-y: auto;
height: 100%;
dt {
border-left: 5px solid @color-theme;
padding: 3px 7px;
margin: 30px 0 15px;
+ dd h3 {
margin-top: 0;
}
}
dd {
margin-left: 15px;
// font-size: 13px;
> div {
padding: 0 15px;
}
}
h3 {
font-size: 12px;
margin: 25px 0 15px;
}
p {
padding: 3px 0;
.btn {
+ .btn {
margin-left: 10px;
}
}
}
}
.gap {
+ .gap {
margin-left: 20px;
}
}
.theme {
display: flex;
// padding: 0 15px;
li {
display: flex;
flex-flow: column nowrap;
align-items: center;
cursor: pointer;
// color: @color-theme;
margin-right: 30px;
transition: color .3s ease;
&:last-child {
margin-right: 0;
}
span {
display: block;
width: 36px;
height: 36px;
margin-bottom: 5px;
border: 2px solid transparent;
padding: 2px;
transition: border-color .3s ease;
border-radius: 5px;
&:after {
display: block;
content: ' ';
width: 100%;
height: 100%;
border-radius: 4px;
}
}
each(@themes, {
&:global(.@{value}) {
span {
&:after {
background-color: ~'@{color-@{value}-theme}';
}
}
}
})
}
}
.save-path {
font-size: 12px;
}
each(@themes, {
:global(#container.@{value}) {
.tbody {
tr {
&.active {
color: ~'@{color-@{value}-theme}';
}
}
}
.setting {
dt {
border-left-color: ~'@{color-@{value}-theme}';
}
}
.theme {
display: flex;
li {
&.active {
&:global(.@{value}) {
color: ~'@{color-@{value}-theme}';
span {
border-color: ~'@{color-@{value}-theme}';
}
}
}
}
}
}
})
</style>