From c4c227d33ea6f4737bcdb65a4de2863e9407f63b Mon Sep 17 00:00:00 2001 From: SimonShiki <sinangentoo@gmail.com> Date: Sun, 11 Aug 2024 09:35:53 +0800 Subject: [PATCH] :bug: fix: ncm signin issue Signed-off-by: SimonShiki <sinangentoo@gmail.com> --- src/components/base/pagination.tsx | 10 +++---- src/components/songlist-item.tsx | 2 +- src/jotais/settings.ts | 1 - src/pages/ncm.tsx | 46 ++++++++++++++++++++++-------- src/storages/ncm.ts | 9 ++++-- 5 files changed, 46 insertions(+), 22 deletions(-) diff --git a/src/components/base/pagination.tsx b/src/components/base/pagination.tsx index 2841d36..8a87295 100644 --- a/src/components/base/pagination.tsx +++ b/src/components/base/pagination.tsx @@ -56,7 +56,7 @@ export default function Pagination ({ currentPage, totalPages, onPageChange, siz onPageChange(pageNumber); } }} - className={size === 'md' ? 'px-4 h-10' : 'px-2 h-6'} + className={size === 'md' ? 'px-3 h-8' : 'px-2 h-6'} iconOnly > {pageNumber} @@ -72,10 +72,10 @@ export default function Pagination ({ currentPage, totalPages, onPageChange, siz <Button onClick={() => onPageChange(Math.max(1, currentPage - 1))} disabled={currentPage === 1} - className={`${size === 'md' ? 'w-10 h-10' : 'w-6 h-6'} group flex justify-center items-center`} + className={`${size === 'md' ? 'w-8 h-8' : 'w-6 h-6'} group flex justify-center items-center`} iconOnly > - <span className={`i-ph:caret-left-bold ${size === 'md' ? 'w-4 h-4' : 'w-3 h-3'} color-text-pri group-disabled:color-outline-sec dark:color-text-dark-pri dark:group-disabled:color-outline-dark-sec`} /> + <span className={`i-fluent:chevron-left-16-regular ${size === 'md' ? 'w-4 h-4' : 'w-3 h-3'} color-text-pri group-disabled:color-outline-sec dark:color-text-dark-pri dark:group-disabled:color-outline-dark-sec`} /> </Button> {renderPageNumbers()} @@ -83,10 +83,10 @@ export default function Pagination ({ currentPage, totalPages, onPageChange, siz <Button onClick={() => onPageChange(Math.min(totalPages, currentPage + 1))} disabled={currentPage === totalPages} - className={`${size === 'md' ? 'w-10 h-10' : 'w-6 h-6'} group flex justify-center items-center`} + className={`${size === 'md' ? 'w-8 h-8' : 'w-6 h-6'} group flex justify-center items-center`} iconOnly > - <span className={`i-ph:caret-right-bold ${size === 'md' ? 'w-4 h-4' : 'w-3 h-3'} color-text-pri group-disabled:color-outline-sec dark:color-text-dark-pri dark:group-disabled:color-outline-dark-sec`} /> + <span className={`i-fluent:chevron-right-16-regular ${size === 'md' ? 'w-4 h-4' : 'w-3 h-3'} color-text-pri group-disabled:color-outline-sec dark:color-text-dark-pri dark:group-disabled:color-outline-dark-sec`} /> </Button> </div> ); diff --git a/src/components/songlist-item.tsx b/src/components/songlist-item.tsx index efce842..28c4fda 100644 --- a/src/components/songlist-item.tsx +++ b/src/components/songlist-item.tsx @@ -15,7 +15,7 @@ export default function SonglistItem (props: SonglistItemProps) { return ( <Card onDoubleClick={() => { props.onClick?.(props.id, props.index); - }} className={`flex flex-row items-center py-2 gap-2 hover:!bg-black cursor-pointer hover:!bg-op-5 transition-colors ${props.hideBg ? '!border-none !bg-transparent' : ''}`}> + }} className={`flex flex-row items-center active:scale-99 py-2 gap-2 hover:!bg-black cursor-pointer hover:!bg-op-5 transition-all ${props.hideBg ? '!border-none !bg-transparent' : ''}`}> <img draggable={false} src={props.cover ?? defaultCover} alt={props.name} className='rounded-md w-10 h-10' /> <span className='color-text-pri font-size-sm font-500'>{props.name}</span> </Card> diff --git a/src/jotais/settings.ts b/src/jotais/settings.ts index 668b881..66e6a29 100644 --- a/src/jotais/settings.ts +++ b/src/jotais/settings.ts @@ -1,6 +1,5 @@ import { focusAtom } from 'jotai-optics'; import { atomWithStorage } from 'jotai/utils'; -import sharedStore from './shared-store'; export interface StorageConfig<Idenfiter extends string> { identifer: Idenfiter; diff --git a/src/pages/ncm.tsx b/src/pages/ncm.tsx index 1a10f42..fa1785f 100644 --- a/src/pages/ncm.tsx +++ b/src/pages/ncm.tsx @@ -13,6 +13,7 @@ import Spinner from '../components/base/spinner'; import Button from '../components/base/button'; import SonglistItem from '../components/songlist-item'; import { FormattedMessage, useIntl } from 'react-intl'; +import Pagination from '../components/base/pagination'; interface NCMProfile { nickname: string; @@ -36,6 +37,9 @@ export default function NCM () { const [searchPage, setSearchPage] = useState(1); const [showSonglist, setShowSonglist] = useState<string | number | null>(null); const [songlistName, setSonglistName] = useState(''); + const [songlistTotalPage, setSonglistTotalPage] = useState(0); + const [songlistPage, setSonglistPage] = useState(0); + const [songlistDetail, setSonglistDetail] = useState<AbstractSong<'ncm'>[]>([]); const [isSearching, setIsSearching] = useState(false); @@ -68,6 +72,18 @@ export default function NCM () { updateSearchResult(); }, [isSearching, searchText, ncmInstance]); + useEffect(() => { + if (!showSonglist || !songlistPage) return; + ncmInstance.getRemoteSonglistDetail(showSonglist as number, 10, songlistPage).then((detail) => { + setSonglistDetail(detail); + }); + }, [songlistPage]); + + useEffect(() => { + if (showSonglist) return; + setSonglistPage(0); + }, [showSonglist]); + const handleClickSong = useCallback((song: AbstractSong<'ncm'>, playlist: AbstractSong<'ncm'>[]) => { player.clearPlaylist(); player.addToPlaylist(...playlist); @@ -87,7 +103,9 @@ export default function NCM () { const handleClickRemoteSonglist = useCallback(async (id: string | number, index: number) => { setShowSonglist(id); setSonglistName(songlist[index].name); - setSonglistDetail(await ncmInstance.getRemoteSonglistDetail(id)); + setSonglistDetail([]); + setSonglistPage(1); + setSonglistTotalPage(Math.ceil(songlist[index].trackCount / 10)); }, [songlist, ncmInstance]); const intl = useIntl(); @@ -205,17 +223,21 @@ export default function NCM () { </span> </Button> </div> - <Virtuoso - className="flex-1" - totalCount={barOpen ? songlistDetail.length + 1 : songlistDetail.length} - itemContent={(index) => { - if (index === songlistDetail.length) { - return <div className="h-20" />; - } - const song = songlistDetail[index]; - return <SongItem song={song} onClick={() => handleClickSong(song, songlistDetail)} hideBg={!(index % 2)} />; - }} - /> + {songlistDetail.length > 0 ? ( + <Virtuoso + className="flex-1" + totalCount={songlistDetail.length} + itemContent={(index) => { + const song = songlistDetail[index]; + return <SongItem song={song} onClick={() => handleClickSong(song, songlistDetail)} hideBg={!(index % 2)} />; + }} + /> + ) : ( + <div className='w-full h-full flex justify-center items-center'> + <Spinner /> + </div> + )} + <Pagination totalPages={songlistTotalPage} className={`mx-auto ${barOpen ? 'mb-20' : ''}`} currentPage={songlistPage} onPageChange={setSonglistPage} /> </div> ); } diff --git a/src/storages/ncm.ts b/src/storages/ncm.ts index b200af6..d7dc90b 100644 --- a/src/storages/ncm.ts +++ b/src/storages/ncm.ts @@ -255,9 +255,9 @@ export class NCM implements AbstractStorage { } private initListener () { - const ncmConfig = sharedStore.get(this.ncmStorageConfigJotai) as NCMConfig; const loggedInJotai = focusAtom(this.ncmStorageConfigJotai, (optic) => optic.prop('loggedIn')); sharedStore.sub(loggedInJotai, async () => { + const ncmConfig = sharedStore.get(this.ncmStorageConfigJotai) as NCMConfig; const loggedIn = sharedStore.get(loggedInJotai); if (loggedIn) { const { userId } = await this.getProfile(); @@ -390,8 +390,11 @@ export class NCM implements AbstractStorage { async getRemoteSonglistDetail (id: string | number, limit = 10, page = 1) { const offset = (page - 1) * limit; const res = await fetch(`${this.config.api}playlist/track/all?id=${id}&limit=${limit}&offset=${offset}${this.config.cookie ? `&cookie=${this.config.cookie}` : ''}`); - const { songs } = await res.json(); - const mappedList: Song<'ncm'>[] = (songs as NCMSonglistTrack[]).map(song => ({ + const data = await res.json(); + if (!data.songs) { + console.error(data); + } + const mappedList: Song<'ncm'>[] = (data.songs as NCMSonglistTrack[]).map(song => ({ id: song.id, name: song.name, cover: song.al.picUrl,