[FEAT] add on air

This commit is contained in:
Edouard DUPIN 2025-01-11 20:48:22 +01:00
parent 6b801d250f
commit eb5a366a12
5 changed files with 181 additions and 3 deletions

View File

@ -39,6 +39,7 @@ import { colors } from '@/theme/foundations/colors';
import { requestSignIn, requestSignOut, requestSignUp } from '@/utils/sso';
import { useThemeMode } from '@/utils/theme-tools';
import { useSessionService } from '@/service/session';
import { MdHome, MdOutlinePlaylistPlay, MdOutlineUploadFile } from 'react-icons/md';
export const TOP_BAR_HEIGHT = '50px';
@ -81,6 +82,9 @@ export const TopBar = ({ title, children }: TopBarProps) => {
const onSelectHome = () => {
navigate('/');
};
const onSelectOnAir = () => {
navigate('/on-air');
};
const onHelp = () => {
navigate('/help');
};
@ -202,11 +206,22 @@ export const TopBar = ({ title, children }: TopBarProps) => {
onClick={onSelectHome}
width="full"
>
<LuHome />
<MdHome />
<Text paddingLeft="3px" fontWeight="bold" marginRight="auto">
Home
</Text>
</Button>
<Button
background="#00000000"
borderRadius="0px"
onClick={onSelectOnAir}
width="full"
>
<MdOutlinePlaylistPlay />
<Text paddingLeft="3px" fontWeight="bold" marginRight="auto">
On air
</Text>
</Button>
<hr />
<Button
background="#00000000"
@ -214,7 +229,7 @@ export const TopBar = ({ title, children }: TopBarProps) => {
onClick={onSelectAdd}
width="full"
>
<LuArrowUpSquare />
<MdOutlineUploadFile />
<Text paddingLeft="3px" fontWeight="bold" marginRight="auto">
Add Media
</Text>

View File

@ -0,0 +1,28 @@
import { Track } from '@/back-api';
import { Covers } from '@/components/Cover';
import { MenuElement } from '@/components/contextMenu/ContextMenu';
import { useSpecificTrack } from '@/service/Track';
import { DisplayTrackFull } from './DisplayTrackFull';
import { DisplayTrackSkeleton } from './DisplayTrackSkeleton';
export type DisplayTrackProps = {
trackId: Track["id"];
onClick?: () => void;
contextMenu?: MenuElement[];
};
export const DisplayTrackFullId = ({
trackId,
onClick,
contextMenu,
}: DisplayTrackProps) => {
const { dataTrack } = useSpecificTrack(trackId);
if (dataTrack) {
return (
<DisplayTrackFull track={dataTrack} onClick={onClick} contextMenu={contextMenu} />
);
} else {
return (
<DisplayTrackSkeleton />
);
}
};

View File

@ -16,6 +16,7 @@ import { TrackRoutes } from '@/scene/track/TrackRoutes';
import { useHasRight } from '@/service/session';
import { SettingsPage } from './home/SettingsPage';
import { AddPage } from './home/AddPage';
import { OnAirPage } from './onAir/OnAirPage';
export const AppRoutes = () => {
const { isReadable } = useHasRight('user');
@ -34,6 +35,7 @@ export const AppRoutes = () => {
<Route path="help" element={<HelpPage />} />
<Route path="settings" element={<SettingsPage />} />
<Route path="add" element={<AddPage />} />
<Route path="on-air/*" element={<OnAirPage />} />
<Route path="artist/*" element={<ArtistRoutes />} />
<Route path="album/*" element={<AlbumRoutes />} />
<Route path="gender/*" element={<GenderRoutes />} />

View File

@ -10,7 +10,7 @@ import { EmptyEnd } from '@/components/EmptyEnd';
import { PageLayout } from '@/components/Layout/PageLayout';
import { SearchInput } from '@/components/SearchInput';
import { BUTTON_TOP_BAR_PROPERTY, TopBar } from '@/components/TopBar/TopBar';
import { useArtistService, useOrderedArtists } from '@/service/Artist';
import { useOrderedArtists } from '@/service/Artist';
import { useThemeMode } from '@/utils/theme-tools';
import { BASE_WRAP_HEIGHT, BASE_WRAP_ICON_SIZE, BASE_WRAP_SPACING, BASE_WRAP_WIDTH } from '@/constants/genericSpacing';
import { MdOutlineForkRight } from 'react-icons/md';

View File

@ -0,0 +1,133 @@
import { Box, Button, Flex, Text } from '@chakra-ui/react';
import { LuDisc3 } from 'react-icons/lu';
import { MdEdit } from 'react-icons/md';
import { Route, Routes, useNavigate, useParams } from 'react-router-dom';
import { Covers } from '@/components/Cover';
import { EmptyEnd } from '@/components/EmptyEnd';
import { PageLayout } from '@/components/Layout/PageLayout';
import { PageLayoutInfoCenter } from '@/components/Layout/PageLayoutInfoCenter';
import { BUTTON_TOP_BAR_PROPERTY, TopBar } from '@/components/TopBar/TopBar';
import { AlbumEditPopUp } from '@/components/popup/AlbumEditPopUp';
import { TrackEditPopUp } from '@/components/popup/TrackEditPopUp';
import { DisplayTrack } from '@/components/track/DisplayTrack';
import { DisplayTrackFull } from '@/components/track/DisplayTrackFull';
import { useActivePlaylistService } from '@/service/ActivePlaylist';
import { useSpecificAlbum } from '@/service/Album';
import { useTracksOfAnAlbum } from '@/service/Track';
import { useThemeMode } from '@/utils/theme-tools';
import { BASE_WRAP_SPACING } from '@/constants/genericSpacing';
import { DisplayTrackFullId } from '@/components/track/DisplayTrackFullId';
export const OnAirPage = () => {
const { mode } = useThemeMode();
const { playInList } = useActivePlaylistService();
const { playTrackList, trackOffset, setNewPlaylist } = useActivePlaylistService();
const navigate = useNavigate();
const onSelectItem = (trackId: number) => {
let currentPlay = 0;
if (!playTrackList) {
console.log('Fail to get list of on air...');
return;
}
for (let iii = 0; iii < playTrackList.length; iii++) {
if (playTrackList[iii] === trackId) {
currentPlay = iii;
}
}
playInList(currentPlay, playTrackList);
};
const removeTrack = (trackId: number) => {
let elementToRemoveOffset = 0;
if (!playTrackList) {
console.log('Fail to remove element of on air...');
return;
}
const newList: number[] = [];
for (let iii = 0; iii < playTrackList.length; iii++) {
if (playTrackList[iii] === trackId) {
elementToRemoveOffset = iii;
} else {
newList.push(playTrackList[iii])
}
}
let newPlayed = trackOffset;
if (newPlayed != undefined) {
if (elementToRemoveOffset <= newPlayed) {
newPlayed = newPlayed - 1;
}
playInList(newPlayed, newList);
} else {
setNewPlaylist(newList);
}
};
console.log(`playTrackList = ${JSON.stringify(playTrackList, null, 2)}`);
if (!playTrackList) {
return (
<>
<TopBar title="Album detail" />
<PageLayoutInfoCenter>
No data is currently playing...
</PageLayoutInfoCenter>
</>
);
}
return (
<>
<TopBar title="On Air ...">
</TopBar>
<PageLayout>
<Flex
direction="column"
gap={BASE_WRAP_SPACING}
marginX="auto"
padding="20px"
width="80%"
>
{!playTrackList && <>No playing</>}
{playTrackList && playTrackList?.map((data) => (
<Box
minWidth="100%"
//height="60px"
border="1px"
borderColor="brand.900"
backgroundColor={mode('#FFFFFF88', '#00000088')}
key={data}
padding="5px"
as="button"
_hover={{
boxShadow: 'outline-over',
bgColor: mode('#FFFFFFF7', '#000000F7'),
}}
>
<DisplayTrackFullId
trackId={data}
onClick={() => onSelectItem(data)}
contextMenu={[
{
name: 'Edit',
onClick: () => {
navigate(`edit-track/${data}`);
},
},
{
name: 'Remove from playlist',
onClick: () => {
removeTrack(data);
},
},
]}
/>
</Box>
))}
<EmptyEnd />
</Flex>
<Routes>
<Route path="edit-track/:trackId" element={<TrackEditPopUp />} />
<Route path="edit-album/:albumId" element={<AlbumEditPopUp />} />
</Routes>
</PageLayout>
</>
);
};