music(player): 侧边栏 ★ 标记 + sort-bar '仅看收藏' 切换
deploy music / build-and-deploy (push) Successful in 1m59s
deploy music / build-and-deploy (push) Successful in 1m59s
This commit is contained in:
@@ -54,6 +54,12 @@
|
|||||||
<button :class="{ active: sortMode === 'least' }" @click="setSort('least')">最少播放</button>
|
<button :class="{ active: sortMode === 'least' }" @click="setSort('least')">最少播放</button>
|
||||||
<button :class="{ active: sortMode === 'recent' }" @click="setSort('recent')">最近</button>
|
<button :class="{ active: sortMode === 'recent' }" @click="setSort('recent')">最近</button>
|
||||||
<button :class="{ active: sortMode === 'random' }" @click="setSort('random')">随机</button>
|
<button :class="{ active: sortMode === 'random' }" @click="setSort('random')">随机</button>
|
||||||
|
<button
|
||||||
|
class="fav-toggle"
|
||||||
|
:class="{ active: favOnly }"
|
||||||
|
:title="favOnly ? '显示全部' : '仅看收藏'"
|
||||||
|
@click="toggleFavOnly"
|
||||||
|
>{{ favOnly ? '★' : '☆' }}</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="playlist">
|
<div class="playlist">
|
||||||
@@ -72,7 +78,10 @@
|
|||||||
title="单击切换 / 双击切换并播放"
|
title="单击切换 / 双击切换并播放"
|
||||||
>
|
>
|
||||||
<div class="row-main">
|
<div class="row-main">
|
||||||
<div class="row-title">{{ p.title }}</div>
|
<div class="row-title">
|
||||||
|
<span v-if="p.favorite" class="row-fav" title="已收藏">★</span>
|
||||||
|
{{ p.title }}
|
||||||
|
</div>
|
||||||
<div class="row-meta">
|
<div class="row-meta">
|
||||||
<span v-if="p.artist">{{ p.artist }}</span>
|
<span v-if="p.artist">{{ p.artist }}</span>
|
||||||
<span v-if="p.category" class="cat">{{ p.category }}</span>
|
<span v-if="p.category" class="cat">{{ p.category }}</span>
|
||||||
@@ -416,6 +425,7 @@ const activeTagName = ref(null)
|
|||||||
|
|
||||||
const search = ref('')
|
const search = ref('')
|
||||||
const sortMode = ref(localStorage.getItem('music.sort') || 'name')
|
const sortMode = ref(localStorage.getItem('music.sort') || 'name')
|
||||||
|
const favOnly = ref(localStorage.getItem('music.favOnly') === 'true')
|
||||||
const repeatOne = ref(false)
|
const repeatOne = ref(false)
|
||||||
const volume = ref(parseFloat(localStorage.getItem('music.vol') || '1'))
|
const volume = ref(parseFloat(localStorage.getItem('music.vol') || '1'))
|
||||||
const muted = ref(localStorage.getItem('music.muted') === '1')
|
const muted = ref(localStorage.getItem('music.muted') === '1')
|
||||||
@@ -648,6 +658,9 @@ const tabs = computed(() => {
|
|||||||
const filtered = computed(() => {
|
const filtered = computed(() => {
|
||||||
const q = search.value.trim().toLowerCase()
|
const q = search.value.trim().toLowerCase()
|
||||||
let arr = pieces.value
|
let arr = pieces.value
|
||||||
|
if (favOnly.value) {
|
||||||
|
arr = arr.filter(p => p.favorite)
|
||||||
|
}
|
||||||
if (q) {
|
if (q) {
|
||||||
arr = arr.filter(p => {
|
arr = arr.filter(p => {
|
||||||
const hay = `${p.title} ${p.artist || ''} ${p.category || ''} ${(p.tags || []).join(' ')}`.toLowerCase()
|
const hay = `${p.title} ${p.artist || ''} ${p.category || ''} ${(p.tags || []).join(' ')}`.toLowerCase()
|
||||||
@@ -655,6 +668,7 @@ const filtered = computed(() => {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
arr = [...arr]
|
arr = [...arr]
|
||||||
|
// 名称排序时,收藏的自然置顶;其它模式按用户选的指标排,不强行打断
|
||||||
switch (sortMode.value) {
|
switch (sortMode.value) {
|
||||||
case 'hot':
|
case 'hot':
|
||||||
arr.sort((a, b) => b.play_count - a.play_count || a.title.localeCompare(b.title, 'zh'))
|
arr.sort((a, b) => b.play_count - a.play_count || a.title.localeCompare(b.title, 'zh'))
|
||||||
@@ -676,11 +690,21 @@ const filtered = computed(() => {
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
arr.sort((a, b) => a.title.localeCompare(b.title, 'zh'))
|
arr.sort((a, b) => {
|
||||||
|
const fa = a.favorite ? 1 : 0
|
||||||
|
const fb = b.favorite ? 1 : 0
|
||||||
|
if (fa !== fb) return fb - fa
|
||||||
|
return a.title.localeCompare(b.title, 'zh')
|
||||||
|
})
|
||||||
}
|
}
|
||||||
return arr
|
return arr
|
||||||
})
|
})
|
||||||
|
|
||||||
|
function toggleFavOnly() {
|
||||||
|
favOnly.value = !favOnly.value
|
||||||
|
localStorage.setItem('music.favOnly', favOnly.value ? 'true' : 'false')
|
||||||
|
}
|
||||||
|
|
||||||
function hash(id, seed) {
|
function hash(id, seed) {
|
||||||
let x = (id ^ Math.floor(seed * 1e9)) >>> 0
|
let x = (id ^ Math.floor(seed * 1e9)) >>> 0
|
||||||
x = (x ^ (x << 13)) >>> 0
|
x = (x ^ (x << 13)) >>> 0
|
||||||
@@ -1378,6 +1402,24 @@ onBeforeUnmount(() => {
|
|||||||
border-color: var(--accent-strong);
|
border-color: var(--accent-strong);
|
||||||
color: var(--accent);
|
color: var(--accent);
|
||||||
}
|
}
|
||||||
|
.sort-bar .fav-toggle {
|
||||||
|
margin-left: auto;
|
||||||
|
border-radius: 4px !important;
|
||||||
|
border-right-width: 1px !important;
|
||||||
|
font-size: 14px;
|
||||||
|
padding: 4px 8px;
|
||||||
|
}
|
||||||
|
.sort-bar .fav-toggle.active {
|
||||||
|
color: #f5b800;
|
||||||
|
border-color: #f5b800;
|
||||||
|
background: rgba(245, 184, 0, 0.12);
|
||||||
|
}
|
||||||
|
|
||||||
|
.row-fav {
|
||||||
|
color: #f5b800;
|
||||||
|
margin-right: 4px;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
.playlist { flex: 1; overflow-y: auto; }
|
.playlist { flex: 1; overflow-y: auto; }
|
||||||
.hint { padding: 40px 20px; text-align: center; color: var(--text-mute); font-size: 14px; }
|
.hint { padding: 40px 20px; text-align: center; color: var(--text-mute); font-size: 14px; }
|
||||||
|
|||||||
Reference in New Issue
Block a user