mirror of
https://github.com/algerkong/AlgerMusicPlayer.git
synced 2026-04-14 23:11:00 +08:00
feat: 优化移动端适配
This commit is contained in:
@@ -38,6 +38,7 @@
|
||||
:title="album.name"
|
||||
:subtitle="getArtistNames(album)"
|
||||
:tracks="albumTracksMap[album.id] || []"
|
||||
:show-hover-tracks="!isMobile"
|
||||
:animation-delay="calculateAnimationDelay(index, 0.04)"
|
||||
@click="handleAlbumClick(album)"
|
||||
@play="playAlbum(album)"
|
||||
@@ -62,7 +63,7 @@ import { getAlbum } from '@/api/list';
|
||||
import { navigateToMusicList } from '@/components/common/MusicListNavigator';
|
||||
import { usePlayerCoreStore } from '@/store/modules/playerCore';
|
||||
import { usePlaylistStore } from '@/store/modules/playlist';
|
||||
import { calculateAnimationDelay, isElectron } from '@/utils';
|
||||
import { calculateAnimationDelay, isElectron, isMobile } from '@/utils';
|
||||
|
||||
import HomeListItem from './HomeListItem.vue';
|
||||
|
||||
@@ -104,7 +105,7 @@ const fetchAlbums = async () => {
|
||||
if (data.code === 200) {
|
||||
albums.value = data.weekData || data.monthData || data.albums || [];
|
||||
// Preload tracks for displayed albums (Electron only)
|
||||
if (isElectron) {
|
||||
if (isElectron && !isMobile.value) {
|
||||
preloadAllTracks();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -68,7 +68,7 @@ import { onMounted, ref } from 'vue';
|
||||
|
||||
import { getHotSinger } from '@/api/home';
|
||||
import { useArtist } from '@/hooks/useArtist';
|
||||
import { calculateAnimationDelay, getImgUrl } from '@/utils';
|
||||
import { calculateAnimationDelay, getImgUrl, isMobile } from '@/utils';
|
||||
|
||||
const props = defineProps<{
|
||||
title: string;
|
||||
@@ -100,6 +100,7 @@ const fetchArtists = async () => {
|
||||
|
||||
// Enhanced horizontal scroll with wheel support
|
||||
const handleWheel = (e: WheelEvent) => {
|
||||
if (isMobile.value) return;
|
||||
if (!scrollContainer.value) return;
|
||||
|
||||
// Prevent default vertical scroll
|
||||
@@ -161,7 +162,7 @@ onMounted(() => {
|
||||
-webkit-overflow-scrolling: touch;
|
||||
|
||||
/* Optimize for touch */
|
||||
touch-action: pan-x;
|
||||
touch-action: pan-x pan-y;
|
||||
}
|
||||
|
||||
.artists-track {
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
<!-- Hover Overlay with Song Preview -->
|
||||
<div
|
||||
v-if="showHoverTracks"
|
||||
class="absolute inset-0 flex items-end opacity-0 transition-all duration-500 ease-out group-hover:opacity-100"
|
||||
:style="overlayStyle"
|
||||
>
|
||||
@@ -108,10 +109,12 @@ const props = withDefaults(
|
||||
badgeType?: 'new' | 'hot' | 'recommend';
|
||||
playCount?: number;
|
||||
animationDelay?: string;
|
||||
showHoverTracks?: boolean;
|
||||
}>(),
|
||||
{
|
||||
tracks: () => [],
|
||||
animationDelay: '0s'
|
||||
animationDelay: '0s',
|
||||
showHoverTracks: true
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
@@ -18,10 +18,7 @@
|
||||
</div>
|
||||
|
||||
<!-- Loading Skeleton -->
|
||||
<div
|
||||
v-if="loading"
|
||||
class="songs-grid grid grid-cols-1 gap-3 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 xl:grid-cols-5"
|
||||
>
|
||||
<div v-if="loading" class="songs-grid grid gap-3" :class="gridClass">
|
||||
<div
|
||||
v-for="i in 10"
|
||||
:key="i"
|
||||
@@ -30,10 +27,7 @@
|
||||
</div>
|
||||
|
||||
<!-- Songs Grid (Even columns: 1→2→3→4→5) -->
|
||||
<div
|
||||
v-else
|
||||
class="songs-grid grid grid-cols-1 gap-2 md:gap-3 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 xl:grid-cols-5"
|
||||
>
|
||||
<div v-else class="songs-grid grid gap-2 md:gap-3" :class="gridClass">
|
||||
<song-item
|
||||
v-for="(song, index) in songs"
|
||||
:key="song.id"
|
||||
@@ -49,14 +43,14 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { onMounted, ref } from 'vue';
|
||||
import { computed, onMounted, ref } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
|
||||
import { getRecommendMusic } from '@/api/home';
|
||||
import SongItem from '@/components/common/SongItem.vue';
|
||||
import { usePlayerStore } from '@/store';
|
||||
import { SongResult } from '@/types/music';
|
||||
import { calculateAnimationDelay } from '@/utils';
|
||||
import { calculateAnimationDelay, isMobile } from '@/utils';
|
||||
|
||||
const props = defineProps<{
|
||||
title: string;
|
||||
@@ -67,6 +61,11 @@ const { t } = useI18n();
|
||||
const playerStore = usePlayerStore();
|
||||
const songs = ref<SongResult[]>([]);
|
||||
const loading = ref(true);
|
||||
const gridClass = computed(() =>
|
||||
isMobile.value
|
||||
? 'grid-cols-1 sm:grid-cols-2'
|
||||
: 'grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 xl:grid-cols-5'
|
||||
);
|
||||
|
||||
const fetchSongs = async () => {
|
||||
try {
|
||||
|
||||
@@ -60,7 +60,7 @@ import { getListDetail } from '@/api/list';
|
||||
import { navigateToMusicList } from '@/components/common/MusicListNavigator';
|
||||
import { usePlayerCoreStore } from '@/store/modules/playerCore';
|
||||
import { usePlaylistStore } from '@/store/modules/playlist';
|
||||
import { calculateAnimationDelay, isElectron } from '@/utils';
|
||||
import { calculateAnimationDelay, isElectron, isMobile } from '@/utils';
|
||||
|
||||
import HomeListItem from './HomeListItem.vue';
|
||||
|
||||
@@ -88,8 +88,13 @@ const playlists = ref<any[]>([]);
|
||||
const loading = ref(true);
|
||||
const playlistTracksMap = reactive<Record<number, any[]>>({});
|
||||
|
||||
const effectiveColumns = computed(() =>
|
||||
isMobile.value ? Math.min(2, props.columns) : props.columns
|
||||
);
|
||||
const effectiveRows = computed(() => (isMobile.value ? 2 : props.rows));
|
||||
|
||||
// Calculate display count to fill exactly N rows
|
||||
const displayCount = computed(() => props.columns * props.rows);
|
||||
const displayCount = computed(() => effectiveColumns.value * effectiveRows.value);
|
||||
|
||||
const displayPlaylists = computed(() => {
|
||||
const count = displayCount.value;
|
||||
@@ -97,7 +102,7 @@ const displayPlaylists = computed(() => {
|
||||
});
|
||||
|
||||
const gridStyle = computed(() => ({
|
||||
gridTemplateColumns: `repeat(${props.columns}, minmax(0, 1fr))`
|
||||
gridTemplateColumns: `repeat(${effectiveColumns.value}, minmax(0, 1fr))`
|
||||
}));
|
||||
|
||||
const fetchPlaylists = async () => {
|
||||
|
||||
Reference in New Issue
Block a user