mirror of
https://github.com/algerkong/AlgerMusicPlayer.git
synced 2026-04-24 16:27:23 +08:00
feat: 优化移动端界面设计以及歌词界面设计 添加播放模式选择
This commit is contained in:
@@ -39,6 +39,7 @@ export default defineConfig({
|
|||||||
],
|
],
|
||||||
publicDir: resolve('resources'),
|
publicDir: resolve('resources'),
|
||||||
server: {
|
server: {
|
||||||
|
host: '0.0.0.0',
|
||||||
proxy: {
|
proxy: {
|
||||||
// with options
|
// with options
|
||||||
[process.env.VITE_API_LOCAL as string]: {
|
[process.env.VITE_API_LOCAL as string]: {
|
||||||
|
|||||||
@@ -168,42 +168,57 @@ export default {
|
|||||||
},
|
},
|
||||||
lyricSettings: {
|
lyricSettings: {
|
||||||
title: 'Lyric Settings',
|
title: 'Lyric Settings',
|
||||||
|
tabs: {
|
||||||
|
display: 'Display',
|
||||||
|
interface: 'Interface',
|
||||||
|
typography: 'Typography',
|
||||||
|
mobile: 'Mobile'
|
||||||
|
},
|
||||||
pureMode: 'Pure Mode',
|
pureMode: 'Pure Mode',
|
||||||
hideCover: 'Hide Cover',
|
hideCover: 'Hide Cover',
|
||||||
centerDisplay: 'Center Display',
|
centerDisplay: 'Center Display',
|
||||||
showTranslation: 'Show Translation',
|
showTranslation: 'Show Translation',
|
||||||
|
hideLyrics: 'Hide Lyrics',
|
||||||
hidePlayBar: 'Hide Play Bar',
|
hidePlayBar: 'Hide Play Bar',
|
||||||
fontSize: 'Font Size',
|
hideMiniPlayBar: 'Hide Mini Play Bar',
|
||||||
letterSpacing: 'Letter Spacing',
|
|
||||||
lineHeight: 'Line Height',
|
|
||||||
backgroundTheme: 'Background Theme',
|
backgroundTheme: 'Background Theme',
|
||||||
fontSizeMarks: {
|
|
||||||
small: 'Small',
|
|
||||||
medium: 'Medium',
|
|
||||||
large: 'Large'
|
|
||||||
},
|
|
||||||
letterSpacingMarks: {
|
|
||||||
compact: 'Compact',
|
|
||||||
default: 'Default',
|
|
||||||
loose: 'Loose'
|
|
||||||
},
|
|
||||||
lineHeightMarks: {
|
|
||||||
compact: 'Compact',
|
|
||||||
default: 'Default',
|
|
||||||
loose: 'Loose'
|
|
||||||
},
|
|
||||||
themeOptions: {
|
themeOptions: {
|
||||||
default: 'Default',
|
default: 'Default',
|
||||||
light: 'Light',
|
light: 'Light',
|
||||||
dark: 'Dark'
|
dark: 'Dark'
|
||||||
},
|
},
|
||||||
hideMiniPlayBar: 'Hide Mini Play Bar',
|
fontSize: 'Font Size',
|
||||||
hideLyrics: 'Hide Lyrics',
|
fontSizeMarks: {
|
||||||
tabs: {
|
small: 'Small',
|
||||||
interface: 'Interface',
|
medium: 'Medium',
|
||||||
display: 'Display',
|
large: 'Large'
|
||||||
typography: 'Typography'
|
},
|
||||||
}
|
letterSpacing: 'Letter Spacing',
|
||||||
|
letterSpacingMarks: {
|
||||||
|
compact: 'Compact',
|
||||||
|
default: 'Default',
|
||||||
|
loose: 'Loose'
|
||||||
|
},
|
||||||
|
lineHeight: 'Line Height',
|
||||||
|
lineHeightMarks: {
|
||||||
|
compact: 'Compact',
|
||||||
|
default: 'Default',
|
||||||
|
loose: 'Loose'
|
||||||
|
},
|
||||||
|
mobileLayout: 'Mobile Layout',
|
||||||
|
layoutOptions: {
|
||||||
|
default: 'Default',
|
||||||
|
ios: 'iOS Style',
|
||||||
|
android: 'Android Style'
|
||||||
|
},
|
||||||
|
mobileCoverStyle: 'Cover Style',
|
||||||
|
coverOptions: {
|
||||||
|
record: 'Record',
|
||||||
|
square: 'Square',
|
||||||
|
full: 'Full Screen'
|
||||||
|
},
|
||||||
|
lyricLines: 'Lyric Lines',
|
||||||
|
mobileUnavailable: 'This setting is only available on mobile devices'
|
||||||
},
|
},
|
||||||
shortcutSettings: {
|
shortcutSettings: {
|
||||||
title: 'Shortcut Settings',
|
title: 'Shortcut Settings',
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ export default {
|
|||||||
playFailed: '当前歌曲播放失败,播放下一首',
|
playFailed: '当前歌曲播放失败,播放下一首',
|
||||||
playMode: {
|
playMode: {
|
||||||
sequence: '顺序播放',
|
sequence: '顺序播放',
|
||||||
loop: '循环播放',
|
loop: '单曲循环',
|
||||||
random: '随机播放'
|
random: '随机播放'
|
||||||
},
|
},
|
||||||
fullscreen: {
|
fullscreen: {
|
||||||
|
|||||||
@@ -167,19 +167,33 @@ export default {
|
|||||||
portNumber: '请输入有效的端口号(1-65535)'
|
portNumber: '请输入有效的端口号(1-65535)'
|
||||||
},
|
},
|
||||||
lyricSettings: {
|
lyricSettings: {
|
||||||
title: '页面设置',
|
title: '歌词设置',
|
||||||
|
tabs: {
|
||||||
|
display: '显示',
|
||||||
|
interface: '界面',
|
||||||
|
typography: '文字',
|
||||||
|
mobile: '移动端'
|
||||||
|
},
|
||||||
pureMode: '纯净模式',
|
pureMode: '纯净模式',
|
||||||
hideCover: '隐藏封面',
|
hideCover: '隐藏封面',
|
||||||
centerDisplay: '居中显示',
|
centerDisplay: '居中显示',
|
||||||
showTranslation: '显示翻译',
|
showTranslation: '显示翻译',
|
||||||
|
hideLyrics: '隐藏歌词',
|
||||||
hidePlayBar: '隐藏播放栏',
|
hidePlayBar: '隐藏播放栏',
|
||||||
|
hideMiniPlayBar: '隐藏迷你播放栏',
|
||||||
|
backgroundTheme: '背景主题',
|
||||||
|
themeOptions: {
|
||||||
|
default: '默认',
|
||||||
|
light: '亮色',
|
||||||
|
dark: '暗色'
|
||||||
|
},
|
||||||
fontSize: '字体大小',
|
fontSize: '字体大小',
|
||||||
fontSizeMarks: {
|
fontSizeMarks: {
|
||||||
small: '小',
|
small: '小',
|
||||||
medium: '中',
|
medium: '中',
|
||||||
large: '大'
|
large: '大'
|
||||||
},
|
},
|
||||||
letterSpacing: '文字间距',
|
letterSpacing: '字间距',
|
||||||
letterSpacingMarks: {
|
letterSpacingMarks: {
|
||||||
compact: '紧凑',
|
compact: '紧凑',
|
||||||
default: '默认',
|
default: '默认',
|
||||||
@@ -191,19 +205,20 @@ export default {
|
|||||||
default: '默认',
|
default: '默认',
|
||||||
loose: '宽松'
|
loose: '宽松'
|
||||||
},
|
},
|
||||||
backgroundTheme: '背景主题',
|
mobileLayout: '移动端布局',
|
||||||
themeOptions: {
|
layoutOptions: {
|
||||||
default: '默认',
|
default: '默认',
|
||||||
light: '亮色',
|
ios: 'iOS风格',
|
||||||
dark: '暗色'
|
android: '安卓风格'
|
||||||
},
|
},
|
||||||
hideMiniPlayBar: '隐藏迷你播放栏',
|
mobileCoverStyle: '封面样式',
|
||||||
hideLyrics: '隐藏歌词',
|
coverOptions: {
|
||||||
tabs: {
|
record: '唱片',
|
||||||
interface: '界面',
|
square: '方形',
|
||||||
typography: '文字',
|
full: '全屏'
|
||||||
display: '显示'
|
},
|
||||||
}
|
lyricLines: '歌词行数',
|
||||||
|
mobileUnavailable: '此设置仅在移动端可用'
|
||||||
},
|
},
|
||||||
shortcutSettings: {
|
shortcutSettings: {
|
||||||
title: '快捷键设置',
|
title: '快捷键设置',
|
||||||
|
|||||||
@@ -0,0 +1,58 @@
|
|||||||
|
{
|
||||||
|
"settings": {
|
||||||
|
"lyricSettings": {
|
||||||
|
"title": "歌词设置",
|
||||||
|
"tabs": {
|
||||||
|
"display": "显示",
|
||||||
|
"interface": "界面",
|
||||||
|
"typography": "文字",
|
||||||
|
"mobile": "移动端"
|
||||||
|
},
|
||||||
|
"pureMode": "纯净模式",
|
||||||
|
"hideCover": "隐藏封面",
|
||||||
|
"centerDisplay": "居中显示",
|
||||||
|
"showTranslation": "显示翻译",
|
||||||
|
"hideLyrics": "隐藏歌词",
|
||||||
|
"hidePlayBar": "隐藏播放栏",
|
||||||
|
"hideMiniPlayBar": "隐藏迷你播放栏",
|
||||||
|
"backgroundTheme": "背景主题",
|
||||||
|
"themeOptions": {
|
||||||
|
"default": "默认",
|
||||||
|
"light": "亮色",
|
||||||
|
"dark": "暗色"
|
||||||
|
},
|
||||||
|
"fontSize": "字体大小",
|
||||||
|
"fontSizeMarks": {
|
||||||
|
"small": "小",
|
||||||
|
"medium": "中",
|
||||||
|
"large": "大"
|
||||||
|
},
|
||||||
|
"letterSpacing": "字间距",
|
||||||
|
"letterSpacingMarks": {
|
||||||
|
"compact": "紧凑",
|
||||||
|
"default": "默认",
|
||||||
|
"loose": "宽松"
|
||||||
|
},
|
||||||
|
"lineHeight": "行高",
|
||||||
|
"lineHeightMarks": {
|
||||||
|
"compact": "紧凑",
|
||||||
|
"default": "默认",
|
||||||
|
"loose": "宽松"
|
||||||
|
},
|
||||||
|
"mobileLayout": "移动端布局",
|
||||||
|
"layoutOptions": {
|
||||||
|
"default": "默认",
|
||||||
|
"ios": "iOS风格",
|
||||||
|
"android": "安卓风格"
|
||||||
|
},
|
||||||
|
"mobileCoverStyle": "封面样式",
|
||||||
|
"coverOptions": {
|
||||||
|
"record": "唱片",
|
||||||
|
"square": "方形",
|
||||||
|
"full": "全屏"
|
||||||
|
},
|
||||||
|
"lyricLines": "歌词行数",
|
||||||
|
"mobileUnavailable": "此设置仅在移动端可用"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -114,6 +114,47 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</n-tab-pane>
|
</n-tab-pane>
|
||||||
|
|
||||||
|
<!-- 移动端设置 -->
|
||||||
|
<n-tab-pane :name="'mobile'" :tab="t('settings.lyricSettings.tabs.mobile')">
|
||||||
|
<div class="tab-content" v-if="isMobile">
|
||||||
|
<div class="section-title">{{ t('settings.lyricSettings.mobileLayout') }}</div>
|
||||||
|
<n-radio-group v-model:value="config.mobileLayout" name="mobileLayout" class="mb-4">
|
||||||
|
<n-space>
|
||||||
|
<n-radio value="default">{{ t('settings.lyricSettings.layoutOptions.default') }}</n-radio>
|
||||||
|
<n-radio value="ios">{{ t('settings.lyricSettings.layoutOptions.ios') }}</n-radio>
|
||||||
|
<n-radio value="android">{{ t('settings.lyricSettings.layoutOptions.android') }}</n-radio>
|
||||||
|
</n-space>
|
||||||
|
</n-radio-group>
|
||||||
|
|
||||||
|
<div class="section-title">{{ t('settings.lyricSettings.mobileCoverStyle') }}</div>
|
||||||
|
<n-radio-group v-model:value="config.mobileCoverStyle" name="mobileCoverStyle" class="mb-4">
|
||||||
|
<n-space>
|
||||||
|
<n-radio value="record">{{ t('settings.lyricSettings.coverOptions.record') }}</n-radio>
|
||||||
|
<n-radio value="square">{{ t('settings.lyricSettings.coverOptions.square') }}</n-radio>
|
||||||
|
<n-radio value="full">{{ t('settings.lyricSettings.coverOptions.full') }}</n-radio>
|
||||||
|
</n-space>
|
||||||
|
</n-radio-group>
|
||||||
|
|
||||||
|
<div class="slider-item">
|
||||||
|
<span>{{ t('settings.lyricSettings.lyricLines') }}</span>
|
||||||
|
<n-slider
|
||||||
|
v-model:value="config.mobileShowLyricLines"
|
||||||
|
:step="1"
|
||||||
|
:min="1"
|
||||||
|
:max="5"
|
||||||
|
:marks="{
|
||||||
|
1: '1',
|
||||||
|
3: '3',
|
||||||
|
5: '5'
|
||||||
|
}"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div v-else class="mobile-unavailable">
|
||||||
|
{{ t('settings.lyricSettings.mobileUnavailable') }}
|
||||||
|
</div>
|
||||||
|
</n-tab-pane>
|
||||||
</n-tabs>
|
</n-tabs>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -124,6 +165,7 @@ import { onMounted, ref, watch } from 'vue';
|
|||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
|
|
||||||
import { DEFAULT_LYRIC_CONFIG, LyricConfig } from '@/types/lyric';
|
import { DEFAULT_LYRIC_CONFIG, LyricConfig } from '@/types/lyric';
|
||||||
|
import { isMobile } from '@/utils';
|
||||||
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
const config = ref<LyricConfig>({ ...DEFAULT_LYRIC_CONFIG });
|
const config = ref<LyricConfig>({ ...DEFAULT_LYRIC_CONFIG });
|
||||||
@@ -253,4 +295,8 @@ defineExpose({
|
|||||||
color: var(--text-color-active) !important;
|
color: var(--text-color-active) !important;
|
||||||
@apply text-xs;
|
@apply text-xs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.mobile-unavailable {
|
||||||
|
@apply text-center py-4 text-gray-500 text-sm;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -3,7 +3,8 @@
|
|||||||
class="mobile-play-bar"
|
class="mobile-play-bar"
|
||||||
:class="[
|
:class="[
|
||||||
setAnimationClass('animate__fadeInUp'),
|
setAnimationClass('animate__fadeInUp'),
|
||||||
musicFullVisible ? 'play-bar-expanded' : 'play-bar-mini'
|
musicFullVisible ? 'play-bar-expanded' : 'play-bar-mini',
|
||||||
|
!shouldShowMobileMenu ? 'mobile-play-bar-no-menu' : ''
|
||||||
]"
|
]"
|
||||||
:style="{
|
:style="{
|
||||||
color: musicFullVisible
|
color: musicFullVisible
|
||||||
@@ -16,7 +17,7 @@
|
|||||||
}"
|
}"
|
||||||
>
|
>
|
||||||
<!-- 完整模式 - 在musicFullVisible为true时显示 -->
|
<!-- 完整模式 - 在musicFullVisible为true时显示 -->
|
||||||
<template v-if="musicFullVisible">
|
<template v-if="false">
|
||||||
<!-- 顶部信息区域 -->
|
<!-- 顶部信息区域 -->
|
||||||
<div class="music-info-header">
|
<div class="music-info-header">
|
||||||
<div class="music-info-main">
|
<div class="music-info-main">
|
||||||
@@ -61,31 +62,9 @@
|
|||||||
<div class="control-btn next" @click="handleNext">
|
<div class="control-btn next" @click="handleNext">
|
||||||
<i class="iconfont ri-skip-forward-fill"></i>
|
<i class="iconfont ri-skip-forward-fill"></i>
|
||||||
</div>
|
</div>
|
||||||
<n-popover
|
<div class="control-btn list" @click="openPlayListDrawer">
|
||||||
trigger="click"
|
<i class="iconfont ri-menu-line"></i>
|
||||||
:z-index="99999999"
|
</div>
|
||||||
content-class="mobile-play-list"
|
|
||||||
raw
|
|
||||||
:show-arrow="false"
|
|
||||||
placement="top"
|
|
||||||
@update-show="scrollToPlayList"
|
|
||||||
>
|
|
||||||
<template #trigger>
|
|
||||||
<div class="control-btn list">
|
|
||||||
<i class="iconfont ri-menu-line"></i>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
<div class="mobile-play-list-container">
|
|
||||||
<div class="mobile-play-list-back"></div>
|
|
||||||
<n-virtual-list ref="playListRef" :item-size="56" item-resizable :items="playList">
|
|
||||||
<template #default="{ item }">
|
|
||||||
<div class="mobile-play-list-item">
|
|
||||||
<song-item :key="item.id" :item="item" mini></song-item>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
</n-virtual-list>
|
|
||||||
</div>
|
|
||||||
</n-popover>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 定时关闭按钮 -->
|
<!-- 定时关闭按钮 -->
|
||||||
@@ -93,7 +72,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<!-- Mini模式 - 在musicFullVisible为false时显示 -->
|
<!-- Mini模式 - 在musicFullVisible为false时显示 -->
|
||||||
<div v-else class="mobile-mini-controls">
|
<div v-if="!musicFullVisible" class="mobile-mini-controls">
|
||||||
<!-- 歌曲信息 -->
|
<!-- 歌曲信息 -->
|
||||||
<div class="mini-song-info" @click="setMusicFull">
|
<div class="mini-song-info" @click="setMusicFull">
|
||||||
<n-image
|
<n-image
|
||||||
@@ -103,12 +82,13 @@
|
|||||||
preview-disabled
|
preview-disabled
|
||||||
/>
|
/>
|
||||||
<div class="mini-song-text">
|
<div class="mini-song-text">
|
||||||
<n-ellipsis class="mini-song-title" line-clamp="1">
|
<n-ellipsis line-clamp="1">
|
||||||
{{ playMusic.name }}
|
<span class="mini-song-title">{{ playMusic.name }}</span>
|
||||||
</n-ellipsis>
|
<span class="mx-2 text-gray-500 dark:text-gray-400">-</span>
|
||||||
<n-ellipsis class="mini-song-artist" line-clamp="1">
|
<span class="mini-song-artist">
|
||||||
<span v-for="(artists, artistsindex) in artistList" :key="artistsindex">
|
<span v-for="(artists, artistsindex) in artistList" :key="artistsindex">
|
||||||
{{ artists.name }}{{ artistsindex < artistList.length - 1 ? ' / ' : '' }}
|
{{ artists.name }}{{ artistsindex < artistList.length - 1 ? ' / ' : '' }}
|
||||||
|
</span>
|
||||||
</span>
|
</span>
|
||||||
</n-ellipsis>
|
</n-ellipsis>
|
||||||
</div>
|
</div>
|
||||||
@@ -119,34 +99,12 @@
|
|||||||
<div class="mini-control-btn play" @click="playMusicEvent">
|
<div class="mini-control-btn play" @click="playMusicEvent">
|
||||||
<i class="iconfont icon" :class="play ? 'icon-stop' : 'icon-play'"></i>
|
<i class="iconfont icon" :class="play ? 'icon-stop' : 'icon-play'"></i>
|
||||||
</div>
|
</div>
|
||||||
<n-popover
|
<i class="iconfont icon-list mini-list-icon" @click="openPlayListDrawer"></i>
|
||||||
trigger="click"
|
|
||||||
:z-index="99999999"
|
|
||||||
content-class="mobile-play-list"
|
|
||||||
raw
|
|
||||||
:show-arrow="false"
|
|
||||||
placement="top"
|
|
||||||
@update-show="scrollToPlayList"
|
|
||||||
>
|
|
||||||
<template #trigger>
|
|
||||||
<i class="iconfont icon-list mini-list-icon"></i>
|
|
||||||
</template>
|
|
||||||
<div class="mobile-play-list-container">
|
|
||||||
<div class="mobile-play-list-back"></div>
|
|
||||||
<n-virtual-list ref="playListRef" :item-size="56" item-resizable :items="playList">
|
|
||||||
<template #default="{ item }">
|
|
||||||
<div class="mobile-play-list-item">
|
|
||||||
<song-item :key="item.id" :item="item" mini></song-item>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
</n-virtual-list>
|
|
||||||
</div>
|
|
||||||
</n-popover>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 全屏播放器 -->
|
<!-- 全屏播放器 -->
|
||||||
<music-full ref="MusicFullRef" v-model="musicFullVisible" :background="background" />
|
<music-full-wrapper ref="MusicFullRef" v-model="musicFullVisible" :background="background" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -154,21 +112,19 @@
|
|||||||
import { useThrottleFn } from '@vueuse/core';
|
import { useThrottleFn } from '@vueuse/core';
|
||||||
import { computed, ref, watch } from 'vue';
|
import { computed, ref, watch } from 'vue';
|
||||||
|
|
||||||
import SongItem from '@/components/common/SongItem.vue';
|
|
||||||
import { allTime, artistList, nowTime, playMusic, sound, textColors } from '@/hooks/MusicHook';
|
import { allTime, artistList, nowTime, playMusic, sound, textColors } from '@/hooks/MusicHook';
|
||||||
import MusicFull from '@/layout/components/MusicFull.vue';
|
import MusicFullWrapper from '@/layout/components/MusicFullWrapper.vue';
|
||||||
import { usePlayerStore } from '@/store/modules/player';
|
import { usePlayerStore } from '@/store/modules/player';
|
||||||
import { useSettingsStore } from '@/store/modules/settings';
|
import { useSettingsStore } from '@/store/modules/settings';
|
||||||
import type { SongResult } from '@/type/music';
|
|
||||||
import { getImgUrl, secondToMinute, setAnimationClass } from '@/utils';
|
import { getImgUrl, secondToMinute, setAnimationClass } from '@/utils';
|
||||||
|
|
||||||
|
const shouldShowMobileMenu = inject('shouldShowMobileMenu');
|
||||||
|
|
||||||
const playerStore = usePlayerStore();
|
const playerStore = usePlayerStore();
|
||||||
const settingsStore = useSettingsStore();
|
const settingsStore = useSettingsStore();
|
||||||
|
|
||||||
// 是否播放
|
// 是否播放
|
||||||
const play = computed(() => playerStore.isPlay);
|
const play = computed(() => playerStore.isPlay);
|
||||||
// 播放列表
|
|
||||||
const playList = computed(() => playerStore.playList as SongResult[]);
|
|
||||||
// 背景颜色
|
// 背景颜色
|
||||||
const background = ref('#000');
|
const background = ref('#000');
|
||||||
|
|
||||||
@@ -206,14 +162,9 @@ const setMusicFull = () => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// 播放列表引用
|
// 打开播放列表抽屉
|
||||||
const playListRef = ref<any>(null);
|
const openPlayListDrawer = () => {
|
||||||
|
playerStore.setPlayListDrawerVisible(true);
|
||||||
const scrollToPlayList = (val: boolean) => {
|
|
||||||
if (!val) return;
|
|
||||||
setTimeout(() => {
|
|
||||||
playListRef.value?.scrollTo({ top: playerStore.playListIndex * 56 });
|
|
||||||
}, 50);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// 收藏功能
|
// 收藏功能
|
||||||
@@ -251,11 +202,15 @@ watch(
|
|||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.mobile-play-bar {
|
.mobile-play-bar {
|
||||||
@apply fixed bottom-[56px] left-0 w-full flex flex-col shadow-lg;
|
@apply fixed bottom-[56px] left-0 w-full flex flex-col;
|
||||||
z-index: 10000;
|
z-index: 10000;
|
||||||
animation-duration: 0.3s !important;
|
animation-duration: 0.3s !important;
|
||||||
transition: all 0.3s ease;
|
transition: all 0.3s ease;
|
||||||
|
|
||||||
|
&.mobile-play-bar-no-menu {
|
||||||
|
@apply bottom-[10px];
|
||||||
|
}
|
||||||
|
|
||||||
&.play-bar-expanded {
|
&.play-bar-expanded {
|
||||||
@apply bg-transparent;
|
@apply bg-transparent;
|
||||||
height: auto; /* 自动适应内容高度 */
|
height: auto; /* 自动适应内容高度 */
|
||||||
@@ -285,7 +240,7 @@ watch(
|
|||||||
}
|
}
|
||||||
|
|
||||||
&.play-bar-mini {
|
&.play-bar-mini {
|
||||||
@apply h-14 py-0 bg-light dark:bg-dark;
|
@apply h-14 py-0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 顶部信息区域
|
// 顶部信息区域
|
||||||
@@ -423,13 +378,13 @@ watch(
|
|||||||
|
|
||||||
// Mini模式样式
|
// Mini模式样式
|
||||||
.mobile-mini-controls {
|
.mobile-mini-controls {
|
||||||
@apply flex items-center justify-between px-4 h-14;
|
@apply flex items-center justify-between pr-4 mx-3 h-12 rounded-full bg-light-100 dark:bg-dark-100 shadow-lg;
|
||||||
|
|
||||||
.mini-song-info {
|
.mini-song-info {
|
||||||
@apply flex items-center flex-1 min-w-0 cursor-pointer;
|
@apply flex items-center flex-1 min-w-0 cursor-pointer;
|
||||||
|
|
||||||
.mini-song-cover {
|
.mini-song-cover {
|
||||||
@apply w-8 h-8 rounded-md;
|
@apply w-12 h-12 rounded-full border-8 border-dark-300 dark:border-light-300;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mini-song-text {
|
.mini-song-text {
|
||||||
@@ -440,7 +395,7 @@ watch(
|
|||||||
}
|
}
|
||||||
|
|
||||||
.mini-song-artist {
|
.mini-song-artist {
|
||||||
@apply text-xs text-gray-500 dark:text-gray-400 mt-0.5;
|
@apply text-xs text-gray-500 dark:text-gray-400;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -148,8 +148,8 @@
|
|||||||
{{ t('player.playBar.playList') }}
|
{{ t('player.playBar.playList') }}
|
||||||
</n-tooltip>
|
</n-tooltip>
|
||||||
</div>
|
</div>
|
||||||
<!-- 播放音乐 -->
|
<!-- 全屏播放器 -->
|
||||||
<music-full ref="MusicFullRef" v-model="musicFullVisible" :background="background" />
|
<music-full-wrapper ref="MusicFullRef" v-model="musicFullVisible" :background="background" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -169,7 +169,7 @@ import {
|
|||||||
textColors
|
textColors
|
||||||
} from '@/hooks/MusicHook';
|
} from '@/hooks/MusicHook';
|
||||||
import { useArtist } from '@/hooks/useArtist';
|
import { useArtist } from '@/hooks/useArtist';
|
||||||
import MusicFull from '@/layout/components/MusicFull.vue';
|
import MusicFullWrapper from '@/layout/components/MusicFullWrapper.vue';
|
||||||
import { audioService } from '@/services/audioService';
|
import { audioService } from '@/services/audioService';
|
||||||
import {
|
import {
|
||||||
isBilibiliIdMatch,
|
isBilibiliIdMatch,
|
||||||
|
|||||||
@@ -117,6 +117,10 @@ const handleClearPlaylist = () => {
|
|||||||
message.info(t('player.playList.alreadyEmpty'));
|
message.info(t('player.playList.alreadyEmpty'));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(isMobile.value){
|
||||||
|
closePanel();
|
||||||
|
}
|
||||||
|
|
||||||
dialog.warning({
|
dialog.warning({
|
||||||
title: t('player.playList.clearConfirmTitle'),
|
title: t('player.playList.clearConfirmTitle'),
|
||||||
@@ -254,17 +258,18 @@ const handleDeleteSong = (song: SongResult) => {
|
|||||||
// 移动端适配
|
// 移动端适配
|
||||||
@media (max-width: 768px) {
|
@media (max-width: 768px) {
|
||||||
.playlist-panel {
|
.playlist-panel {
|
||||||
|
position: fixed;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 60vh;
|
height: 80vh;
|
||||||
top: auto;
|
top: auto;
|
||||||
bottom: 56px; // 移动端底部留出导航栏高度
|
bottom: 0; // 移动端底部留出导航栏高度
|
||||||
border-radius: 16px 16px 0 0;
|
border-radius: 30px 30px 0 0;
|
||||||
border-left: none;
|
border-left: none;
|
||||||
border-top: 1px solid theme('colors.gray.200');
|
border-top: 1px solid theme('colors.gray.200');
|
||||||
box-shadow: 0 -5px 20px rgba(0, 0, 0, 0.1);
|
box-shadow: 0 -5px 20px rgba(0, 0, 0, 0.1);
|
||||||
|
|
||||||
&-header {
|
&-header {
|
||||||
@apply text-center relative;
|
@apply text-center relative px-4;
|
||||||
|
|
||||||
&::before {
|
&::before {
|
||||||
content: '';
|
content: '';
|
||||||
@@ -280,7 +285,11 @@ const handleDeleteSong = (song: SongResult) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
&-content {
|
&-content {
|
||||||
height: calc(60vh - 60px);
|
height: calc(80vh - 60px);
|
||||||
|
@apply px-4;
|
||||||
|
.delete-btn{
|
||||||
|
@apply visible;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,9 @@ import { useMessage } from 'naive-ui';
|
|||||||
|
|
||||||
import { getSongUrl } from '@/store/modules/player';
|
import { getSongUrl } from '@/store/modules/player';
|
||||||
import type { SongResult } from '@/type/music';
|
import type { SongResult } from '@/type/music';
|
||||||
|
import { isElectron } from '@/utils';
|
||||||
|
|
||||||
|
const ipcRenderer = isElectron ? window.electron.ipcRenderer : null;
|
||||||
|
|
||||||
// 全局下载管理(闭包模式)
|
// 全局下载管理(闭包模式)
|
||||||
const createDownloadManager = () => {
|
const createDownloadManager = () => {
|
||||||
@@ -58,11 +61,11 @@ const createDownloadManager = () => {
|
|||||||
|
|
||||||
// 移除可能存在的旧监听器
|
// 移除可能存在的旧监听器
|
||||||
if (completeListener) {
|
if (completeListener) {
|
||||||
window.electron.ipcRenderer.removeListener('music-download-complete', completeListener);
|
ipcRenderer?.removeListener('music-download-complete', completeListener);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (errorListener) {
|
if (errorListener) {
|
||||||
window.electron.ipcRenderer.removeListener('music-download-error', errorListener);
|
ipcRenderer?.removeListener('music-download-error', errorListener);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 创建新的监听器
|
// 创建新的监听器
|
||||||
@@ -99,8 +102,8 @@ const createDownloadManager = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// 添加监听器
|
// 添加监听器
|
||||||
window.electron.ipcRenderer.on('music-download-complete', completeListener);
|
ipcRenderer?.on('music-download-complete', completeListener);
|
||||||
window.electron.ipcRenderer.on('music-download-error', errorListener);
|
ipcRenderer?.on('music-download-error', errorListener);
|
||||||
|
|
||||||
isInitialized = true;
|
isInitialized = true;
|
||||||
},
|
},
|
||||||
@@ -110,12 +113,12 @@ const createDownloadManager = () => {
|
|||||||
if (!isInitialized) return;
|
if (!isInitialized) return;
|
||||||
|
|
||||||
if (completeListener) {
|
if (completeListener) {
|
||||||
window.electron.ipcRenderer.removeListener('music-download-complete', completeListener);
|
ipcRenderer?.removeListener('music-download-complete', completeListener);
|
||||||
completeListener = null;
|
completeListener = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (errorListener) {
|
if (errorListener) {
|
||||||
window.electron.ipcRenderer.removeListener('music-download-error', errorListener);
|
ipcRenderer?.removeListener('music-download-error', errorListener);
|
||||||
errorListener = null;
|
errorListener = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -181,7 +184,7 @@ export const useDownload = () => {
|
|||||||
songData.ar = songData.ar || songData.song?.artists;
|
songData.ar = songData.ar || songData.song?.artists;
|
||||||
|
|
||||||
// 发送下载请求
|
// 发送下载请求
|
||||||
window.electron.ipcRenderer.send('download-music', {
|
ipcRenderer?.send('download-music', {
|
||||||
url: typeof musicUrl === 'string' ? musicUrl : musicUrl.url,
|
url: typeof musicUrl === 'string' ? musicUrl : musicUrl.url,
|
||||||
filename,
|
filename,
|
||||||
songInfo: {
|
songInfo: {
|
||||||
@@ -277,7 +280,7 @@ export const useDownload = () => {
|
|||||||
downloadTime: Date.now()
|
downloadTime: Date.now()
|
||||||
};
|
};
|
||||||
|
|
||||||
window.electron.ipcRenderer.send('download-music', {
|
ipcRenderer?.send('download-music', {
|
||||||
url,
|
url,
|
||||||
filename,
|
filename,
|
||||||
songInfo,
|
songInfo,
|
||||||
|
|||||||
@@ -53,9 +53,9 @@ export function useSongItem(props: {
|
|||||||
const handleImageLoad = async (imageElement: HTMLImageElement) => {
|
const handleImageLoad = async (imageElement: HTMLImageElement) => {
|
||||||
if (!imageElement) return;
|
if (!imageElement) return;
|
||||||
|
|
||||||
const { backgroundColor } = await getImageBackground(imageElement);
|
const { backgroundColor, primaryColor } = await getImageBackground(imageElement);
|
||||||
// eslint-disable-next-line vue/no-mutating-props
|
|
||||||
props.item.backgroundColor = backgroundColor;
|
props.item.backgroundColor = backgroundColor;
|
||||||
|
props.item.primaryColor = primaryColor;
|
||||||
};
|
};
|
||||||
|
|
||||||
// 播放音乐
|
// 播放音乐
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
<!-- 搜索栏 -->
|
<!-- 搜索栏 -->
|
||||||
<search-bar />
|
<search-bar />
|
||||||
<!-- 主页面路由 -->
|
<!-- 主页面路由 -->
|
||||||
<div class="main-content" :native-scrollbar="false">
|
<div class="main-content" :native-scrollbar="false" :class="{'mobile-content': !shouldShowMobileMenu}">
|
||||||
<router-view
|
<router-view
|
||||||
v-slot="{ Component }"
|
v-slot="{ Component }"
|
||||||
class="main-page"
|
class="main-page"
|
||||||
@@ -21,7 +21,7 @@
|
|||||||
</router-view>
|
</router-view>
|
||||||
</div>
|
</div>
|
||||||
<play-bottom />
|
<play-bottom />
|
||||||
<app-menu v-if="isMobile && !playerStore.musicFull" class="menu" :menus="menus" />
|
<app-menu v-if="shouldShowMobileMenu" class="menu" :menus="menus" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- 底部音乐播放 -->
|
<!-- 底部音乐播放 -->
|
||||||
@@ -103,6 +103,16 @@ const isPlay = computed(() => playerStore.playMusic && playerStore.playMusic.id)
|
|||||||
const { menus } = menuStore;
|
const { menus } = menuStore;
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
|
|
||||||
|
// 判断当前路由是否应该在移动端显示AppMenu
|
||||||
|
const shouldShowMobileMenu = computed(() => {
|
||||||
|
// 过滤出在menus中定义的路径
|
||||||
|
const menuPaths = menus.map((item: any) => item.path);
|
||||||
|
// 检查当前路由路径是否在menus中
|
||||||
|
return menuPaths.includes(route.path) && isMobile.value && !playerStore.musicFull;
|
||||||
|
});
|
||||||
|
|
||||||
|
provide('shouldShowMobileMenu', shouldShowMobileMenu);
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
settingsStore.initializeSettings();
|
settingsStore.initializeSettings();
|
||||||
settingsStore.initializeTheme();
|
settingsStore.initializeTheme();
|
||||||
@@ -156,7 +166,10 @@ provide('openPlaylistDrawer', openPlaylistDrawer);
|
|||||||
overflow: auto;
|
overflow: auto;
|
||||||
display: block;
|
display: block;
|
||||||
flex: none;
|
flex: none;
|
||||||
padding-bottom: 70px;
|
}
|
||||||
|
|
||||||
|
.mobile-content {
|
||||||
|
height: calc(100vh - 75px);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -27,6 +27,7 @@
|
|||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { useRoute } from 'vue-router';
|
import { useRoute } from 'vue-router';
|
||||||
|
import { ref, watch } from 'vue';
|
||||||
|
|
||||||
import icon from '@/assets/icon.png';
|
import icon from '@/assets/icon.png';
|
||||||
|
|
||||||
@@ -115,7 +116,7 @@ const isText = ref(false);
|
|||||||
bottom: 0;
|
bottom: 0;
|
||||||
left: 0;
|
left: 0;
|
||||||
z-index: 99999;
|
z-index: 99999;
|
||||||
@apply bg-light dark:bg-black border-t border-gray-200 dark:border-gray-700;
|
@apply bg-light dark:bg-black border-none border-gray-200 dark:border-gray-700;
|
||||||
|
|
||||||
&-header {
|
&-header {
|
||||||
display: none;
|
display: none;
|
||||||
@@ -127,9 +128,16 @@ const isText = ref(false);
|
|||||||
|
|
||||||
&-item {
|
&-item {
|
||||||
&-link {
|
&-link {
|
||||||
@apply my-2 w-auto;
|
@apply my-2 w-auto px-2;
|
||||||
|
width: auto !important;
|
||||||
|
margin-top: 8px;
|
||||||
|
margin-bottom: 8px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&-expanded {
|
||||||
|
@apply w-full;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -0,0 +1,15 @@
|
|||||||
|
<template>
|
||||||
|
<component :is="componentToUse" v-bind="$attrs" />
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { computed } from 'vue';
|
||||||
|
import { isMobile } from '@/utils';
|
||||||
|
import MusicFull from '@/layout/components/MusicFull.vue';
|
||||||
|
import MusicFullMobile from '@/components/lyric/MusicFullMobile.vue';
|
||||||
|
|
||||||
|
// 根据当前设备类型选择需要显示的组件
|
||||||
|
const componentToUse = computed(() => {
|
||||||
|
return isMobile.value ? MusicFullMobile : MusicFull;
|
||||||
|
});
|
||||||
|
</script>
|
||||||
@@ -20,10 +20,11 @@ const getSettingsStore = () => {
|
|||||||
const loginRouter = {
|
const loginRouter = {
|
||||||
path: '/login',
|
path: '/login',
|
||||||
name: 'login',
|
name: 'login',
|
||||||
mate: {
|
meta: {
|
||||||
keepAlive: true,
|
keepAlive: true,
|
||||||
title: '登录',
|
title: '登录',
|
||||||
icon: 'icon-Home'
|
icon: 'icon-Home',
|
||||||
|
back: true
|
||||||
},
|
},
|
||||||
component: () => import('@/views/login/index.vue')
|
component: () => import('@/views/login/index.vue')
|
||||||
};
|
};
|
||||||
@@ -31,7 +32,7 @@ const loginRouter = {
|
|||||||
const setRouter = {
|
const setRouter = {
|
||||||
path: '/set',
|
path: '/set',
|
||||||
name: 'set',
|
name: 'set',
|
||||||
mate: {
|
meta: {
|
||||||
keepAlive: true,
|
keepAlive: true,
|
||||||
title: '设置',
|
title: '设置',
|
||||||
icon: 'icon-Home'
|
icon: 'icon-Home'
|
||||||
|
|||||||
@@ -10,6 +10,10 @@ export interface LyricConfig {
|
|||||||
pureModeEnabled: boolean;
|
pureModeEnabled: boolean;
|
||||||
hideMiniPlayBar: boolean;
|
hideMiniPlayBar: boolean;
|
||||||
hideLyrics: boolean;
|
hideLyrics: boolean;
|
||||||
|
// 移动端配置
|
||||||
|
mobileLayout: 'default' | 'ios' | 'android';
|
||||||
|
mobileCoverStyle: 'record' | 'square' | 'full';
|
||||||
|
mobileShowLyricLines: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const DEFAULT_LYRIC_CONFIG: LyricConfig = {
|
export const DEFAULT_LYRIC_CONFIG: LyricConfig = {
|
||||||
@@ -23,5 +27,9 @@ export const DEFAULT_LYRIC_CONFIG: LyricConfig = {
|
|||||||
hidePlayBar: false,
|
hidePlayBar: false,
|
||||||
hideMiniPlayBar: true,
|
hideMiniPlayBar: true,
|
||||||
pureModeEnabled: false,
|
pureModeEnabled: false,
|
||||||
hideLyrics: false
|
hideLyrics: false,
|
||||||
|
// 移动端默认配置
|
||||||
|
mobileLayout: 'ios',
|
||||||
|
mobileCoverStyle: 'full',
|
||||||
|
mobileShowLyricLines: 3
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -115,6 +115,7 @@
|
|||||||
:compact="isCompactLayout"
|
:compact="isCompactLayout"
|
||||||
:item="formatSong(item)"
|
:item="formatSong(item)"
|
||||||
@play="handlePlay"
|
@play="handlePlay"
|
||||||
|
:style="{paddingBottom: index === filteredSongs.length - 1 ? '100px' : '0'}"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@@ -697,7 +698,7 @@ const handleVirtualScroll = (e: any) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.albums-grid {
|
.albums-grid {
|
||||||
@apply grid gap-6 grid-cols-2 sm:grid-cols-3 md:grid-cols-5 lg:grid-cols-6;
|
@apply grid gap-6 grid-cols-2 sm:grid-cols-3 md:grid-cols-5 lg:grid-cols-6 pb-40;
|
||||||
}
|
}
|
||||||
|
|
||||||
.loading-more {
|
.loading-more {
|
||||||
|
|||||||
@@ -539,7 +539,7 @@ const handleBatchDownload = async () => {
|
|||||||
|
|
||||||
.mobile {
|
.mobile {
|
||||||
.favorite-page {
|
.favorite-page {
|
||||||
@apply p-4;
|
@apply p-4 m-0;
|
||||||
|
|
||||||
.favorite-header {
|
.favorite-header {
|
||||||
@apply mb-4;
|
@apply mb-4;
|
||||||
|
|||||||
@@ -146,7 +146,7 @@ const loginPhone = async () => {
|
|||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.login-page {
|
.login-page {
|
||||||
@apply flex flex-col items-center justify-center p-20 pt-20;
|
@apply flex flex-col items-center justify-center pt-20;
|
||||||
@apply bg-light dark:bg-black;
|
@apply bg-light dark:bg-black;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -216,4 +216,10 @@ const loginPhone = async () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.mobile {
|
||||||
|
.login-page {
|
||||||
|
@apply pt-0;
|
||||||
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -160,7 +160,7 @@
|
|||||||
<n-virtual-list
|
<n-virtual-list
|
||||||
ref="songListRef"
|
ref="songListRef"
|
||||||
class="song-virtual-list"
|
class="song-virtual-list"
|
||||||
style="height: calc(80vh - 60px)"
|
style="max-height: calc(100vh - 130px);"
|
||||||
:items="filteredSongs"
|
:items="filteredSongs"
|
||||||
:item-size="isCompactLayout ? 50 : 70"
|
:item-size="isCompactLayout ? 50 : 70"
|
||||||
item-resizable
|
item-resizable
|
||||||
@@ -179,6 +179,7 @@
|
|||||||
@play="handlePlay"
|
@play="handlePlay"
|
||||||
@remove-song="handleRemoveSong"
|
@remove-song="handleRemoveSong"
|
||||||
@select="(id, selected) => handleSelect(id, selected)"
|
@select="(id, selected) => handleSelect(id, selected)"
|
||||||
|
:style="{paddingBottom: index === filteredSongs.length - 1 ? '100px' : '0'}"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -90,6 +90,10 @@
|
|||||||
</n-scrollbar>
|
</n-scrollbar>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<!-- 未登录时显示登录组件 -->
|
||||||
|
<div v-if="!isLoggedIn && isMobile" class="login-container" :class="setAnimationClass('animate__fadeIn')">
|
||||||
|
<login-component @login-success="handleLoginSuccess" />
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -109,6 +113,7 @@ import { useUserStore } from '@/store/modules/user';
|
|||||||
import type { Playlist } from '@/type/listDetail';
|
import type { Playlist } from '@/type/listDetail';
|
||||||
import type { IUserDetail } from '@/type/user';
|
import type { IUserDetail } from '@/type/user';
|
||||||
import { getImgUrl, isElectron, isMobile, setAnimationClass, setAnimationDelay } from '@/utils';
|
import { getImgUrl, isElectron, isMobile, setAnimationClass, setAnimationDelay } from '@/utils';
|
||||||
|
import LoginComponent from '@/views/login/index.vue';
|
||||||
|
|
||||||
defineOptions({
|
defineOptions({
|
||||||
name: 'User'
|
name: 'User'
|
||||||
@@ -143,7 +148,7 @@ const checkLoginStatus = () => {
|
|||||||
const userData = localStorage.getItem('user');
|
const userData = localStorage.getItem('user');
|
||||||
|
|
||||||
if (!token || !userData) {
|
if (!token || !userData) {
|
||||||
router.push('/login');
|
!isMobile.value && router.push('/login');
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -270,6 +275,14 @@ const showFollowList = () => {
|
|||||||
// if (!user.value) return;
|
// if (!user.value) return;
|
||||||
// router.push('/user/followers');
|
// router.push('/user/followers');
|
||||||
// };
|
// };
|
||||||
|
|
||||||
|
const handleLoginSuccess = () => {
|
||||||
|
// 处理登录成功后的逻辑
|
||||||
|
checkLoginStatus();
|
||||||
|
loadData();
|
||||||
|
};
|
||||||
|
|
||||||
|
const isLoggedIn = computed(() => userStore.user);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
@@ -398,5 +411,9 @@ const showFollowList = () => {
|
|||||||
.user-page {
|
.user-page {
|
||||||
@apply px-4;
|
@apply px-4;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.login-container {
|
||||||
|
@apply flex justify-center items-center h-full w-full;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
Reference in New Issue
Block a user