use reactive songlist element size to show song details selectively

This commit is contained in:
geoffrey45
2022-08-27 20:57:21 +03:00
parent f26e952703
commit a9ce08b092
4 changed files with 130 additions and 58 deletions
+9 -3
View File
@@ -5,13 +5,18 @@
<div id="app-grid"> <div id="app-grid">
<LeftSidebar /> <LeftSidebar />
<NavBar /> <NavBar />
<div id="acontent" class="rounded"> <div
id="acontent"
class="rounded"
:style="{
marginBottom: !settings.use_alt_np ? '-1rem' : '0',
}"
>
<router-view /> <router-view />
</div> </div>
<NowPlayingRight /> <NowPlayingRight />
<SearchInput /> <SearchInput />
<RightSideBar /> <RightSideBar />
<!-- <Tabs /> -->
</div> </div>
</template> </template>
@@ -27,7 +32,6 @@ import handleShortcuts from "@/composables/useKeyboard";
import Modal from "@/components/modal.vue"; import Modal from "@/components/modal.vue";
import NavBar from "@/components/nav/NavBar.vue"; import NavBar from "@/components/nav/NavBar.vue";
// import Tabs from "@/components/RightSideBar/Tabs.vue";
import ContextMenu from "@/components/contextMenu.vue"; import ContextMenu from "@/components/contextMenu.vue";
import Notification from "@/components/Notification.vue"; import Notification from "@/components/Notification.vue";
@@ -35,6 +39,7 @@ import RightSideBar from "@/components/RightSideBar/Main.vue";
import SearchInput from "@/components/RightSideBar/SearchInput.vue"; import SearchInput from "@/components/RightSideBar/SearchInput.vue";
import NowPlayingRight from "@/components/RightSideBar/NowPlayingRight.vue"; import NowPlayingRight from "@/components/RightSideBar/NowPlayingRight.vue";
import LeftSidebar from "./components/LeftSidebar/index.vue"; import LeftSidebar from "./components/LeftSidebar/index.vue";
import useSettingsStore from "@/stores/settings";
import { readLocalStorage, writeLocalStorage } from "@/utils"; import { readLocalStorage, writeLocalStorage } from "@/utils";
@@ -42,6 +47,7 @@ const queue = useQStore();
const router = useRouter(); const router = useRouter();
const modal = useModalStore(); const modal = useModalStore();
const context_store = useContextStore(); const context_store = useContextStore();
const settings = useSettingsStore();
const app_dom = document.getElementById("app") as HTMLElement; const app_dom = document.getElementById("app") as HTMLElement;
queue.readQueue(); queue.readQueue();
+76 -24
View File
@@ -1,38 +1,46 @@
<template> <template>
<div class="folder"> <div
<div class="table rounded" v-if="tracks.length"> class="table rounded"
<div class="header"> v-if="tracks.length"
<div class="disc-number" v-if="disc">Disc {{ disc }}</div> ref="tracklistElem"
<div class="disc-number" v-if="$route.name === Routes.folder"> :class="{
In this folder isSmall: isSmall,
</div> isMedium: isMedium,
</div> }"
<div class="songlist"> >
<SongItem <div class="header">
v-for="track in getTrackList()" <div class="disc-number" v-if="disc">Disc {{ disc }}</div>
:key="track.trackid" <div class="disc-number" v-if="$route.name === Routes.folder">
:track="track" In this folder
:index="track.index"
@updateQueue="updateQueue"
:isPlaying="queue.playing"
:isCurrent="queue.currentid == track.trackid"
:isHighlighted="($route.query.highlight as string) == track.hash"
/>
</div> </div>
</div> </div>
<div v-else-if="tracks.length === 0"> <div class="songlist">
<div class="no-results"> <SongItem
<div class="text">No tracks here</div> v-for="track in getTrackList()"
</div> :key="track.trackid"
:track="track"
:index="track.index"
@updateQueue="updateQueue"
:isPlaying="queue.playing"
:isCurrent="queue.currentid == track.trackid"
:isHighlighted="($route.query.highlight as string) == track.hash"
/>
</div> </div>
<div class="copyright" v-if="copyright && copyright()"> <div class="copyright" v-if="copyright && copyright()">
{{ copyright() }} {{ copyright() }}
</div> </div>
</div> </div>
<div v-else-if="tracks.length === 0">
<div class="no-results">
<div class="text">No tracks here</div>
</div>
</div>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { onMounted, onUpdated, ref } from "vue";
import { onBeforeRouteUpdate, useRoute } from "vue-router"; import { onBeforeRouteUpdate, useRoute } from "vue-router";
import { useElementSize } from "@vueuse/core";
import SongItem from "../shared/SongItem.vue"; import SongItem from "../shared/SongItem.vue";
@@ -41,7 +49,7 @@ import { Track } from "@/interfaces";
import useAlbumStore from "@/stores/pages/album"; import useAlbumStore from "@/stores/pages/album";
import useQStore from "@/stores/queue"; import useQStore from "@/stores/queue";
import { focusElem } from "@/utils"; import { focusElem } from "@/utils";
import { onMounted, onUpdated, ref } from "vue"; import { computed } from "@vue/reactivity";
const queue = useQStore(); const queue = useQStore();
const album = useAlbumStore(); const album = useAlbumStore();
@@ -60,6 +68,17 @@ const route = useRoute();
const routename = route.name as string; const routename = route.name as string;
const highlightid = ref(route.query.highlight as string | null); const highlightid = ref(route.query.highlight as string | null);
const tracklistElem = ref<HTMLElement | null>(null);
const { width, height } = useElementSize(tracklistElem);
const brk = {
sm: 500,
md: 800,
};
const isSmall = computed(() => width.value < brk.sm);
const isMedium = computed(() => width.value > brk.sm && width.value < brk.md);
function highlightTrack(t_hash: string) { function highlightTrack(t_hash: string) {
focusElem(`track-${t_hash}`, 500, "center"); focusElem(`track-${t_hash}`, 500, "center");
} }
@@ -229,4 +248,37 @@ function getTrackList() {
} }
} }
} }
.table.isSmall {
.songlist-item {
grid-template-columns: 1.5rem 1.5fr 2rem 2.5rem;
}
.song-artists,
.song-album {
display: none !important;
}
.isSmallArtists {
display: unset !important;
font-size: small;
opacity: 0.7;
}
}
.table.isMedium {
.songlist-item {
grid-template-columns: 1.5rem 1.5fr 1fr 2rem 2.5rem;
}
.song-album {
display: none !important;
}
}
// .table.isLarge {
// .songlist-item {
// grid-template-columns: 1.5rem 1.5fr 1fr 1fr 2rem 2.5rem;
// }
// }
</style> </style>
+17
View File
@@ -0,0 +1,17 @@
<template>
<div class="ellip" v-if="artists[0] !== ''">
<span v-for="artist in putCommas(artists)" :key="artist">{{ artist }}</span>
</div>
<div class="ellip" v-else>
<span>{{ albumartist }}</span>
</div>
</template>
<script setup lang="ts">
import { putCommas } from "@/utils";
defineProps<{
artists: string[];
albumartist: string | undefined;
}>();
</script>
+28 -31
View File
@@ -27,24 +27,20 @@
:class="{ last_played: !isPlaying }" :class="{ last_played: !isPlaying }"
></div> ></div>
</div> </div>
<div @click="emitUpdate(track)"> <div>
<div class="title ellip"> <div class="title ellip" @click="emitUpdate(track)">
{{ track.title }} {{ track.title }}
</div> </div>
<div class="isSmallArtists" style="display: none;">
<ArtistName
:artists="track.artists"
:albumartist="track.albumartist"
/>
</div>
</div> </div>
</div> </div>
<div class="song-artists"> <div class="song-artists">
<div class="ellip" v-if="track.artists[0] !== ''"> <ArtistName :artists="track.artists" :albumartist="track.albumartist" />
<span
class="artist"
v-for="artist in putCommas(track.artists)"
:key="artist"
>{{ artist }}</span
>
</div>
<div class="ellip" v-else>
<span class="artist">{{ track.albumartist }}</span>
</div>
</div> </div>
<router-link <router-link
class="song-album ellip" class="song-album ellip"
@@ -78,7 +74,8 @@ import OptionSvg from "@/assets/icons/more.svg";
import { showTrackContextMenu as showContext } from "@/composables/context"; import { showTrackContextMenu as showContext } from "@/composables/context";
import { paths } from "@/config"; import { paths } from "@/config";
import { Track } from "@/interfaces"; import { Track } from "@/interfaces";
import { formatSeconds, putCommas } from "@/utils"; import { formatSeconds } from "@/utils";
import ArtistName from "./ArtistName.vue";
const context_on = ref(false); const context_on = ref(false);
const imguri = paths.images.thumb; const imguri = paths.images.thumb;
@@ -110,26 +107,26 @@ function showMenu(e: Event) {
display: grid; display: grid;
grid-template-columns: 1.5rem 1.5fr 1fr 1.5fr 2rem 2.5rem; grid-template-columns: 1.5rem 1.5fr 1fr 1.5fr 2rem 2.5rem;
align-items: center; align-items: center;
justify-items: flex-start; justify-content: flex-start;
height: 3.75rem; height: 3.75rem;
gap: 1rem; gap: 1rem;
user-select: none; user-select: none;
@include for-desktop-down { // @include for-desktop-down {
grid-template-columns: 1.5rem 1.5fr 1fr 2.5rem; // grid-template-columns: 1.5rem 1.5fr 1fr 2.5rem;
.song-album { // .song-album {
display: none !important; // display: none !important;
} // }
.song-duration { // .song-duration {
display: none !important; // display: none !important;
} // }
} // }
@include tablet-portrait { // @include tablet-portrait {
grid-template-columns: 1.5rem 1.5fr 1fr 2.5rem; // grid-template-columns: 1.5rem 1.5fr 1fr 2.5rem;
} // }
&:hover { &:hover {
background-color: $gray4; background-color: $gray4;
@@ -162,7 +159,7 @@ function showMenu(e: Event) {
} }
.song-duration { .song-duration {
font-size: 0.9rem; font-size: small;
text-align: left; text-align: left;
.ellip { .ellip {
@@ -236,9 +233,9 @@ function showMenu(e: Event) {
td:nth-child(2) { td:nth-child(2) {
border-radius: 0 $small $small 0; border-radius: 0 $small $small 0;
@include phone-only { // @include phone-only {
border-radius: $small; // border-radius: $small;
} // }
} }
} }
</style> </style>