Skip to content

Commit

Permalink
improve playlist/playqueue style
Browse files Browse the repository at this point in the history
  • Loading branch information
mebtte committed Nov 28, 2023
1 parent 0b6b1be commit c831c2c
Show file tree
Hide file tree
Showing 12 changed files with 120 additions and 62 deletions.
2 changes: 1 addition & 1 deletion apps/pwa/src/components/tab_list.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ function TabList<TabType extends string>({
tabList,
onChange,
...props
}: HtmlHTMLAttributes<HTMLDivElement> & {
}: Omit<HtmlHTMLAttributes<HTMLDivElement>, 'onChange'> & {
current: TabType;
tabList: {
tab: TabType;
Expand Down
2 changes: 2 additions & 0 deletions apps/pwa/src/i18n/en_us.ts
Original file line number Diff line number Diff line change
Expand Up @@ -215,4 +215,6 @@ export default {
someone_created_at: '%s1 created at %s2',
quit_shared_musicbill_question:
'are you sure to quit this shared musicbill ?',
playlist: 'playlist',
playqueue: 'playqueue',
};
2 changes: 2 additions & 0 deletions apps/pwa/src/i18n/zh_hans.ts
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,8 @@ const zhCN: {
unknown_singer: '未知歌手',
someone_created_at: '%s1 创建于 %s2',
quit_shared_musicbill_question: '确定退出该共享乐单吗?',
playlist: '播放列表',
playqueue: '播放队列',
};

export default zhCN;
2 changes: 1 addition & 1 deletion apps/pwa/src/pages/player/pages/exploration/cache.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import Cache from '#/utils/cache';
import Cache from '@/utils/cache';
import { ExplorationItem } from './constants';

export enum CacheKey {
Expand Down
2 changes: 1 addition & 1 deletion apps/pwa/src/pages/player/pages/musicbill/cache.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import Cache from '#/utils/cache';
import Cache from '@/utils/cache';

export enum CacheKey {
MUSICBILL_PAGE_SCROLL_TOP = 'musicbill_page_scroll_top_{{id}}',
Expand Down
6 changes: 3 additions & 3 deletions apps/pwa/src/pages/player/playlist_playqueue_drawer/cache.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import Cache from '#/utils/cache';
import Cache from '@/utils/cache';
import { Tab } from './constants';

export enum CacheKey {
TAB = 'tab',
SELECTED_TAB = 'selected_tab',
}

export default new Cache<
CacheKey,
{
[CacheKey.TAB]: Tab;
[CacheKey.SELECTED_TAB]: Tab;
}
>();
52 changes: 16 additions & 36 deletions apps/pwa/src/pages/player/playlist_playqueue_drawer/content.tsx
Original file line number Diff line number Diff line change
@@ -1,50 +1,34 @@
import { useEffect, useState } from 'react';
import TabList from '@/components/tab_list';
import { useTransition } from 'react-spring';
import styled from 'styled-components';
import Playqueue from './playqueue';
import Playlist from './playlist';
import { Tab, TAB_LIST_HEIGHT } from './constants';
import { Tab } from './constants';
import cache, { CacheKey } from './cache';

const TAB_MAP_LABEL: Record<Tab, string> = {
[Tab.PLAYLIST]: '播放列表',
[Tab.PLAYQUEUE]: '播放队列',
};
const TAB_LIST = Object.values(Tab).map((t) => ({
tab: t,
label: TAB_MAP_LABEL[t],
}));
const StyledTabList = styled(TabList)`
position: absolute;
top: 0;
left: 0;
width: 100%;
height: ${TAB_LIST_HEIGHT}px;
padding: 0 20px;
backdrop-filter: blur(5px);
`;
import TabList from './tab_list';

function Content() {
const [tab, setTab] = useState(
() => cache.get(CacheKey.TAB) || Tab.PLAYQUEUE,
const [selectedTab, setSelectedTab] = useState(
() => cache.get(CacheKey.SELECTED_TAB) || Tab.PLAYQUEUE,
);

useEffect(() => {
cache.set({ key: CacheKey.TAB, value: tab, ttl: Infinity });
}, [tab]);

const transitions = useTransition(tab, {
cache.set({
key: CacheKey.SELECTED_TAB,
value: selectedTab,
ttl: Infinity,
});
}, [selectedTab]);

const transitions = useTransition(selectedTab, {
from: { opacity: 0 },
enter: { opacity: 1 },
leave: { opacity: 0 },
});

return (
<>
{transitions((style, t) => {
switch (t) {
{transitions((style, tab) => {
switch (tab) {
case Tab.PLAYLIST: {
return <Playlist style={style} />;
}
Expand All @@ -58,11 +42,7 @@ function Content() {
}
}
})}
<StyledTabList
current={tab}
onChange={(t) => setTab(t)}
tabList={TAB_LIST}
/>
<TabList selectedTab={selectedTab} onChange={setSelectedTab} />
</>
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import Empty from '@/components/empty';
import { flexCenter } from '@/style/flexbox';
import autoScrollbar from '@/style/auto_scrollbar';
import { t } from '@/i18n';
import useTitlebarArea from '@/utils/use_titlebar_area_rect';
import { TAB_LIST_HEIGHT } from '../constants';
import Context from '../../context';
import TabContent from '../tab_content';
Expand All @@ -33,7 +34,6 @@ const Style = styled(TabContent)`
> .content {
${absoluteFullSize}
padding-top: ${TAB_LIST_HEIGHT}px;
padding-bottom: calc(${FILTER_HEIGHT}px + env(safe-area-inset-bottom, 0));
&.list {
Expand Down Expand Up @@ -73,14 +73,19 @@ function Playlist({ style }: { style: unknown }) {
);
}, [keyword]);

const { height: titlebarAreaHeight } = useTitlebarArea();
const contentStyle: CSSProperties = {
paddingTop: TAB_LIST_HEIGHT + titlebarAreaHeight,
};

const filteredPlaylist = playlist.filter((music) =>
filterMusic(music, keyword),
);
return (
// @ts-expect-error
<Style style={style}>
{filteredPlaylist.length ? (
<div className="content list" ref={listRef}>
<div className="content list" style={contentStyle} ref={listRef}>
<List
length={filteredPlaylist.length}
type="uniform"
Expand Down Expand Up @@ -140,7 +145,7 @@ function Playlist({ style }: { style: unknown }) {
/>
</div>
) : (
<div className="content empty">
<div className="content empty" style={contentStyle}>
<Empty
description={keyword ? t('no_suitable_music') : t('empty_playlist')}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import absoluteFullSize from '@/style/absolute_full_size';
import { CSSVariable } from '@/global_style';
import autoScrollbar from '@/style/auto_scrollbar';
import { t } from '@/i18n';
import useTitlebarArea from '@/utils/use_titlebar_area_rect';
import Context from '../context';
import TabContent from './tab_content';
import MusicBase from '../components/music_base';
Expand All @@ -32,7 +33,6 @@ const Style = styled(TabContent)`
> .content {
${absoluteFullSize}
padding-top: ${TAB_LIST_HEIGHT}px;
padding-bottom: env(safe-area-inset-bottom, 0);
&.list {
Expand All @@ -56,13 +56,17 @@ const removeStyle: CSSProperties = {

function Playqueue({ style }: { style: unknown }) {
const { currentPlayqueuePosition, playqueue } = useContext(Context);
const { height: titlebarAreaHeight } = useTitlebarArea();

const { length } = playqueue;
const contentStyle: CSSProperties = {
paddingTop: TAB_LIST_HEIGHT + titlebarAreaHeight,
};
return (
// @ts-expect-error
<Style style={style}>
{playqueue.length ? (
<div className="content list">
<div className="content list" style={contentStyle}>
<List
type="uniform"
length={length}
Expand Down Expand Up @@ -159,7 +163,7 @@ function Playqueue({ style }: { style: unknown }) {
/>
</div>
) : (
<div className="content empty">
<div className="content empty" style={contentStyle}>
<Empty description={t('empty_playqueue')} />
</div>
)}
Expand Down
64 changes: 64 additions & 0 deletions apps/pwa/src/pages/player/playlist_playqueue_drawer/tab_list.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import TabList from '@/components/tab_list';
import { t } from '@/i18n';
import { CSSProperties, useContext } from 'react';
import useTitlebarArea from '@/utils/use_titlebar_area_rect';
import { Tab, TAB_LIST_HEIGHT } from './constants';
import context from '../context';

const TAB_MAP_LABEL: Record<Tab, string> = {
[Tab.PLAYLIST]: t('playlist'),
[Tab.PLAYQUEUE]: t('playqueue'),
};
const style: CSSProperties = {
position: 'absolute',
top: 0,
left: 0,
width: '100%',

paddingInline: 20,
backdropFilter: 'blur(5px)',
};

function Wrapper({
selectedTab,
onChange,
}: {
selectedTab: Tab;
onChange: (tab: Tab) => void;
}) {
const { height } = useTitlebarArea();
const { playlist, playqueue } = useContext(context);
const getCount = (tab: Tab) => {
switch (tab) {
case Tab.PLAYLIST: {
return playlist.length;
}
case Tab.PLAYQUEUE: {
return playqueue.length;
}
default: {
return 0;
}
}
};
return (
<TabList
current={selectedTab}
onChange={onChange}
tabList={Object.values(Tab).map((tab) => {
const count = getCount(tab);
return {
tab,
label: `${TAB_MAP_LABEL[tab]}${count > 0 ? ` (${count})` : ''}`,
};
})}
style={{
...style,
height: height + TAB_LIST_HEIGHT,
paddingBlockStart: height,
}}
/>
);
}

export default Wrapper;
29 changes: 15 additions & 14 deletions apps/pwa/src/pages/player/user_drawer/user_drawer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -64,17 +64,17 @@ const Style = styled.div`
}
}
`;
const StyledTabList = styled(TabList)`
z-index: 1;
const tabListStyle: CSSProperties = {
zIndex: 1,

position: sticky;
top: ${MINI_INFO_HEIGHT}px;
position: 'sticky',
top: MINI_INFO_HEIGHT,

padding: 5px 20px;
padding: '5px 20px',

backdrop-filter: blur(5px);
background-color: rgb(255 255 255 / 0.5);
`;
backdropFilter: 'blur(5px)',
backgroundColor: 'rgb(255 255 255 / 0.5)',
};
const TabContent = styled(animated.div)`
position: absolute;
top: 0;
Expand All @@ -87,7 +87,7 @@ const TabContent = styled(animated.div)`
function UserDetail({ user }: { user: UserDetailType }) {
const mountedRef = useRef(false);
const scrollableRef = useRef<HTMLDivElement>(null);
const [tab, setTab] = useState(Tab.MUSIC);
const [selectedTab, setSelectedTab] = useState(Tab.MUSIC);

const [miniInfoVisible, setMiniInfoVisible] = useState(false);
const onScroll: UIEventHandler<HTMLDivElement> = (e) => {
Expand All @@ -103,17 +103,18 @@ function UserDetail({ user }: { user: UserDetailType }) {
});
}
mountedRef.current = true;
}, [tab]);
}, [selectedTab]);

const transitions = useTransition(tab, TRANSITION);
const transitions = useTransition(selectedTab, TRANSITION);
return (
<Style>
<div className="scrollable" onScroll={onScroll} ref={scrollableRef}>
<Info user={user} />
<StyledTabList
current={tab}
<TabList
current={selectedTab}
tabList={TAB_LIST}
onChange={(t) => setTab(t)}
onChange={(tab) => setSelectedTab(tab)}
style={tabListStyle}
/>
<div className="tab-content">
{transitions((style, t) => {
Expand Down
File renamed without changes.

0 comments on commit c831c2c

Please sign in to comment.