Improve header color styles on detail pages

This commit is contained in:
jeffvli 2023-07-20 17:31:56 -07:00
parent 713260bfc9
commit 31eb22f968
11 changed files with 473 additions and 429 deletions

View file

@ -34,6 +34,7 @@ import {
import { SwiperGridCarousel } from '/@/renderer/components/grid-carousel'; import { SwiperGridCarousel } from '/@/renderer/components/grid-carousel';
import { FullWidthDiscCell } from '/@/renderer/components/virtual-table/cells/full-width-disc-cell'; import { FullWidthDiscCell } from '/@/renderer/components/virtual-table/cells/full-width-disc-cell';
import { useCurrentSongRowStyles } from '/@/renderer/components/virtual-table/hooks/use-current-song-row-styles'; import { useCurrentSongRowStyles } from '/@/renderer/components/virtual-table/hooks/use-current-song-row-styles';
import { LibraryBackgroundOverlay } from '/@/renderer/features/shared/components/library-background-overlay';
const isFullWidthRow = (node: RowNode) => { const isFullWidthRow = (node: RowNode) => {
return node.id?.startsWith('disc-'); return node.id?.startsWith('disc-');
@ -41,6 +42,10 @@ const isFullWidthRow = (node: RowNode) => {
const ContentContainer = styled.div` const ContentContainer = styled.div`
position: relative; position: relative;
z-index: 0;
`;
const DetailContainer = styled.div`
display: flex; display: flex;
flex-direction: column; flex-direction: column;
padding: 1rem 2rem 5rem; padding: 1rem 2rem 5rem;
@ -49,17 +54,14 @@ const ContentContainer = styled.div`
.ag-theme-alpine-dark { .ag-theme-alpine-dark {
--ag-header-background-color: rgba(0, 0, 0, 0%) !important; --ag-header-background-color: rgba(0, 0, 0, 0%) !important;
} }
.ag-header {
margin-bottom: 0.5rem;
}
`; `;
interface AlbumDetailContentProps { interface AlbumDetailContentProps {
background?: string;
tableRef: MutableRefObject<AgGridReactType | null>; tableRef: MutableRefObject<AgGridReactType | null>;
} }
export const AlbumDetailContent = ({ tableRef }: AlbumDetailContentProps) => { export const AlbumDetailContent = ({ tableRef, background }: AlbumDetailContentProps) => {
const { albumId } = useParams() as { albumId: string }; const { albumId } = useParams() as { albumId: string };
const server = useCurrentServer(); const server = useCurrentServer();
const detailQuery = useAlbumDetail({ query: { id: albumId }, serverId: server?.id }); const detailQuery = useAlbumDetail({ query: { id: albumId }, serverId: server?.id });
@ -271,10 +273,11 @@ export const AlbumDetailContent = ({ tableRef }: AlbumDetailContentProps) => {
return ( return (
<ContentContainer> <ContentContainer>
<LibraryBackgroundOverlay backgroundColor={background} />
<DetailContainer>
<Box component="section"> <Box component="section">
<Group <Group
ref={showGenres ? null : intersectRef} ref={showGenres ? null : intersectRef}
className="test"
py="1rem" py="1rem"
spacing="md" spacing="md"
> >
@ -283,7 +286,8 @@ export const AlbumDetailContent = ({ tableRef }: AlbumDetailContentProps) => {
<Button <Button
compact compact
loading={ loading={
createFavoriteMutation.isLoading || deleteFavoriteMutation.isLoading createFavoriteMutation.isLoading ||
deleteFavoriteMutation.isLoading
} }
variant="subtle" variant="subtle"
onClick={handleFavorite} onClick={handleFavorite}
@ -324,9 +328,12 @@ export const AlbumDetailContent = ({ tableRef }: AlbumDetailContentProps) => {
component={Link} component={Link}
radius={0} radius={0}
size="md" size="md"
to={generatePath(`${AppRoute.LIBRARY_ALBUMS}?genre=${genre.id}`, { to={generatePath(
`${AppRoute.LIBRARY_ALBUMS}?genre=${genre.id}`,
{
albumId, albumId,
})} },
)}
variant="outline" variant="outline"
> >
{genre.name} {genre.name}
@ -410,7 +417,9 @@ export const AlbumDetailContent = ({ tableRef }: AlbumDetailContentProps) => {
itemType={LibraryItem.ALBUM} itemType={LibraryItem.ALBUM}
route={{ route={{
route: AppRoute.LIBRARY_ALBUMS_DETAIL, route: AppRoute.LIBRARY_ALBUMS_DETAIL,
slugs: [{ idProperty: 'id', slugProperty: 'albumId' }], slugs: [
{ idProperty: 'id', slugProperty: 'albumId' },
],
}} }}
title={{ title={{
label: carousel.title, label: carousel.title,
@ -422,6 +431,7 @@ export const AlbumDetailContent = ({ tableRef }: AlbumDetailContentProps) => {
) : null} ) : null}
</> </>
</Stack> </Stack>
</DetailContainer>
</ContentContainer> </ContentContainer>
); );
}; };

View file

@ -35,7 +35,7 @@ export const AlbumDetailHeader = forwardRef(
}, },
{ {
id: 'duration', id: 'duration',
secondary: true, secondary: false,
value: value:
detailQuery?.data?.duration && formatDurationString(detailQuery.data.duration), detailQuery?.data?.duration && formatDurationString(detailQuery.data.duration),
}, },

View file

@ -57,7 +57,10 @@ const AlbumDetailRoute = () => {
ref={headerRef} ref={headerRef}
background={background} background={background}
/> />
<AlbumDetailContent tableRef={tableRef} /> <AlbumDetailContent
background={background}
tableRef={tableRef}
/>
</NativeScrollArea> </NativeScrollArea>
</AnimatedPage> </AnimatedPage>
); );

View file

@ -35,9 +35,14 @@ import { useAlbumArtistDetail } from '/@/renderer/features/artists/queries/album
import { useTopSongsList } from '/@/renderer/features/artists/queries/top-songs-list-query'; import { useTopSongsList } from '/@/renderer/features/artists/queries/top-songs-list-query';
import { getColumnDefs, VirtualTable } from '/@/renderer/components/virtual-table'; import { getColumnDefs, VirtualTable } from '/@/renderer/components/virtual-table';
import { SwiperGridCarousel } from '/@/renderer/components/grid-carousel'; import { SwiperGridCarousel } from '/@/renderer/components/grid-carousel';
import { LibraryBackgroundOverlay } from '/@/renderer/features/shared/components/library-background-overlay';
const ContentContainer = styled.div` const ContentContainer = styled.div`
position: relative; position: relative;
z-index: 0;
`;
const DetailContainer = styled.div`
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: 3rem; gap: 3rem;
@ -47,13 +52,13 @@ const ContentContainer = styled.div`
.ag-theme-alpine-dark { .ag-theme-alpine-dark {
--ag-header-background-color: rgba(0, 0, 0, 0%) !important; --ag-header-background-color: rgba(0, 0, 0, 0%) !important;
} }
.ag-header {
margin-bottom: 0.5rem;
}
`; `;
export const AlbumArtistDetailContent = () => { interface AlbumArtistDetailContentProps {
background?: string;
}
export const AlbumArtistDetailContent = ({ background }: AlbumArtistDetailContentProps) => {
const { albumArtistId } = useParams() as { albumArtistId: string }; const { albumArtistId } = useParams() as { albumArtistId: string };
const cq = useContainerQuery(); const cq = useContainerQuery();
const handlePlayQueueAdd = usePlayQueueAdd(); const handlePlayQueueAdd = usePlayQueueAdd();
@ -318,6 +323,8 @@ export const AlbumArtistDetailContent = () => {
return ( return (
<ContentContainer ref={cq.ref}> <ContentContainer ref={cq.ref}>
<LibraryBackgroundOverlay backgroundColor={background} />
<DetailContainer>
<Box component="section"> <Box component="section">
<Group spacing="md"> <Group spacing="md">
<PlayButton onClick={() => handlePlay(playButtonBehavior)} /> <PlayButton onClick={() => handlePlay(playButtonBehavior)} />
@ -325,7 +332,8 @@ export const AlbumArtistDetailContent = () => {
<Button <Button
compact compact
loading={ loading={
createFavoriteMutation.isLoading || deleteFavoriteMutation.isLoading createFavoriteMutation.isLoading ||
deleteFavoriteMutation.isLoading
} }
variant="subtle" variant="subtle"
onClick={handleFavorite} onClick={handleFavorite}
@ -433,9 +441,12 @@ export const AlbumArtistDetailContent = () => {
compact compact
uppercase uppercase
component={Link} component={Link}
to={generatePath(AppRoute.LIBRARY_ALBUM_ARTISTS_DETAIL_TOP_SONGS, { to={generatePath(
AppRoute.LIBRARY_ALBUM_ARTISTS_DETAIL_TOP_SONGS,
{
albumArtistId, albumArtistId,
})} },
)}
variant="subtle" variant="subtle"
> >
View all View all
@ -486,6 +497,7 @@ export const AlbumArtistDetailContent = () => {
))} ))}
</Stack> </Stack>
</Box> </Box>
</DetailContainer>
</ContentContainer> </ContentContainer>
); );
}; };

View file

@ -58,7 +58,7 @@ const AlbumArtistDetailRoute = () => {
ref={headerRef} ref={headerRef}
background={background} background={background}
/> />
<AlbumArtistDetailContent /> <AlbumArtistDetailContent background={background} />
</NativeScrollArea> </NativeScrollArea>
</AnimatedPage> </AnimatedPage>
); );

View file

@ -55,7 +55,7 @@ const BackgroundImageOverlay = styled.div`
z-index: -1; z-index: -1;
width: 100%; width: 100%;
height: 100%; height: 100%;
background: linear-gradient(180deg, rgba(20, 21, 23, 40%), var(--main-bg)); background: var(--bg-header-overlay);
`; `;
const Controls = () => { const Controls = () => {

View file

@ -42,10 +42,6 @@ const ContentContainer = styled.div`
.ag-theme-alpine-dark { .ag-theme-alpine-dark {
--ag-header-background-color: rgba(0, 0, 0, 0%) !important; --ag-header-background-color: rgba(0, 0, 0, 0%) !important;
} }
.ag-header {
margin-bottom: 0.5rem;
}
`; `;
interface PlaylistDetailContentProps { interface PlaylistDetailContentProps {

View file

@ -0,0 +1,14 @@
import styled from 'styled-components';
export const LibraryBackgroundOverlay = styled.div<{ backgroundColor?: string }>`
position: absolute;
z-index: -1;
width: 100%;
height: 20vh;
min-height: 200px;
background: ${(props) => props.backgroundColor};
background-image: var(--bg-subheader-overlay);
opacity: 0.3;
user-select: none;
pointer-events: none;
`;

View file

@ -1,6 +1,6 @@
import { forwardRef, ReactNode, Ref } from 'react';
import { Center, Group } from '@mantine/core'; import { Center, Group } from '@mantine/core';
import { useMergedRef } from '@mantine/hooks'; import { useMergedRef } from '@mantine/hooks';
import { forwardRef, ReactNode, Ref } from 'react';
import { RiAlbumFill } from 'react-icons/ri'; import { RiAlbumFill } from 'react-icons/ri';
import { Link } from 'react-router-dom'; import { Link } from 'react-router-dom';
import { SimpleImg } from 'react-simple-img'; import { SimpleImg } from 'react-simple-img';
@ -57,6 +57,7 @@ const BackgroundImage = styled.div<{ background: string }>`
width: 100%; width: 100%;
height: 100%; height: 100%;
background: ${(props) => props.background}; background: ${(props) => props.background};
opacity: 0.9;
`; `;
const BackgroundImageOverlay = styled.div` const BackgroundImageOverlay = styled.div`
@ -66,8 +67,7 @@ const BackgroundImageOverlay = styled.div`
z-index: 0; z-index: 0;
width: 100%; width: 100%;
height: 100%; height: 100%;
background: linear-gradient(180deg, rgba(25, 26, 28, 5%), var(--main-bg)), background: var(--bg-header-overlay);
var(--background-noise);
`; `;
interface LibraryHeaderProps { interface LibraryHeaderProps {

View file

@ -123,6 +123,10 @@
--card-poster-radius: 3px; --card-poster-radius: 3px;
--background-noise: url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIzMDAiIGhlaWdodD0iMzAwIj48ZmlsdGVyIGlkPSJhIiB4PSIwIiB5PSIwIj48ZmVUdXJidWxlbmNlIHR5cGU9ImZyYWN0YWxOb2lzZSIgYmFzZUZyZXF1ZW5jeT0iLjc1IiBzdGl0Y2hUaWxlcz0ic3RpdGNoIi8+PGZlQ29sb3JNYXRyaXggdHlwZT0ic2F0dXJhdGUiIHZhbHVlcz0iMCIvPjwvZmlsdGVyPjxwYXRoIGZpbHRlcj0idXJsKCNhKSIgb3BhY2l0eT0iLjA1IiBkPSJNMCAwaDMwMHYzMDBIMHoiLz48L3N2Zz4='); --background-noise: url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIzMDAiIGhlaWdodD0iMzAwIj48ZmlsdGVyIGlkPSJhIiB4PSIwIiB5PSIwIj48ZmVUdXJidWxlbmNlIHR5cGU9ImZyYWN0YWxOb2lzZSIgYmFzZUZyZXF1ZW5jeT0iLjc1IiBzdGl0Y2hUaWxlcz0ic3RpdGNoIi8+PGZlQ29sb3JNYXRyaXggdHlwZT0ic2F0dXJhdGUiIHZhbHVlcz0iMCIvPjwvZmlsdGVyPjxwYXRoIGZpbHRlcj0idXJsKCNhKSIgb3BhY2l0eT0iLjA1IiBkPSJNMCAwaDMwMHYzMDBIMHoiLz48L3N2Zz4=');
--bg-header-overlay: linear-gradient(transparent 0%, rgba(0, 0, 0, 50%) 100%),
var(--background-noise);
--bg-subheader-overlay: linear-gradient(180deg, rgba(0, 0, 0, 5%) 0%, var(--main-bg) 100%),
var(--background-noise);
--table-header-bg: rgb(24, 24, 24); --table-header-bg: rgb(24, 24, 24);
--table-header-fg: rgb(179, 179, 179); --table-header-fg: rgb(179, 179, 179);

View file

@ -102,6 +102,11 @@ body[data-theme='defaultLight'] {
--card-poster-bg-hover: transparent; --card-poster-bg-hover: transparent;
--card-poster-radius: 5px; --card-poster-radius: 5px;
--bg-header-overlay: linear-gradient(rgba(255, 255, 255, 50%) 0%, rgba(255, 255, 255, 20%)),
var(--background-noise);
--bg-subheader-overlay: linear-gradient(180deg, rgba(255, 255, 255, 5%) 0%, var(--main-bg)),
var(--background-noise);
--table-header-bg: rgb(245, 245, 245); --table-header-bg: rgb(245, 245, 245);
--table-header-fg: rgb(40, 40, 40); --table-header-fg: rgb(40, 40, 40);
--table-border: none; --table-border: none;