diff --git a/package.json b/package.json index 6797df7..6ecf5c0 100644 --- a/package.json +++ b/package.json @@ -14,7 +14,8 @@ "dev:renderer": "vite dev", "build:main": "node scripts/build.main.mjs", "build:renderer": "vite build", - "build": "npm run typecheck && npm run build:renderer && npm run build:main && electron-builder --config .electron-builder.config.js --dir", + "build": "npm run typecheck && cross-env-shell IS_ELECTRON=true npm run build:renderer && npm run build:main && electron-builder --config .electron-builder.config.js", + "build-dir": "npm run typecheck && cross-env-shell IS_ELECTRON=true npm run build:renderer && npm run build:main && electron-builder --config .electron-builder.config.js --dir", "typecheck": "tsc --noEmit --project src/renderer/tsconfig.json", "debug": "cross-env-shell NODE_ENV=debug \"npm run typecheck && node scripts/build.mjs && vite ./src/renderer\"", "eslint": "eslint --ext .ts,.js ./", diff --git a/src/renderer/components/Player.tsx b/src/renderer/components/Player.tsx index a7d51ff..1d2b76c 100644 --- a/src/renderer/components/Player.tsx +++ b/src/renderer/components/Player.tsx @@ -57,7 +57,7 @@ const PlayingTrack = () => { - toast('Work in progress')}> + toast('施工中...')}> { const playerSnapshot = useSnapshot(player) const mode = useMemo(() => playerSnapshot.mode, [playerSnapshot.mode]) - const isFM = () => mode === PlayerMode.FM - return (
- toast('Work in progress')} disabled={isFM()}> + toast('Work in progress')} + disabled={mode === PlayerMode.FM} + > - toast('Work in progress')} disabled={isFM()}> + toast('施工中...')} + disabled={mode === PlayerMode.FM} + > - toast('Work in progress')} disabled={isFM()}> + toast('施工中...')} + disabled={mode === PlayerMode.FM} + > - toast('Work in progress')}> + toast('施工中...')}> - toast('Work in progress')}> + toast('施工中...')}>
diff --git a/src/renderer/components/Topbar.tsx b/src/renderer/components/Topbar.tsx index 1b8f0f2..0d792f3 100644 --- a/src/renderer/components/Topbar.tsx +++ b/src/renderer/components/Topbar.tsx @@ -68,7 +68,10 @@ const SearchBox = () => { const Settings = () => { return ( -
+
toast('施工中...')} + className='app-region-no-drag btn-hover-animation rounded-lg p-2.5 text-gray-500 transition duration-300 after:rounded-full after:bg-black/[.06] hover:text-gray-900 dark:text-gray-300 dark:after:bg-white/10 dark:hover:text-gray-200' + >
) @@ -78,20 +81,27 @@ const Avatar = () => { const navigate = useNavigate() const { data: user } = useUser() - const avatarUrl = resizeImage(user?.profile?.avatarUrl ?? '', 'sm') + const avatarUrl = user?.profile?.avatarUrl + ? resizeImage(user?.profile?.avatarUrl ?? '', 'sm') + : '' return ( - navigate('/login')} - className='app-region-no-drag h-9 w-9 rounded-full bg-gray-100 dark:bg-gray-700' - /> - //
navigate('/login')}> - // - //
+ <> + {avatarUrl ? ( + navigate('/login')} + className='app-region-no-drag h-9 w-9 rounded-full bg-gray-100 dark:bg-gray-700' + /> + ) : ( +
navigate('/login')}> + +
+ )} + ) } diff --git a/src/renderer/pages/Album.tsx b/src/renderer/pages/Album.tsx index c99acd1..7da64a6 100644 --- a/src/renderer/pages/Album.tsx +++ b/src/renderer/pages/Album.tsx @@ -191,7 +191,7 @@ const Header = ({ color={ButtonColor.Gray} iconColor={ButtonColor.Gray} isSkelton={isLoading} - onClick={() => toast('Work in progress')} + onClick={() => toast('施工中...')} > @@ -200,7 +200,7 @@ const Header = ({ color={ButtonColor.Gray} iconColor={ButtonColor.Gray} isSkelton={isLoading} - onClick={() => toast('Work in progress')} + onClick={() => toast('施工中...')} > diff --git a/src/renderer/pages/Home.tsx b/src/renderer/pages/Home.tsx index f1605dd..c2f845e 100644 --- a/src/renderer/pages/Home.tsx +++ b/src/renderer/pages/Home.tsx @@ -8,6 +8,21 @@ import DailyTracksCard from '@/components/DailyTracksCard' import FMCard from '@/components/FMCard' export default function Home() { + const { + data: dailyRecommendPlaylists, + isLoading: isLoadingDailyRecommendPlaylists, + } = useQuery( + PlaylistApiNames.FETCH_DAILY_RECOMMEND_PLAYLISTS, + fetchDailyRecommendPlaylists, + { + retry: false, + placeholderData: () => + window.ipcRenderer?.sendSync('getApiCacheSync', { + api: 'recommend/resource', + }), + } + ) + const { data: recommendedPlaylists, isLoading: isLoadingRecommendedPlaylists, @@ -24,20 +39,6 @@ export default function Home() { } ) - const { - data: dailyRecommendPlaylists, - isLoading: isLoadingDailyRecommendPlaylists, - } = useQuery( - PlaylistApiNames.FETCH_DAILY_RECOMMEND_PLAYLISTS, - fetchDailyRecommendPlaylists, - { - placeholderData: () => - window.ipcRenderer?.sendSync('getApiCacheSync', { - api: 'recommend/resource', - }), - } - ) - const playlists = [ ...(dailyRecommendPlaylists?.recommend ?? []), ...(recommendedPlaylists?.result ?? []), diff --git a/src/renderer/pages/Login.tsx b/src/renderer/pages/Login.tsx index 9301964..f2cb7eb 100644 --- a/src/renderer/pages/Login.tsx +++ b/src/renderer/pages/Login.tsx @@ -28,7 +28,7 @@ const EmailInput = ({ return (
- Email + 邮箱
- Phone + 手机
- Password + 密码
- Login + 登录 ) } @@ -153,15 +153,15 @@ const OtherLoginMethods = ({ }[] = [ { id: Method.QRCODE, - name: 'QR Code', + name: '二维码', }, { id: Method.EMAIL, - name: 'Email', + name: '邮箱', }, { id: Method.PHONE, - name: 'Phone', + name: '手机', }, ] return ( @@ -178,7 +178,7 @@ const OtherLoginMethods = ({ @@ -127,7 +127,7 @@ const Header = memo( color={ButtonColor.Gray} iconColor={ButtonColor.Gray} isSkelton={isLoading} - onClick={() => toast('Work in progress')} + onClick={() => toast('施工中...')} > diff --git a/src/renderer/utils/player.ts b/src/renderer/utils/player.ts index 510c958..27128a4 100644 --- a/src/renderer/utils/player.ts +++ b/src/renderer/utils/player.ts @@ -157,7 +157,10 @@ export class Player { */ private async _fetchAudioSource(trackID: TrackID) { const response = await fetchAudioSourceWithReactQuery({ id: trackID }) - if (response.data?.[0]?.url) return response.data[0].url + return { + audio: response.data?.[0]?.url, + id: trackID, + } } /** @@ -174,14 +177,14 @@ export class Player { * Play audio via howler */ private async _playAudio() { - const audio = await this._fetchAudioSource(this.trackID) + const { audio, id } = await this._fetchAudioSource(this.trackID) if (!audio) { toast('Failed to load audio source') return } Howler.unload() const howler = new Howl({ - src: [audio], + src: [`${audio}?id=${id}`], format: ['mp3', 'flac'], html5: true, autoplay: true, @@ -191,8 +194,9 @@ export class Player { _howler = howler this.play() this.state = State.PLAYING - - this._cacheAudio(this.trackID, audio) + _howler.once('load', () => { + this._cacheAudio(_howler._src) + }) if (!this._progressInterval) { this._setupProgressInterval() @@ -209,8 +213,10 @@ export class Player { } } - private _cacheAudio(id: number, audio: string) { + private _cacheAudio(audio: string) { if (audio.includes('yesplaymusic')) return + const id = Number(audio.split('?id=')[1]) + if (isNaN(id) || !id) return cacheAudio(id, audio) } @@ -242,18 +248,13 @@ export class Player { play(fade: boolean = false) { if (_howler.playing()) return - const setPlayState = () => { - this.state = State.PLAYING - } - _howler.play() if (fade) { _howler.once('play', () => { _howler.fade(0, this._volume, PLAY_PAUSE_FADE_DURATION) - setPlayState() }) } else { - setPlayState() + this.state = State.PLAYING } } @@ -262,18 +263,15 @@ export class Player { * @param {boolean} fade fade out */ pause(fade: boolean = false) { - const setPauseState = () => { - _howler.pause() - this.state = State.PAUSED - } - if (fade) { _howler.fade(this._volume, 0, PLAY_PAUSE_FADE_DURATION) + this.state = State.PAUSED _howler.once('fade', () => { - setPauseState() + _howler.pause() }) } else { - setPauseState() + this.state = State.PAUSED + _howler.pause() } } diff --git a/vite.config.ts b/vite.config.ts index 0a2734a..c93ea7f 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -42,6 +42,7 @@ export default defineConfig({ ], base: './', build: { + target: process.env.IS_ELECTRON ? 'esnext' : 'modules', sourcemap: process.env.NODE_ENV === 'debug', outDir: '../../dist/renderer', emptyOutDir: true,