mirror of
https://github.com/tcsenpai/swingmusic.git
synced 2025-06-08 20:25:52 +00:00
client: move table items to a independent component
This commit is contained in:
parent
17cbe14217
commit
521c195570
@ -272,7 +272,6 @@ def getArtistData(artist: str):
|
|||||||
@cache.cached()
|
@cache.cached()
|
||||||
def getFolderTree(folder: str = None):
|
def getFolderTree(folder: str = None):
|
||||||
req_dir = folder.replace('|', '/')
|
req_dir = folder.replace('|', '/')
|
||||||
print(folder)
|
|
||||||
|
|
||||||
if folder == "home":
|
if folder == "home":
|
||||||
req_dir = home_dir
|
req_dir = home_dir
|
||||||
@ -316,7 +315,6 @@ def getFolderTree(folder: str = None):
|
|||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
print(song['image'])
|
|
||||||
song['image'] = img_path + song['image']
|
song['image'] = img_path + song['image']
|
||||||
|
|
||||||
return {"files": remove_duplicates(songs), "folders": sorted(folders, key=lambda i: i['name'])}
|
return {"files": remove_duplicates(songs), "folders": sorted(folders, key=lambda i: i['name'])}
|
||||||
|
@ -52,7 +52,7 @@ export default {
|
|||||||
background-image: url(../../assets/icons/folder.svg);
|
background-image: url(../../assets/icons/folder.svg);
|
||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
background-position: 1rem;
|
background-position: 1rem;
|
||||||
background-size: 10% 100%;
|
background-size: 1.5rem;
|
||||||
background-color: rgb(22, 36, 85);
|
background-color: rgb(22, 36, 85);
|
||||||
transition: all 0.2s ease;
|
transition: all 0.2s ease;
|
||||||
|
|
||||||
|
@ -11,62 +11,17 @@
|
|||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr
|
<SongItem
|
||||||
|
:searchSongs="searchSongs"
|
||||||
|
:songTitleWidth="songTitleWidth"
|
||||||
|
:minWidth="minWidth"
|
||||||
v-for="song in searchSongs"
|
v-for="song in searchSongs"
|
||||||
:key="song"
|
:key="song"
|
||||||
|
:song="song"
|
||||||
|
:current="current"
|
||||||
:class="{ current: current._id == song._id }"
|
:class="{ current: current._id == song._id }"
|
||||||
>
|
@updateQueue="updateQueue"
|
||||||
<td
|
/>
|
||||||
:style="{ width: songTitleWidth + 'px' }"
|
|
||||||
class="flex"
|
|
||||||
@click="updateQueue(song), playAudio(song.filepath)"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="album-art rounded image"
|
|
||||||
:style="{
|
|
||||||
backgroundImage: `url("${song.image}")`,
|
|
||||||
}"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="now-playing-track image"
|
|
||||||
v-if="current._id == song._id"
|
|
||||||
:class="{ active: is_playing, not_active: !is_playing }"
|
|
||||||
></div>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<span class="ellip">{{ song.title }}</span>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
<td :style="{ width: songTitleWidth + 'px' }">
|
|
||||||
<div class="ellip" v-if="song.artists[0] != ''">
|
|
||||||
<span
|
|
||||||
class="artist"
|
|
||||||
v-for="artist in putCommas(song.artists)"
|
|
||||||
:key="artist"
|
|
||||||
>{{ artist }}</span
|
|
||||||
>
|
|
||||||
</div>
|
|
||||||
<div class="ellip" v-else>
|
|
||||||
<span class="artist">{{ song.album_artist }}</span>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
<td :style="{ width: songTitleWidth + 'px' }">
|
|
||||||
<router-link
|
|
||||||
class="ellip"
|
|
||||||
:to="{
|
|
||||||
name: 'AlbumView',
|
|
||||||
params: { album: song.album, artist: song.album_artist },
|
|
||||||
}"
|
|
||||||
>{{ song.album }}</router-link
|
|
||||||
>
|
|
||||||
</td>
|
|
||||||
<td
|
|
||||||
:style="{ width: songTitleWidth + 'px' }"
|
|
||||||
v-if="songTitleWidth > minWidth"
|
|
||||||
>
|
|
||||||
{{ `${Math.trunc(song.length / 60)} min` }}
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
@ -84,30 +39,21 @@
|
|||||||
import { computed, ref, toRefs } from "@vue/reactivity";
|
import { computed, ref, toRefs } from "@vue/reactivity";
|
||||||
import { onMounted, onUnmounted } from "@vue/runtime-core";
|
import { onMounted, onUnmounted } from "@vue/runtime-core";
|
||||||
|
|
||||||
import audio from "@/composables/playAudio.js";
|
import SongItem from "../SongItem.vue";
|
||||||
import perks from "@/composables/perks.js";
|
import perks from "@/composables/perks.js";
|
||||||
import state from "@/composables/state.js";
|
import state from "@/composables/state.js";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
props: ["songs"],
|
props: ["songs"],
|
||||||
|
components: {
|
||||||
|
SongItem,
|
||||||
|
},
|
||||||
setup(props) {
|
setup(props) {
|
||||||
const song_list = toRefs(props).songs;
|
const song_list = toRefs(props).songs;
|
||||||
const songtitle = ref(null);
|
const songtitle = ref(null);
|
||||||
const songTitleWidth = ref(null);
|
const songTitleWidth = ref(null);
|
||||||
|
|
||||||
const minWidth = ref(300);
|
const minWidth = ref(300);
|
||||||
const putCommas = perks.putCommas;
|
|
||||||
|
|
||||||
const updateQueue = async (song) => {
|
|
||||||
if (state.queue.value[0]._id.$oid !== song_list.value[0]._id.$oid) {
|
|
||||||
const new_queue = song_list.value;
|
|
||||||
localStorage.setItem("queue", JSON.stringify(new_queue));
|
|
||||||
state.queue.value = new_queue;
|
|
||||||
}
|
|
||||||
|
|
||||||
state.current.value = song;
|
|
||||||
localStorage.setItem("current", JSON.stringify(song));
|
|
||||||
};
|
|
||||||
|
|
||||||
const resizeSongTitleWidth = () => {
|
const resizeSongTitleWidth = () => {
|
||||||
try {
|
try {
|
||||||
@ -133,21 +79,26 @@ export default {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
const playAudio = audio.playAudio;
|
|
||||||
const current = ref(perks.current);
|
const current = ref(perks.current);
|
||||||
const search_query = ref(state.search_query);
|
const search_query = ref(state.search_query);
|
||||||
|
|
||||||
function doNothing(e) {
|
const updateQueue = async (song) => {
|
||||||
e.preventDefault();
|
if (state.queue.value[0]._id.$oid !== song_list.value[0]._id.$oid) {
|
||||||
e.stopImmediatePropagation();
|
const new_queue = song_list.value;
|
||||||
console.log('mwathani')
|
localStorage.setItem("queue", JSON.stringify(new_queue));
|
||||||
|
state.queue.value = new_queue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
state.current.value = song;
|
||||||
|
localStorage.setItem("current", JSON.stringify(song));
|
||||||
|
};
|
||||||
|
|
||||||
const searchSongs = computed(() => {
|
const searchSongs = computed(() => {
|
||||||
const songs = [];
|
const songs = [];
|
||||||
|
|
||||||
if (search_query.value.length > 2) {
|
if (search_query.value.length > 2) {
|
||||||
state.loading.value = true;
|
state.loading.value = true;
|
||||||
|
|
||||||
for (let i = 0; i < song_list.value.length; i++) {
|
for (let i = 0; i < song_list.value.length; i++) {
|
||||||
if (
|
if (
|
||||||
song_list.value[i].title
|
song_list.value[i].title
|
||||||
@ -168,16 +119,12 @@ export default {
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
searchSongs,
|
searchSongs,
|
||||||
doNothing,
|
updateQueue,
|
||||||
songtitle,
|
songtitle,
|
||||||
songTitleWidth,
|
songTitleWidth,
|
||||||
minWidth,
|
minWidth,
|
||||||
playAudio,
|
|
||||||
updateQueue,
|
|
||||||
putCommas,
|
|
||||||
current,
|
current,
|
||||||
search_query,
|
search_query,
|
||||||
is_playing: state.is_playing,
|
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
<div>
|
<div>
|
||||||
<p id="title" class="ellipsis">{{ current.title }}</p>
|
<p id="title" class="ellipsis">{{ current.title }}</p>
|
||||||
<hr />
|
<hr />
|
||||||
<div id="artist" v-if="current.artists[0] != ''">
|
<div id="artist" class="ellip" v-if="current.artists[0] != ''">
|
||||||
<span v-for="artist in putCommas(current.artists)" :key="artist">{{
|
<span v-for="artist in putCommas(current.artists)" :key="artist">{{
|
||||||
artist
|
artist
|
||||||
}}</span>
|
}}</span>
|
||||||
|
@ -11,9 +11,9 @@
|
|||||||
}"
|
}"
|
||||||
></div>
|
></div>
|
||||||
<div class="tags">
|
<div class="tags">
|
||||||
<p class="title">{{ next.title }}</p>
|
<p class="title ellip">{{ next.title }}</p>
|
||||||
<hr />
|
<hr />
|
||||||
<p class="artist">
|
<p class="artist ellip">
|
||||||
<span v-for="artist in putCommas(next.artists)" :key="artist">{{
|
<span v-for="artist in putCommas(next.artists)" :key="artist">{{
|
||||||
artist
|
artist
|
||||||
}}</span>
|
}}</span>
|
||||||
|
79
src/components/SongItem.vue
Normal file
79
src/components/SongItem.vue
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
<template>
|
||||||
|
<tr>
|
||||||
|
<td
|
||||||
|
:style="{ width: songTitleWidth + 'px' }"
|
||||||
|
class="flex"
|
||||||
|
@click="emitUpdate(song), playAudio(song.filepath)"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="album-art rounded image"
|
||||||
|
:style="{
|
||||||
|
backgroundImage: `url("${song.image}")`,
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="now-playing-track image"
|
||||||
|
v-if="current._id == song._id"
|
||||||
|
:class="{ active: is_playing, not_active: !is_playing }"
|
||||||
|
></div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<span class="ellip">{{ song.title }}</span>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td :style="{ width: songTitleWidth + 'px' }">
|
||||||
|
<div class="ellip" v-if="song.artists[0] != ''">
|
||||||
|
<span
|
||||||
|
class="artist"
|
||||||
|
v-for="artist in putCommas(song.artists)"
|
||||||
|
:key="artist"
|
||||||
|
>{{ artist }}</span
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
<div class="ellip" v-else>
|
||||||
|
<span class="artist">{{ song.album_artist }}</span>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td :style="{ width: songTitleWidth + 'px' }">
|
||||||
|
<router-link
|
||||||
|
class="ellip"
|
||||||
|
:to="{
|
||||||
|
name: 'AlbumView',
|
||||||
|
params: { album: song.album, artist: song.album_artist },
|
||||||
|
}"
|
||||||
|
>{{ song.album }}</router-link
|
||||||
|
>
|
||||||
|
</td>
|
||||||
|
<td
|
||||||
|
:style="{ width: songTitleWidth + 'px' }"
|
||||||
|
v-if="songTitleWidth > minWidth"
|
||||||
|
>
|
||||||
|
{{ `${Math.trunc(song.length / 60)} min` }}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import perks from "@/composables/perks.js";
|
||||||
|
import state from "@/composables/state.js";
|
||||||
|
import audio from "@/composables/playAudio.js"
|
||||||
|
|
||||||
|
export default {
|
||||||
|
props: ["song", "current", "songTitleWidth", "minWidth"],
|
||||||
|
setup(props, { emit }) {
|
||||||
|
function emitUpdate(song) {
|
||||||
|
emit('updateQueue', song);
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
putCommas: perks.putCommas,
|
||||||
|
emitUpdate,
|
||||||
|
is_playing: state.is_playing,
|
||||||
|
playAudio: audio.playAudio
|
||||||
|
};
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
</style>
|
@ -92,23 +92,35 @@ function focusCurrent() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getElem(identifier, type){
|
||||||
|
switch(type){
|
||||||
|
case "class": {
|
||||||
|
return document.getElementsByClassName(identifier)[0]
|
||||||
|
}
|
||||||
|
case "id": {
|
||||||
|
return document.getElementById(identifier)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function focusSearchBox() {
|
||||||
|
const elem = getElem('search', 'id')
|
||||||
|
|
||||||
|
elem.focus()
|
||||||
|
}
|
||||||
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
watch(current, (new_current) => {
|
watch(current, (new_current) => {
|
||||||
media.showMediaNotif();
|
media.showMediaNotif();
|
||||||
|
|
||||||
new Promise((resolve) => {
|
|
||||||
updateNext(new_current);
|
updateNext(new_current);
|
||||||
updatePrev(new_current);
|
updatePrev(new_current);
|
||||||
resolve();
|
|
||||||
}).then(() => {
|
|
||||||
focusCurrent();
|
|
||||||
});
|
|
||||||
|
|
||||||
localStorage.setItem("current", JSON.stringify(new_current));
|
localStorage.setItem("current", JSON.stringify(new_current));
|
||||||
});
|
});
|
||||||
}, 1000);
|
}, 1000);
|
||||||
|
|
||||||
var key_down_fired = false;
|
let key_down_fired = false;
|
||||||
|
|
||||||
window.addEventListener("keydown", (e) => {
|
window.addEventListener("keydown", (e) => {
|
||||||
let target = e.target;
|
let target = e.target;
|
||||||
@ -134,11 +146,12 @@ window.addEventListener("keydown", (e) => {
|
|||||||
if (!key_down_fired) {
|
if (!key_down_fired) {
|
||||||
key_down_fired = true;
|
key_down_fired = true;
|
||||||
|
|
||||||
|
playAudio.playPrev();
|
||||||
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
key_down_fired = false;
|
key_down_fired = false;
|
||||||
}, 1000);
|
}, 1000);
|
||||||
|
|
||||||
playAudio.playPrev();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -148,6 +161,7 @@ window.addEventListener("keydown", (e) => {
|
|||||||
{
|
{
|
||||||
if (!key_down_fired) {
|
if (!key_down_fired) {
|
||||||
if (target.tagName == "INPUT") return;
|
if (target.tagName == "INPUT") return;
|
||||||
|
e.preventDefault();
|
||||||
key_down_fired = true;
|
key_down_fired = true;
|
||||||
|
|
||||||
playAudio.playPause();
|
playAudio.playPause();
|
||||||
@ -159,18 +173,17 @@ window.addEventListener("keydown", (e) => {
|
|||||||
case "f": {
|
case "f": {
|
||||||
if (!key_down_fired) {
|
if (!key_down_fired) {
|
||||||
if (!ctrlKey) return;
|
if (!ctrlKey) return;
|
||||||
|
e.preventDefault();
|
||||||
|
focusSearchBox()
|
||||||
|
|
||||||
console.log("ctrl + f pressed");
|
|
||||||
key_down_fired = true;
|
key_down_fired = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
window.addEventListener("keyup", (e) => {
|
window.addEventListener("keyup", () => {
|
||||||
if (e.code == "Space") {
|
|
||||||
key_down_fired = false;
|
key_down_fired = false;
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
@ -20,6 +20,8 @@ const playAudio = (path) => {
|
|||||||
})
|
})
|
||||||
.then(() => {
|
.then(() => {
|
||||||
audio.play();
|
audio.play();
|
||||||
|
perks.focusCurrent()
|
||||||
|
|
||||||
state.is_playing.value = true;
|
state.is_playing.value = true;
|
||||||
|
|
||||||
audio.ontimeupdate = () => {
|
audio.ontimeupdate = () => {
|
||||||
@ -41,7 +43,6 @@ function playPrev() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function seek(pos) {
|
function seek(pos) {
|
||||||
console.log(pos);
|
|
||||||
audio.currentTime = (pos / 1000) * audio.duration;
|
audio.currentTime = (pos / 1000) * audio.duration;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -68,4 +69,5 @@ audio.addEventListener("pause", () => {
|
|||||||
audio.addEventListener("ended", () => {
|
audio.addEventListener("ended", () => {
|
||||||
playNext();
|
playNext();
|
||||||
});
|
});
|
||||||
|
|
||||||
export default { playAudio, playNext, playPrev, playPause, seek, pos, playing };
|
export default { playAudio, playNext, playPrev, playPause, seek, pos, playing };
|
||||||
|
Loading…
x
Reference in New Issue
Block a user