mirror of
https://github.com/ajnart/homarr.git
synced 2025-11-14 17:26:26 +01:00
💄 Change media-server modal to popover (#1395)
This commit is contained in:
@@ -1,6 +1,5 @@
|
|||||||
import { Card, Divider, Flex, Grid, Group, Text } from '@mantine/core';
|
import { Card, Divider, Flex, Group, Stack, Text } from '@mantine/core';
|
||||||
import { IconDeviceMobile, IconId } from '@tabler/icons-react';
|
import { IconDeviceMobile, IconId } from '@tabler/icons-react';
|
||||||
|
|
||||||
import { GenericSessionInfo } from '~/types/api/media-server/session-info';
|
import { GenericSessionInfo } from '~/types/api/media-server/session-info';
|
||||||
|
|
||||||
export const DetailCollapseable = ({ session }: { session: GenericSessionInfo }) => {
|
export const DetailCollapseable = ({ session }: { session: GenericSessionInfo }) => {
|
||||||
@@ -11,18 +10,18 @@ export const DetailCollapseable = ({ session }: { session: GenericSessionInfo })
|
|||||||
details = [
|
details = [
|
||||||
...details,
|
...details,
|
||||||
{
|
{
|
||||||
title: "Video",
|
title: 'Video',
|
||||||
metrics: [
|
metrics: [
|
||||||
{
|
{
|
||||||
name: "Resolution",
|
name: 'Resolution',
|
||||||
value: `${session.currentlyPlaying.metadata.video.width}x${session.currentlyPlaying.metadata.video.height}`,
|
value: `${session.currentlyPlaying.metadata.video.width}x${session.currentlyPlaying.metadata.video.height}`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Framerate",
|
name: 'Framerate',
|
||||||
value: session.currentlyPlaying.metadata.video.videoFrameRate,
|
value: session.currentlyPlaying.metadata.video.videoFrameRate,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Video Codec",
|
name: 'Video Codec',
|
||||||
value: session.currentlyPlaying.metadata.video.videoCodec,
|
value: session.currentlyPlaying.metadata.video.videoCodec,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -39,14 +38,14 @@ export const DetailCollapseable = ({ session }: { session: GenericSessionInfo })
|
|||||||
details = [
|
details = [
|
||||||
...details,
|
...details,
|
||||||
{
|
{
|
||||||
title: "Audio",
|
title: 'Audio',
|
||||||
metrics: [
|
metrics: [
|
||||||
{
|
{
|
||||||
name: "Audio Channels",
|
name: 'Audio Channels',
|
||||||
value: `${session.currentlyPlaying.metadata.audio.audioChannels}`,
|
value: `${session.currentlyPlaying.metadata.audio.audioChannels}`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Audio Codec",
|
name: 'Audio Codec',
|
||||||
value: session.currentlyPlaying.metadata.audio.audioCodec,
|
value: session.currentlyPlaying.metadata.audio.audioCodec,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
@@ -58,24 +57,24 @@ export const DetailCollapseable = ({ session }: { session: GenericSessionInfo })
|
|||||||
details = [
|
details = [
|
||||||
...details,
|
...details,
|
||||||
{
|
{
|
||||||
title: "Transcoding",
|
title: 'Transcoding',
|
||||||
metrics: [
|
metrics: [
|
||||||
{
|
{
|
||||||
name: "Resolution",
|
name: 'Resolution',
|
||||||
value: `${session.currentlyPlaying.metadata.transcoding.width}x${session.currentlyPlaying.metadata.transcoding.height}`,
|
value: `${session.currentlyPlaying.metadata.transcoding.width}x${session.currentlyPlaying.metadata.transcoding.height}`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Context",
|
name: 'Context',
|
||||||
value: session.currentlyPlaying.metadata.transcoding.context,
|
value: session.currentlyPlaying.metadata.transcoding.context,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Hardware Encoding Requested",
|
name: 'Hardware Encoding Requested',
|
||||||
value: session.currentlyPlaying.metadata.transcoding.transcodeHwRequested
|
value: session.currentlyPlaying.metadata.transcoding.transcodeHwRequested
|
||||||
? 'yes'
|
? 'yes'
|
||||||
: 'no',
|
: 'no',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Source Codec",
|
name: 'Source Codec',
|
||||||
value:
|
value:
|
||||||
session.currentlyPlaying.metadata.transcoding.sourceAudioCodec ||
|
session.currentlyPlaying.metadata.transcoding.sourceAudioCodec ||
|
||||||
session.currentlyPlaying.metadata.transcoding.sourceVideoCodec
|
session.currentlyPlaying.metadata.transcoding.sourceVideoCodec
|
||||||
@@ -83,7 +82,7 @@ export const DetailCollapseable = ({ session }: { session: GenericSessionInfo })
|
|||||||
: undefined,
|
: undefined,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Target Codec",
|
name: 'Target Codec',
|
||||||
value: `${session.currentlyPlaying.metadata.transcoding.videoCodec} ${session.currentlyPlaying.metadata.transcoding.audioCodec}`,
|
value: `${session.currentlyPlaying.metadata.transcoding.videoCodec} ${session.currentlyPlaying.metadata.transcoding.audioCodec}`,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
@@ -109,11 +108,12 @@ export const DetailCollapseable = ({ session }: { session: GenericSessionInfo })
|
|||||||
<Text>{session.sessionName}</Text>
|
<Text>{session.sessionName}</Text>
|
||||||
</Flex>
|
</Flex>
|
||||||
{details.length > 0 && (
|
{details.length > 0 && (
|
||||||
<Divider label={"Stats for nerds"} labelPosition="center" mt="lg" mb="sm" />
|
<Divider label={'Stats for nerds'} labelPosition="center" mt="lg" mb="sm" />
|
||||||
)}
|
)}
|
||||||
<Grid>
|
<Group align="start">
|
||||||
{details.map((detail, index) => (
|
{details.map((detail, index) => (
|
||||||
<Grid.Col xs={12} sm={6} key={index}>
|
<>
|
||||||
|
<Stack spacing={0} key={index}>
|
||||||
<Text weight="bold">{detail.title}</Text>
|
<Text weight="bold">{detail.title}</Text>
|
||||||
{detail.metrics
|
{detail.metrics
|
||||||
.filter((x) => x.value !== undefined)
|
.filter((x) => x.value !== undefined)
|
||||||
@@ -123,9 +123,13 @@ export const DetailCollapseable = ({ session }: { session: GenericSessionInfo })
|
|||||||
<Text>{metric.value}</Text>
|
<Text>{metric.value}</Text>
|
||||||
</Group>
|
</Group>
|
||||||
))}
|
))}
|
||||||
</Grid.Col>
|
</Stack>
|
||||||
|
{index < details.length - 1 && (
|
||||||
|
<Divider key={'divider' + index} orientation="vertical" />
|
||||||
|
)}
|
||||||
|
</>
|
||||||
))}
|
))}
|
||||||
</Grid>
|
</Group>
|
||||||
</Card>
|
</Card>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,9 +1,8 @@
|
|||||||
import { Avatar, Collapse, Flex, Text, createStyles } from '@mantine/core';
|
import { Avatar, Flex, Popover, Text, createStyles } from '@mantine/core';
|
||||||
import { useState } from 'react';
|
|
||||||
|
|
||||||
import { AppAvatar } from '~/components/AppAvatar';
|
import { AppAvatar } from '~/components/AppAvatar';
|
||||||
import { GenericSessionInfo } from '~/types/api/media-server/session-info';
|
import { GenericSessionInfo } from '~/types/api/media-server/session-info';
|
||||||
import { AppType } from '~/types/app';
|
import { AppType } from '~/types/app';
|
||||||
|
|
||||||
import { DetailCollapseable } from './DetailCollapseable';
|
import { DetailCollapseable } from './DetailCollapseable';
|
||||||
import { NowPlayingDisplay } from './NowPlayingDisplay';
|
import { NowPlayingDisplay } from './NowPlayingDisplay';
|
||||||
|
|
||||||
@@ -13,12 +12,20 @@ interface TableRowProps {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const TableRow = ({ session, app }: TableRowProps) => {
|
export const TableRow = ({ session, app }: TableRowProps) => {
|
||||||
const [collapseOpen, setCollapseOpen] = useState(false);
|
|
||||||
const hasUserThumb = session.userProfilePicture !== undefined;
|
const hasUserThumb = session.userProfilePicture !== undefined;
|
||||||
const { classes } = useStyles();
|
const { classes } = useStyles();
|
||||||
return (
|
return (
|
||||||
<>
|
<Popover
|
||||||
<tr className={classes.dataRow} onClick={() => setCollapseOpen(!collapseOpen)}>
|
withArrow
|
||||||
|
withinPortal
|
||||||
|
radius="lg"
|
||||||
|
shadow="sm"
|
||||||
|
transitionProps={{
|
||||||
|
transition: 'pop',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Popover.Target>
|
||||||
|
<tr className={classes.dataRow}>
|
||||||
<td>
|
<td>
|
||||||
<Flex wrap="nowrap" gap="xs">
|
<Flex wrap="nowrap" gap="xs">
|
||||||
{app?.appearance.iconUrl && <AppAvatar iconUrl={app.appearance.iconUrl} />}
|
{app?.appearance.iconUrl && <AppAvatar iconUrl={app.appearance.iconUrl} />}
|
||||||
@@ -41,14 +48,11 @@ export const TableRow = ({ session, app }: TableRowProps) => {
|
|||||||
<NowPlayingDisplay session={session} />
|
<NowPlayingDisplay session={session} />
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
</Popover.Target>
|
||||||
<td className={classes.collapseTableDataCell} colSpan={3}>
|
<Popover.Dropdown>
|
||||||
<Collapse in={collapseOpen} w="100%">
|
|
||||||
<DetailCollapseable session={session} />
|
<DetailCollapseable session={session} />
|
||||||
</Collapse>
|
</Popover.Dropdown>
|
||||||
</td>
|
</Popover>
|
||||||
</tr>
|
|
||||||
</>
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -56,8 +60,4 @@ const useStyles = createStyles(() => ({
|
|||||||
dataRow: {
|
dataRow: {
|
||||||
cursor: 'pointer',
|
cursor: 'pointer',
|
||||||
},
|
},
|
||||||
collapseTableDataCell: {
|
|
||||||
border: 'none !important',
|
|
||||||
padding: '0 !important',
|
|
||||||
},
|
|
||||||
}));
|
}));
|
||||||
|
|||||||
Reference in New Issue
Block a user