simple fs

This commit is contained in:
vapormusic 2022-01-06 17:24:57 +07:00
parent 1f3676c374
commit ee2b332350
6 changed files with 276 additions and 23 deletions

View file

@ -232,6 +232,7 @@ const app = new Vue({
mkIsReady: false, mkIsReady: false,
playerReady: false, playerReady: false,
animateBackground: false, animateBackground: false,
currentArtUrl: '',
lyricon: false, lyricon: false,
currentTrackID: '', currentTrackID: '',
currentTrackIDBG: '', currentTrackIDBG: '',
@ -587,6 +588,7 @@ const app = new Vue({
self.chrome.artworkReady = false self.chrome.artworkReady = false
self.lyrics = [] self.lyrics = []
self.richlyrics = [] self.richlyrics = []
app.getCurrentArtURL();
app.getNowPlayingArtwork(42); app.getNowPlayingArtwork(42);
app.getNowPlayingArtworkBG(32); app.getNowPlayingArtworkBG(32);
app.loadLyrics() app.loadLyrics()
@ -2527,6 +2529,7 @@ const app = new Vue({
} }
}, 200) }, 200)
}, },
getNowPlayingArtwork(size = 600) { getNowPlayingArtwork(size = 600) {
if (typeof this.mk.nowPlayingItem === "undefined") return; if (typeof this.mk.nowPlayingItem === "undefined") return;
let interval = setInterval(() => { let interval = setInterval(() => {
@ -2537,7 +2540,7 @@ const app = new Vue({
if (document.querySelector('.app-playback-controls .artwork') != null) { if (document.querySelector('.app-playback-controls .artwork') != null) {
clearInterval(interval); clearInterval(interval);
} }
if (this.mk["nowPlayingItem"]["attributes"]["artwork"]["url"]) { if (app.mk.nowPlayingItem.attributes.artwork != null && app.mk.nowPlayingItem.attributes.artwork.url != null && app.mk.nowPlayingItem.attributes.artwork.url!= '' ) {
document.querySelector('.app-playback-controls .artwork').style.setProperty('--artwork', `url("${decodeURI((this.mk["nowPlayingItem"]["attributes"]["artwork"]["url"])).replace('{w}', size).replace('{h}', size)}")`); document.querySelector('.app-playback-controls .artwork').style.setProperty('--artwork', `url("${decodeURI((this.mk["nowPlayingItem"]["attributes"]["artwork"]["url"])).replace('{w}', size).replace('{h}', size)}")`);
try { try {
clearInterval(interval); clearInterval(interval);
@ -2566,6 +2569,21 @@ const app = new Vue({
}, 200) }, 200)
},
async getCurrentArtURL(){
try{
this.currentArtUrl = '';
if (app.mk.nowPlayingItem != null && app.mk.nowPlayingItem.attributes != null && app.mk.nowPlayingItem.attributes.artwork != null && app.mk.nowPlayingItem.attributes.artwork.url != null && app.mk.nowPlayingItem.attributes.artwork.url!= '' )
{this.currentArtUrl = (this.mk["nowPlayingItem"]["attributes"]["artwork"]["url"] ?? '').replace('{w}', 50).replace('{h}', 50);
} else {
let data = await this.mk.api.library.song(this.mk.nowPlayingItem.id);
if (data != null && data !== "" && data.attributes != null && data.attributes.artwork != null) {
this.currentArtUrl = (data["attributes"]["artwork"]["url"] ?? '').replace('{w}', 50).replace('{h}', 50);;
} else {this.currentArtUrl = ''}
}
}catch(e){
}
}, },
async setLibraryArt() { async setLibraryArt() {
if (typeof this.mk.nowPlayingItem === "undefined") return; if (typeof this.mk.nowPlayingItem === "undefined") return;

View file

@ -3567,15 +3567,148 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb {
flex-grow: 1; flex-grow: 1;
} }
.right-col{
height: 50vh;
}
.lyrics-col{
width: 60vh;
height: 50vh;
::-webkit-scrollbar {
display: none;
}
&:hover ::-webkit-scrollbar {
display: unset;
}
}
.artwork-col { .artwork-col {
justify-content: center; justify-content: center;
align-items: center; align-items: center;
display: flex; display: flex;
flex-direction: column;
.artwork { .artwork {
width: 50vh; width: 50vh;
height: 50vh; height: 50vh;
} }
.controls-parents{
width: 50vh;
}
.app-playback-controls {
.song-artist , .song-name {
font-weight: 600;
text-align: center;
font-size: 0.9em;
margin-top: 0.25vh;
height: 0.9em;
line-height: 0.9em;
overflow: hidden;
max-width: 360px;
.song-name-normal {
height: inherit;
}
&.song-artist-marquee {
> marquee {
//margin-bottom: -3px;
}
}
}
.song-artist {
font-size: 0.875em;
}
}
.app-playback-controls .playback-info {
margin-top: 0.5vh;
width: 100%;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
position: relative;
input[type="range"] {
width: 100%;
}
>div {
width: 100%;
text-align: center;
}
}
.app-playback-controls .song-progress {
@bgColor: transparent;
//height: 16px;
position: absolute;
bottom: -2.5vh;
left: 0px;
background: @bgColor;
.song-duration p {
font-weight: 400;
font-size: 10px;
height: 1.2em;
line-height: 1.3em;
overflow: hidden;
margin: 0 0 0.5em;
}
&:hover {
> input[type=range] {
&::-webkit-slider-thumb {
opacity: 1;
transform: scale(1);
z-index: 1;
}
}
}
> input[type=range] {
appearance: none;
width: 100%;
height: 4px;
background-color: rgb(200 200 200 / 10%);
border-radius: 2px;
&::-webkit-slider-thumb {
opacity: 0;
transform: scale(0.5);
-webkit-appearance: none;
appearance: none;
width: 12px;
height: 12px;
border-radius: 100%;
background: var(--keyColor);
cursor: default;
transition: opacity .10s var(--appleEase), transform .10s var(--appleEase);
}
&::-moz-range-thumb {
width: 8px;
height: 8px;
border-radius: 100%;
background: var(--keyColor);
cursor: default;
}
}
}
.control-buttons {
margin-top: 2vh;
display: inline-flex;
width: 100%;
justify-content: center;
}
} }
} }

View file

@ -2,20 +2,88 @@
<div class="fullscreen-view"> <div class="fullscreen-view">
<div class="row fs-row"> <div class="row fs-row">
<div class="col artwork-col"> <div class="col artwork-col">
<div class="artwork"> <div class="artwork" @click="app.appMode = 'player'">
<mediaitem-artwork <mediaitem-artwork
:size="600" :size="600"
url="" :url="image ?? ''"
></mediaitem-artwork> ></mediaitem-artwork>
</div> </div>
</div> <div class="controls-parents">
<div class="col"> <template v-if="app.mkReady()">
<div class="fs-info"> <div class="app-playback-controls" @mouseover="app.chrome.progresshover = true"
<div>Name</div> @mouseleave="app.chrome.progresshover = false" @contextmenu="app.nowPlayingContextMenu">
<div>Name</div> <div class="playback-info">
<div>Name</div> <div class="song-name">
{{ app.mk.nowPlayingItem["attributes"]["name"] }}
</div>
<div class="song-artist "
style="display: inline-block; -webkit-box-orient: horizontal; white-space: nowrap;">
<div class="item-navigate song-artist" style="display: inline-block;"
@click="app.getNowPlayingItemDetailed(`artist`)">
{{ app.mk.nowPlayingItem["attributes"]["artistName"] }}
</div>
<div class="song-artist item-navigate" style="display: inline-block;"
@click="app.getNowPlayingItemDetailed('album')">
{{ (app.mk.nowPlayingItem["attributes"]["albumName"]) ? (" - " +
app.mk.nowPlayingItem["attributes"]["albumName"]) : "" }}
</div>
</div>
<div class="song-progress">
<div class="song-duration" style="justify-content: space-between; height: 1px;"
:style="[app.chrome.progresshover ? {'display': 'flex'} : {'display' : 'none'} ]">
<p style="width: auto">{{ app.convertToMins(app.getSongProgress()) }}</p>
<p style="width: auto">{{ app.convertToMins(app.mk.currentPlaybackDuration) }}</p>
</div>
<input type="range" step="0.01" min="0" :style="app.progressBarStyle()"
@input="app.playerLCD.desiredDuration = $event.target.value;app.playerLCD.userInteraction = true"
@mouseup="app.mk.seekToTime($event.target.value);app.playerLCD.desiredDuration = 0;app.playerLCD.userInteraction = false"
:max="app.mk.currentPlaybackDuration" :value="app.getSongProgress()">
</div>
</div>
<div class="control-buttons">
<div class="app-chrome-item">
<button class="playback-button--small shuffle" v-if="app.mk.shuffleMode == 0"
@click="app.mk.shuffleMode = 1"></button>
<button class="playback-button--small shuffle active" v-else
@click="app.mk.shuffleMode = 0"></button>
</div>
<div class="app-chrome-item">
<button class="playback-button previous" @click="app.prevButton()"></button>
</div>
<div class="app-chrome-item">
<button class="playback-button pause" @click="app.mk.pause()" v-if="app.mk.isPlaying"></button>
<button class="playback-button play" @click="app.mk.play()" v-else></button>
</div>
<div class="app-chrome-item">
<button class="playback-button next" @click="app.mk.skipToNextItem()"></button>
</div>
<div class="app-chrome-item">
<button class="playback-button--small repeat" v-if="app.mk.repeatMode == 0"
@click="app.mk.repeatMode = 1"></button>
<button class="playback-button--small repeat active" @click="app.mk.repeatMode = 2"
v-else-if="app.mk.repeatMode == 1"></button>
<button class="playback-button--small repeat repeatOne" @click="app.mk.repeatMode = 0"
v-else-if="app.mk.repeatMode == 2"></button>
</div>
</div>
</div>
</template>
</div> </div>
</div> </div>
<div class="col right-col">
<!-- <div class="fs-info">
<div>Name</div>
<div>Name</div>
<div>Name</div>
</div> -->
<div class="lyrics-col">
<lyrics-view :yoffset="10" :time="time" :lyrics="lyrics"
:richlyrics="richlyrics"></lyrics-view>
<div>
</div>
</div> </div>
@ -25,6 +93,29 @@
<script> <script>
Vue.component('fullscreen-view', { Vue.component('fullscreen-view', {
template: '#fullscreen-view', template: '#fullscreen-view',
props: {
time: {
type: Number,
required: false
},
lyrics: {
type: Array,
required: false
},
richlyrics: {
type: Array,
required: false
},
image: {
type: String,
required: false
}
},
data: function(){
return {
app : this.$root,
}
},
methods: { methods: {
sayHello: function () { sayHello: function () {
alert('Hello world!'); alert('Hello world!');

View file

@ -42,16 +42,15 @@
<script> <script>
Vue.component('lyrics-view', { Vue.component('lyrics-view', {
template: '#lyrics-view', template: '#lyrics-view',
props: ["time", "lyrics", "richlyrics", "translation", "onindex"], props: ["time", "lyrics", "richlyrics", "translation", "onindex", "yoffset"],
data: function () { data: function () {
return { return {
app: this.$root, app: this.$root,
} }
}, },
watch: { watch: {
time: function () { time: function () {
if (app.lyricon && app.drawer.open && this.$refs.lyricsview) { if (((app.lyricon && app.drawer.open) || app.appMode == 'fullscreen') && this.$refs.lyricsview) {
let currentLine = this.$refs.lyricsview.querySelector(`.lyric-line.active`) let currentLine = this.$refs.lyricsview.querySelector(`.lyric-line.active`)
if (currentLine && currentLine.getElementsByClassName('lyricWaiting').length > 0) { if (currentLine && currentLine.getElementsByClassName('lyricWaiting').length > 0) {
let duration = currentLine.getAttribute("end") - currentLine.getAttribute("start"); let duration = currentLine.getAttribute("end") - currentLine.getAttribute("start");
@ -119,17 +118,16 @@
if(startTime != 9999999) this.app.seekTo(startTime, false); if(startTime != 9999999) this.app.seekTo(startTime, false);
}, },
getActiveLyric() { getActiveLyric() {
// console.log(this.time);
const delayfix = 0.1 const delayfix = 0.1
const prevLine = app.currentLyricsLine; const prevLine = app.currentLyricsLine;
for (var i = 0; i < this.lyrics.length; i++) { for (var i = 0; i < this.lyrics.length; i++) {
if (this.time + delayfix >= this.lyrics[i].startTime && this.time + delayfix <= app.lyrics[i].endTime) { if (this.time + delayfix >= this.lyrics[i].startTime && this.time + delayfix <= app.lyrics[i].endTime) {
if (app.currentLyricsLine != i) { if (app.currentLyricsLine != i) {
app.currentLyricsLine = i; app.currentLyricsLine = i;
if (app.lyricon && app.drawer.open && this.$refs.lyricsview.querySelector(`.lyric-line[line-index="${i}"]`)) { if (((app.lyricon && app.drawer.open) || app.appMode == 'fullscreen') && this.$refs.lyricsview.querySelector(`.lyric-line[line-index="${i}"]`)) {
if(this.$refs.lyricsview.querySelector(`.lyric-line[line-index="${prevLine}"]`)) {this.$refs.lyricsview.querySelector(`.lyric-line[line-index="${prevLine}"]`).classList.remove("active");} if(this.$refs.lyricsview.querySelector(`.lyric-line[line-index="${prevLine}"]`)) {this.$refs.lyricsview.querySelector(`.lyric-line[line-index="${prevLine}"]`).classList.remove("active");}
this.$refs.lyricsview.querySelector(`.lyric-line[line-index="${i}"]`).classList.add("active") this.$refs.lyricsview.querySelector(`.lyric-line[line-index="${i}"]`).classList.add("active")
if (checkIfScrollIsStatic) { if (this.checkIfScrollIsStatic) {
let lyricElement = this.$refs.lyricsview.querySelector(`.lyric-line[line-index="${i}"]`) let lyricElement = this.$refs.lyricsview.querySelector(`.lyric-line[line-index="${i}"]`)
// this.$refs.lyricsview.querySelector(`.lyric-line[line-index="${i}"]`).scrollIntoView({ // this.$refs.lyricsview.querySelector(`.lyric-line[line-index="${i}"]`).scrollIntoView({
// behavior: "smooth", // behavior: "smooth",
@ -149,7 +147,7 @@
let scrollTop = parent.scrollTop + scrollTopDiff let scrollTop = parent.scrollTop + scrollTopDiff
let scrollLeft = parent.scrollLeft + scrollLeftDiff let scrollLeft = parent.scrollLeft + scrollLeftDiff
parent.scrollTo({ parent.scrollTo({
top: scrollTop - 128, top: scrollTop - (this.yoffset ?? 128),
left: scrollLeft, left: scrollLeft,
behavior: 'smooth' behavior: 'smooth'
}) })
@ -164,7 +162,7 @@
} }
} }
try{ try{
if (app.drawer.open){ if ((app.drawer.open) || app.appMode == 'fullscreen'){
try{this.$refs.lyricsview.querySelector(`.lyric-line[line-index="${prevLine}"]`).childNodes.classList.remove("verse-active");} catch(e){} try{this.$refs.lyricsview.querySelector(`.lyric-line[line-index="${prevLine}"]`).childNodes.classList.remove("verse-active");} catch(e){}
for (child of this.$refs.lyricsview.querySelector(`.lyric-line[line-index="${app.currentLyricsLine}"]`).querySelectorAll(".verse")){ for (child of this.$refs.lyricsview.querySelector(`.lyric-line[line-index="${app.currentLyricsLine}"]`).querySelectorAll(".verse")){
if (this.time + 0.1 >= child.getAttribute("lyricstart") * 1 + child.getAttribute("versestart") * 1){ if (this.time + 0.1 >= child.getAttribute("lyricstart") * 1 + child.getAttribute("versestart") * 1){
@ -184,7 +182,18 @@
return this.richlyrics[index].l return this.richlyrics[index].l
} }
else return [] else return []
},
checkIfScrollIsStatic : setInterval(() => {
try {
if (position === this.$refs.lyricsview.scrollTop) {
clearInterval(checkIfScrollIsStatic)
// do something
}
position = this.$refs.lyricsview.scrollTop
} catch (e) {
} }
}, 50)
,
} }
}); });
</script> </script>

View file

@ -27,7 +27,7 @@
</div> </div>
</div> </div>
<div class="info-rect" :class="{'info-rect-card': kind == 'card'}" :style="{'--bgartwork': getArtworkUrl(size, true)}"> <div class="info-rect" :class="{'info-rect-card': kind == 'card'}" :style="{'--bgartwork': getArtworkUrl(size, true)}">
<div class="title" v-if="item.attributes.artistNames == null || kind!= 'card'" @click.self='app.routeView(item)'> <div class="title" v-if="item.attributes.artistNames == null || kind!= 'card'" @click='app.routeView(item)'>
<div class="item-navigate text-overflow-elipsis">{{ item.attributes.name }}</div> <div class="item-navigate text-overflow-elipsis">{{ item.attributes.name }}</div>
<div v-if="item.attributes && item.attributes.contentRating == 'explicit'" style= "margin-top: -2.6px;margin-left: 3px;">🅴</div> <div v-if="item.attributes && item.attributes.contentRating == 'explicit'" style= "margin-top: -2.6px;margin-left: 3px;">🅴</div>
</div> </div>

View file

@ -69,7 +69,9 @@
<template v-if="mkReady()"> <template v-if="mkReady()">
<div class="app-playback-controls" @mouseover="chrome.progresshover = true" <div class="app-playback-controls" @mouseover="chrome.progresshover = true"
@mouseleave="chrome.progresshover = false" @contextmenu="nowPlayingContextMenu"> @mouseleave="chrome.progresshover = false" @contextmenu="nowPlayingContextMenu">
<div class="artwork"></div> <div class="artwork" @click="drawer.open = false; appMode = 'fullscreen'">
<img class="small" :url="currentArtUrl"></img>
</div>
<div class="playback-info"> <div class="playback-info">
<div class="song-name"> <div class="song-name">
{{ mk.nowPlayingItem["attributes"]["name"] }} {{ mk.nowPlayingItem["attributes"]["name"] }}
@ -466,7 +468,7 @@
</transition> </transition>
<transition name="fsModeSwitch"> <transition name="fsModeSwitch">
<div class="fullscreen-view-container" v-if="appMode == 'fullscreen'"> <div class="fullscreen-view-container" v-if="appMode == 'fullscreen'">
<fullscreen-view></fullscreen-view> <fullscreen-view :image="currentArtUrl.replace('50x50', '600x600')" :time="lyriccurrenttime" :lyrics="lyrics" :richlyrics="richlyrics"></fullscreen-view>
</div> </div>
</transition> </transition>
<transition name="wpfade"> <transition name="wpfade">