This commit is contained in:
lyswhut
2022-10-29 11:36:35 +08:00
parent 66b965d9f7
commit e45cee6596
715 changed files with 57096 additions and 31771 deletions
@@ -0,0 +1,188 @@
<template>
<SongList ref="list_ref" :list-info="listInfo" @toggle-page="togglePage" />
</template>
<script setup lang="ts">
import { watch, ref, nextTick } from '@common/utils/vueTools'
import { listInfo } from '@renderer/store/songList/state'
import { getAndSetList } from '@renderer/store/songList/action'
import { useRouter, useRoute, onBeforeRouteLeave } from '@common/utils/vueRouter'
import LX from '@renderer/types/lx'
import SongList from './components/SongList.vue'
const props = defineProps<{
source: LX.OnlineSource
tagId: string
sortId?: string
page: number
}>()
const list_ref = ref<any>(null)
const router = useRouter()
const route = useRoute()
const getListData = async(source: LX.OnlineSource, tabId: string, sortId: string, page: number) => {
// console.log(source, tabId, sortId, page)
await getAndSetList(source, tabId, sortId, page).then(() => {
if (listInfo.key == window.lx.songListInfo.songlistKey && window.lx.songListInfo.songlistPosition) {
nextTick(() => {
list_ref.value?.scrollTo(window.lx.songListInfo.songlistPosition)
})
} else if (list_ref.value) {
window.lx.songListInfo.songlistKey = null
nextTick(() => {
list_ref.value.scrollTo(0)
})
}
})
}
const togglePage = (page: number) => {
router.replace({
path: route.path,
query: {
...route.query,
sortId: props.sortId ?? '',
page,
},
})
// getListData(props.source, props.tagId, props.sortId ?? '', page)
}
watch(() => [props.source, props.tagId, props.sortId, props.page], ([source, tagId, sortId, page]) => {
// const source = (await getLeaderboardSetting()).source as LX.OnlineSource
// console.log(source, tagId, sortId)
if (!source || !sortId) return
// console.log(source, tagId, sortId, page)
getListData(source as LX.OnlineSource, tagId as string, sortId as string, page as number)
}, {
immediate: true,
})
onBeforeRouteLeave(() => {
window.lx.songListInfo.songlistKey = listInfo.key
if (list_ref.value) window.lx.songListInfo.songlistPosition = list_ref.value.getScrollTop()
})
</script>
<style lang="less" module>
@import '@renderer/assets/styles/layout.less';
.container {
overflow: hidden;
height: 100%;
display: flex;
flex-flow: column nowrap;
position: relative;
}
.listContent {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
display: flex;
flex-flow: column nowrap;
font-size: 14px;
box-sizing: border-box;
padding: 0 15px;
ul {
display: flex;
flex-flow: row wrap;
justify-content: space-between;
}
}
.item {
width: 32%;
box-sizing: border-box;
display: flex;
margin-top: 15px;
cursor: pointer;
transition: opacity @transition-normal;
&:hover {
opacity: .7;
}
}
.left {
flex: none;
width: 88px;
height: 88px;
display: flex;
background-position: center;
background-size: cover;
border-radius: 4px;
overflow: hidden;
opacity: .9;
img {
object-fit: cover;
}
// box-shadow: 0 0 2px 0 rgba(0,0,0,.2);
}
.right {
flex: auto;
padding: 3px 15px 5px 7px;
overflow: hidden;
h4 {
font-size: 14px;
height: 2.6em;
text-align: justify;
line-height: 1.3;
.mixin-ellipsis-2;
}
}
.songlist_info {
display: flex;
flex-flow: row nowrap;
gap: 15px;
margin-top: 12px;
font-size: 12px;
.mixin-ellipsis-1;
text-align: justify;
line-height: 1.2;
// text-indent: 24px;
color: var(--color-font-label);
svg {
margin-right: 2px;
}
}
.author {
margin-top: 6px;
font-size: 12px;
.mixin-ellipsis-1;
text-align: justify;
line-height: 1.2;
// text-indent: 24px;
color: var(--color-font-label);
}
.pagination {
text-align: center;
padding: 15px 0;
// left: 50%;
// transform: translateX(-50%);
}
.noitem {
position: absolute;
top: 0;
left: 0;
height: 100%;
width: 100%;
display: flex;
flex-flow: column nowrap;
justify-content: center;
align-items: center;
// background-color: var(--color-000);
p {
font-size: 24px;
color: var(--color-font-label);
}
}
</style>
@@ -0,0 +1,170 @@
<template>
<material-modal :show="props.modelValue" teleport="#view" width="60%" @close="emit('update:modelValue', $event)" @after-enter="$refs.input.focus()">
<main :class="$style.main">
<h2>{{ $t('songlist__import_input_title') }}</h2>
<div :class="$style.inputContent">
<base-selection v-model="source" :class="$style.select" :list="props.sourceList" item-key="id" item-name="name" />
<base-input
ref="input"
v-model.trim="text"
:class="$style.input"
:placeholder="$t('songlist__import_input_tip')"
@submit="handleSubmit"
/>
</div>
<div :class="$style.footer">
<div :class="$style.tips">
<ul>
<li>{{ $t('songlist__import_input_tip_1') }}</li>
<li>{{ $t('songlist__import_input_tip_2') }}</li>
<li>{{ $t('songlist__import_input_tip_3') }}</li>
<li>
{{ $t('songlist__import_input_tip_4') }}
<span
class="hover underline"
aria-label="https://lyswhut.github.io/lx-music-doc/desktop/faq/cannot-open-songlist"
@click="openUrl('https://lyswhut.github.io/lx-music-doc/desktop/faq/cannot-open-songlist')"
>FAQ</span>
</li>
</ul>
</div>
<base-btn :class="$style.btn" @click="handleSubmit">{{ $t('songlist__import_input_btn_confirm') }}</base-btn>
</div>
</main>
</material-modal>
</template>
<script setup>
import { openSongListInputInfo } from '@renderer/store/songList/state'
import { setOpenSongListInputInfo } from '@renderer/store/songList/action'
import { ref, watch } from '@common/utils/vueTools'
import { useRoute, useRouter } from '@common/utils/vueRouter'
import { openUrl } from '@common/utils/electron'
const props = defineProps({
modelValue: Boolean,
sourceList: {
type: Array,
required: true,
},
})
const emit = defineEmits(['update:modelValue'])
const router = useRouter()
const route = useRoute()
const text = ref('')
const source = ref('')
watch(() => props.modelValue, (visible) => {
if (!visible) return
source.value = openSongListInputInfo.source || route.query.source
// text.value = openSongListInputInfo.text
})
const handleSubmit = () => {
if (!text.value.length) return
setOpenSongListInputInfo(text.value, source.value)
router.push({
path: '/songList/detail',
query: {
source: source.value,
id: text.value,
refresh: 'true',
},
})
}
</script>
<style lang="less" module>
@import '@renderer/assets/styles/layout.less';
.main {
padding: 0 15px;
// max-width: 530px;
// min-width: 300px;
display: flex;
flex-flow: column nowrap;
min-height: 0;
// max-height: 100%;
// overflow: hidden;
h2 {
font-size: 14px;
color: var(--color-font);
line-height: 1.3;
word-break: break-all;
// text-align: center;
padding: 15px 0 8px;
}
}
.inputContent {
display: flex;
flex-flow: row nowrap;
}
.select {
width: auto;
:global {
.label-content {
height: 100%;
border-top-right-radius: 0;
border-bottom-right-radius: 0;
}
.selection-list {
li {
// background-color: var(--color-main-background);
text-align: center;
line-height: 32px;
font-size: 13px;
&:hover {
background-color: var(--color-button-background-hover);
}
&:active {
background-color: var(--color-button-background-active);
}
}
}
}
}
.input {
flex: auto;
border-top-left-radius: 0;
border-bottom-left-radius: 0;
// width: 100%;
// height: 26px;
padding: 8px 8px;
color: var(--color-font);
}
.footer {
margin: 50px 0 15px;
display: flex;
flex-flow: row nowrap;
align-items: flex-end;
}
.tips {
flex: auto;
font-size: 12px;
color: var(--color-font);
line-height: 1.5;
ul {
list-style: decimal;
padding-left: 15px;
}
}
.btn {
// box-sizing: border-box;
// margin-left: 15px;
// margin-bottom: 15px;
// height: 36px;
// line-height: 36px;
// padding: 0 10px !important;
min-width: 80px;
// .mixin-ellipsis-1;
}
</style>
@@ -0,0 +1,206 @@
<template>
<div :class="$style.container">
<div v-show="!props.listInfo.noItemLabel" ref="dom_list_ref" :class="$style.listContent" class="scroll">
<ul>
<li v-for="item in props.listInfo.list" :key="item.id" :class="$style.item" @click="toDetail(item)">
<div :class="$style.image">
<img :class="$style.img" loading="lazy" decoding="async" :src="item.img">
</div>
<div :class="$style.desc">
<h4>{{ item.name }}</h4>
<div>
<div :class="$style.songlist_info">
<span v-if="item.total != null"><svg-icon name="music" />{{ item.total }}</span>
<span v-if="item.play_count != null"><svg-icon name="headphones" />{{ item.play_count }}</span>
</div>
<p :class="$style.author">{{ item.author }}</p>
</div>
</div>
</li>
<li v-for="(i, index) in 6" :key="index" :class="$style.item" style="margin-bottom: 0;height: 0;" />
</ul>
<div :class="$style.pagination">
<material-pagination :count="props.listInfo.total" :limit="props.listInfo.limit" :page="props.listInfo.page" @btn-click="togglePage" />
</div>
</div>
<transition enter-active-class="animated fadeIn" leave-active-class="animated fadeOut">
<div v-show="props.listInfo.noItemLabel" :class="$style.noitem">
<p v-text="props.listInfo.noItemLabel" />
</div>
</transition>
</div>
</template>
<script setup lang="ts">
import { ref, defineEmits, defineExpose } from '@common/utils/vueTools'
import { ListInfo, ListInfoItem } from '@renderer/store/songList/state'
// import LX from '@renderer/types/lx'
import { useRoute, useRouter } from '@common/utils/vueRouter'
const props = defineProps<{
listInfo: ListInfo
}>()
const router = useRouter()
const route = useRoute()
const dom_list_ref = ref<HTMLElement | null>(null)
const emit = defineEmits(['toggle-page'])
const togglePage = (page: number) => {
emit('toggle-page', page)
}
const toDetail = (info: ListInfoItem) => {
router.push({
path: '/songList/detail',
query: {
source: info.source,
id: info.id,
picUrl: info.img,
fromName: route.name as string,
},
})
}
defineExpose({
scrollTo(top: number) {
dom_list_ref.value?.scrollTo({
top,
// behavior: 'smooth',
})
},
getScrollTop() {
return dom_list_ref.value?.scrollTop ?? 0
},
})
</script>
<style lang="less" module>
@import '@renderer/assets/styles/layout.less';
.container {
overflow: hidden;
height: 100%;
display: flex;
flex-flow: column nowrap;
position: relative;
}
.listContent {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
display: flex;
flex-flow: column nowrap;
font-size: 14px;
box-sizing: border-box;
padding: 15px 15px 0;
ul {
display: flex;
flex-flow: row wrap;
justify-content: space-between;
}
}
.item {
max-width: 360px;
width: 32%;
box-sizing: border-box;
display: flex;
// flex-flow: column nowrap;
// padding: 10px;
margin-bottom: 20px;
cursor: pointer;
transition: opacity @transition-normal;
&:hover {
opacity: .7;
}
}
.image {
flex: none;
width: 40%;
display: flex;
background-position: center;
background-size: cover;
border-radius: 4px;
overflow: hidden;
opacity: .9;
aspect-ratio: 1 / 1;
box-shadow: 0 0 2px 0 rgba(0,0,0,.2);
}
.img {
width: 100%;
height: 100%;
object-fit: cover;
}
.desc {
flex: auto;
padding: 2px 15px 2px 7px;
overflow: hidden;
h4 {
font-size: 14px;
// height: 2.6em;
text-align: justify;
line-height: 1.3;
.mixin-ellipsis-2;
}
}
.songlist_info {
display: flex;
flex-flow: row nowrap;
gap: 15px;
margin-top: 8px;
font-size: 12px;
.mixin-ellipsis-1;
text-align: justify;
line-height: 1.2;
// text-indent: 24px;
color: var(--color-font-label);
svg {
margin-right: 2px;
}
}
.author {
margin-top: 6px;
font-size: 12px;
.mixin-ellipsis-1;
text-align: justify;
line-height: 1.2;
// text-indent: 24px;
color: var(--color-font-label);
}
.pagination {
text-align: center;
padding: 15px 0;
// left: 50%;
// transform: translateX(-50%);
}
.noitem {
position: absolute;
top: 0;
left: 0;
height: 100%;
width: 100%;
display: flex;
flex-flow: column nowrap;
justify-content: center;
align-items: center;
// background-color: var(--color-000);
p {
font-size: 24px;
color: var(--color-font-label);
}
}
</style>
@@ -0,0 +1,174 @@
<template>
<base-tab :model-value="sortId" :class="$style.tab" :list="list" item-label="name" @change="handleToggle" />
</template>
<script setup>
import { watch, shallowReactive } from '@common/utils/vueTools'
import { sortList } from '@renderer/store/songList/state'
import { useRouter, useRoute } from '@common/utils/vueRouter'
const props = defineProps({
source: {
type: String,
required: true,
},
tagId: {
type: String,
required: true,
},
sortId: {
type: String,
default: '',
},
})
const router = useRouter()
const route = useRoute()
const list = shallowReactive([])
const handleToggle = (id) => {
router.replace({
path: route.path,
query: {
source: props.source,
tagId: props.tagId,
sortId: id,
},
})
}
watch(() => props.source, async(source) => {
// const source = (await getLeaderboardSetting()).source as LX.OnlineSource
if (!source) return
let _list = sortList[source] ?? []
list.splice(0, list.length, ..._list)
if (!props.sortId && list.length) handleToggle(list[0].id)
// console.log(list)
}, {
immediate: true,
})
</script>
<style lang="less" module>
@import '@renderer/assets/styles/layout.less';
.tag-list {
font-size: 12px;
position: relative;
&.active {
.label {
.icon {
svg{
transform: rotate(180deg);
}
}
}
.list {
opacity: 1;
transform: scaleY(1);
}
}
}
.label {
padding: 8px 15px;
// background-color: var(--color-button-background);
transition: background-color @transition-normal;
// border-top: 2px solid @color-tab-border-bottom;
// border-left: 2px solid @color-tab-border-bottom;
box-sizing: border-box;
text-align: center;
// border-top-left-radius: 3px;
color: var(--color-button-font);
cursor: pointer;
display: flex;
span {
flex: auto;
}
.icon {
flex: none;
margin-left: 7px;
line-height: 0;
svg {
width: .9em;
transition: transform .2s ease;
transform: rotate(0);
}
}
&:hover {
background-color: var(--color-button-background-hover);
}
&:active {
background-color: var(--color-button-background-active);
}
}
.list {
position: absolute;
top: 100%;
width: 645px;
left: 0;
// border-bottom: 2px solid @color-tab-border-bottom;
// border-right: 2px solid @color-tab-border-bottom;
border-bottom-right-radius: 5px;
background-color: var(--color-main-background);
opacity: 0;
transform: scaleY(0);
overflow-y: auto;
transform-origin: 0 0 0;
max-height: 250px;
transition: .25s ease;
transition-property: transform, opacity;
z-index: 10;
padding: 10px;
box-sizing: border-box;
li {
cursor: pointer;
padding: 8px 15px;
// color: var(--color-button-font);
text-align: center;
outline: none;
transition: background-color @transition-normal;
background-color: var(--color-button-background);
box-sizing: border-box;
&:hover {
background-color: var(--color-button-background-hover);
}
&:active {
background-color: var(--color-button-background-active);
}
}
}
.type {
padding-top: 10px;
padding-bottom: 3px;
color: var(--color-font-label);
}
.tag {
display: inline-block;
margin: 5px;
background-color: var(--color-button-background);
padding: 8px 10px;
border-radius: @radius-progress-border;
transition: background-color @transition-normal;
cursor: pointer;
&:hover {
background-color: var(--color-button-background-hover);
}
&:active {
background-color: var(--color-button-background-active);
}
}
</style>
@@ -0,0 +1,231 @@
<template>
<div :class="[$style.tagList, {[$style.active]: popupVisible}]">
<div ref="dom_btn" :class="$style.label" @click="handleShow">
<span>{{ tagName }}</span>
<div :class="$style.icon">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xlink="http://www.w3.org/1999/xlink" height="100%" viewBox="0 0 451.847 451.847" space="preserve">
<use xlink:href="#icon-down" />
</svg>
</div>
</div>
<div :class="$style.popup" :style="popupStyle" :aria-hidden="!popupVisible" @click.stop>
<div :class="$style.list" class="scroll">
<div :class="$style.tag" @click="handleToggleTag('')">{{ $t('default') }}</div>
<dl v-for="tagInfo in list" :key="tagInfo.name">
<dt :class="$style.type">{{ tagInfo.name }}</dt>
<dd v-for="tag in tagInfo.list" :key="tag.id" :class="$style.tag" @click="handleToggleTag(tag.id)">{{ tag.name }}</dd>
</dl>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import { watch, shallowReactive, ref, onMounted, onBeforeUnmount, computed, reactive } from '@common/utils/vueTools'
import { setTags, getTags } from '@renderer/store/songList/action'
import { tags, TagInfoTypeItem } from '@renderer/store/songList/state'
import LX from '@renderer/types/lx'
import { useRouter, useRoute } from '@common/utils/vueRouter'
import { useI18n } from '@renderer/plugins/i18n'
const props = defineProps<{
source: LX.OnlineSource
tagId: string
sortId?: string
}>()
const router = useRouter()
const route = useRoute()
const t = useI18n()
const list = shallowReactive<TagInfoTypeItem[]>([])
const handleToggleTag = (id: string) => {
router.replace({
path: route.path,
query: {
source: props.source,
tagId: id,
sortId: props.sortId,
},
})
handleHide()
}
watch(() => props.source, async(source) => {
if (!source) return
// const source = (await getLeaderboardSetting()).source as LX.OnlineSource
let tagInfo = tags[source]
// console.log(await getTags(source))
if (tagInfo == null) setTags(tagInfo = await getTags(source), source)
list.splice(0, list.length, ...[{ name: window.i18n.t('songlist__tag_info_hot_tag'), list: [...tagInfo.hotTag] }, ...tagInfo.tags])
}, {
immediate: true,
})
const tagName = computed(() => {
if (!props.tagId) return t('default')
for (const tags of list) {
const tag = tags.list.find(t => t.id == props.tagId)
if (tag) return tag.name
}
return props.tagId
})
const popupStyle = reactive({
width: '645px',
maxHeight: '250px',
})
const setTagPopupWidth = () => {
window.setTimeout(() => {
const dom_view = document.getElementById('view')
popupStyle.width = dom_view!.clientWidth * 0.96 + 'px'
popupStyle.maxHeight = dom_view!.clientHeight * 0.65 + 'px'
}, 50)
}
const dom_btn = ref<HTMLElement | null>(null)
const popupVisible = ref(false)
const handleShow = () => popupVisible.value = !popupVisible.value
const handleHide = (evt?: MouseEvent) => {
// if (e && e.target.parentNode != this.$refs.dom_popup && this.show) return this.show = false
// console.log(this.$refs)
if (evt && (evt.target == dom_btn.value || dom_btn.value?.contains(evt.target as HTMLElement))) return
setTimeout(() => {
popupVisible.value = false
}, 50)
}
onMounted(() => {
setTagPopupWidth()
document.addEventListener('click', handleHide)
window.addEventListener('resize', setTagPopupWidth)
})
onBeforeUnmount(() => {
document.removeEventListener('click', handleHide)
window.removeEventListener('resize', setTagPopupWidth)
})
</script>
<style lang="less" module>
@import '@renderer/assets/styles/layout.less';
.tag-list {
font-size: 12px;
position: relative;
&.active {
.label {
.icon {
svg{
transform: rotate(180deg);
}
}
}
.popup {
opacity: 1;
transform: scale(1);
pointer-events: initial;
}
}
}
.label {
padding: 8px 15px;
// background-color: var(--color-button-background);
transition: color @transition-normal;
// border-top: 2px solid @color-tab-border-bottom;
// border-left: 2px solid @color-tab-border-bottom;
box-sizing: border-box;
text-align: center;
// border-top-left-radius: 3px;
color: var(--color-font);
cursor: pointer;
display: flex;
span {
flex: auto;
}
.icon {
flex: none;
margin-left: 7px;
line-height: 0;
svg {
width: .8em;
transition: transform .2s ease;
transform: rotate(0);
}
}
&:hover {
color: var(--color-primary-font-hover);
}
&:active {
color: var(--color-primary-font-active);
}
}
.popup {
position: absolute;
top: 100%;
width: 645px;
left: 8px;
margin-top: 12px;
border-radius: 4px;
background-color: var(--color-content-background);
opacity: 0;
transform: scale(.95, .8);
transform-origin: 0 0 0;
transition: .25s ease;
transition-property: transform, opacity;
max-height: 250px;
z-index: 10;
pointer-events: none;
filter: drop-shadow(0px 0px 4px rgba(0, 0, 0, .15));
display: flex;
&:before {
content: " ";
position: absolute;
top: -6px;
left: 20px;
width: 0;
height: 0;
border-left: 8px solid transparent;
border-right: 8px solid transparent;
border-bottom: 8px solid var(--color-content-background);
}
}
.list {
padding: 10px;
box-sizing: border-box;
// box-shadow: 0 0 4px rgba(0, 0, 0, .2);
}
.type {
padding-top: 10px;
padding-bottom: 3px;
color: var(--color-font-label);
}
.tag {
display: inline-block;
margin: 5px;
background-color: var(--color-button-background);
padding: 8px 10px;
border-radius: @radius-progress-border;
transition: background-color @transition-normal;
cursor: pointer;
&:hover {
background-color: var(--color-button-background-hover);
}
&:active {
background-color: var(--color-button-background-active);
}
}
</style>
+215
View File
@@ -0,0 +1,215 @@
<template>
<div :class="$style.container">
<div :class="$style.header">
<div :class="$style.left">
<tag-list :source="source" :tag-id="tagId" :sort-id="sortId" />
<sort-tab :source="source" :tag-id="tagId" :sort-id="sortId" />
</div>
<base-btn :class="$style.btn" outline min @click="visibleOpenSongListModal = true">{{ $t('songlist__import_input_show_btn') }}</base-btn>
<base-selection :model-value="source" :class="$style.select" :list="sourceList" item-key="id" item-name="name" @update:model-value="handleToggleSource" />
</div>
<list-view :source="source" :tag-id="tagId" :sort-id="sortId" :page="page" />
<open-list-modal v-model="visibleOpenSongListModal" :source-list="sourceList" />
</div>
</template>
<script lang="ts">
import { computed, ref } from '@common/utils/vueTools'
import { getSongListSetting, setSongListSetting } from '@renderer/utils/data'
import TagList from './components/TagList.vue'
import SortTab from './components/SortTab.vue'
import OpenListModal from './components/OpenListModal.vue'
import ListView from './ListView.vue'
import { sources, listInfo, isVisibleListDetail } from '@renderer/store/songList/state'
import { sourceNames } from '@renderer/store'
import LX from '@renderer/types/lx'
import { useRoute, useRouter } from '@common/utils/vueRouter'
const source = ref<LX.OnlineSource>('kw')
const tagId = ref<string>('')
const sortId = ref<string>('')
const page = ref<number>(1)
interface Query {
source?: string
tagId?: string
sortId?: string
page?: string
}
const verifyQueryParams = async function(this: any, to: { query: Query, path: string}, from: any, next: (route?: { path: string; query: Query }) => void) {
let _source = to.query.source
let _tagId = to.query.tagId
let _sortId = to.query.sortId
let _page: string | undefined = to.query.page
if (isVisibleListDetail.value) {
next({ path: '/songList/detail', query: {} })
return
} else if (_source == null) {
if (listInfo.key) {
_source = listInfo.source
_tagId = listInfo.tagId
_sortId = listInfo.sortId
_page = listInfo.page.toString()
} else {
const setting = await getSongListSetting()
_source = setting.source
_tagId = setting.tagId
_sortId = setting.sortId
_page = '1'
}
next({
path: to.path,
query: { ...to.query, source: _source, tagId: _tagId, sortId: _sortId, page: _page },
})
return
}
next()
source.value = _source as LX.OnlineSource
tagId.value = _tagId ?? ''
sortId.value = _sortId ?? ''
page.value = _page ? parseInt(_page) : 1
setSongListSetting({ source: _source, tagId: _tagId, sortId: _sortId })
}
export default {
components: {
TagList,
SortTab,
ListView,
OpenListModal,
},
beforeRouteEnter: verifyQueryParams,
beforeRouteUpdate: verifyQueryParams,
setup() {
const visibleOpenSongListModal = ref(false)
const sourceList = computed(() => {
return sources.map(s => ({ id: s, name: sourceNames.value[s] }))
})
const router = useRouter()
const route = useRoute()
const handleToggleSource = (id: LX.OnlineSource) => {
if (id == source.value) return
router.replace({
path: route.path,
query: {
source: id,
tagId: '',
},
})
}
return {
source,
tagId,
sortId,
page,
sourceList,
handleToggleSource,
visibleOpenSongListModal,
}
},
}
</script>
<style lang="less" module>
@import '@renderer/assets/styles/layout.less';
.container {
height: 100%;
display: flex;
flex-flow: column nowrap;
position: relative;
}
.header {
flex: none;
width: 100%;
display: flex;
flex-flow: row nowrap;
// padding-right: 5px;
// box-sizing: border-box;
padding-bottom: 5px;
}
.left {
flex: auto;
display: flex;
flex-flow: row nowrap;
}
.btn {
color: var(--color-font);
transition: color @transition-fast;
background: none !important;
&:hover {
color: var(--color-primary-font-hover);
}
}
.select {
font-size: 12px;
width: auto;
flex: none;
padding: 0 5px;
&:hover {
:global(.icon) {
opacity: 1;
}
}
:global {
.label-content {
background-color: transparent !important;
transition: color @transition-fast;
color: var(--color-font);
// line-height: 38px;
// height: 38px;
border-radius: 0;
&:hover {
// background: none !important;
color: var(--color-primary-font-hover);
.icon {
opacity: 1;
// color: var(--color-primary-font-hover);
}
}
}
// .label {
// color: var(--color-font) !important;
// }
.icon {
svg {
width: .8em;
}
// opacity: .6;
// transition: color @transition-fast;
// color: var(--color-font-label);
}
.selection-list {
max-height: 500px;
box-shadow: 0 1px 4px 0 rgba(0,0,0,.2);
li {
// background-color: var(--color-main-background);
text-align: center;
line-height: 38px;
font-size: 13px;
&:hover {
background-color: var(--color-button-background-hover);
}
&:active {
background-color: var(--color-button-background-active);
}
}
}
}
}
</style>