mirror of
https://github.com/ajnart/homarr.git
synced 2025-11-09 23:15:46 +01:00
✨ Add preview if media is available on Plex
This commit is contained in:
@@ -9,9 +9,10 @@ import {
|
||||
ScrollArea,
|
||||
createStyles,
|
||||
Tooltip,
|
||||
Button,
|
||||
} from '@mantine/core';
|
||||
import { useMediaQuery } from '@mantine/hooks';
|
||||
import { IconLink, IconPlayerPlay } from '@tabler/icons';
|
||||
import { IconLink } from '@tabler/icons';
|
||||
import { useConfig } from '../../tools/state';
|
||||
import { serviceItem } from '../../tools/types';
|
||||
|
||||
@@ -20,6 +21,7 @@ export interface IMedia {
|
||||
imdbId?: any;
|
||||
artist?: string;
|
||||
title: string;
|
||||
voteAverage?: string;
|
||||
poster?: string;
|
||||
genres: string[];
|
||||
seasonNumber?: number;
|
||||
@@ -55,22 +57,41 @@ export function MediaDisplay(props: { media: IMedia }) {
|
||||
alt={media.title}
|
||||
/>
|
||||
)}
|
||||
<Group direction="column" style={{ minWidth: phone ? 450 : '65vw' }}>
|
||||
<Group noWrap mr="sm" className={classes.overview}>
|
||||
<Group
|
||||
style={{ minWidth: phone ? 450 : '65vw' }}
|
||||
noWrap
|
||||
mr="sm"
|
||||
my="sm"
|
||||
position="apart"
|
||||
className={classes.overview}
|
||||
>
|
||||
<Group direction="column" spacing={0}>
|
||||
<Title order={3}>{media.title}</Title>
|
||||
{media.plexUrl && (
|
||||
<Tooltip label="Open in Plex">
|
||||
<Anchor href={media.plexUrl} target="_blank">
|
||||
<ActionIcon>
|
||||
<IconPlayerPlay />
|
||||
</ActionIcon>
|
||||
</Anchor>
|
||||
</Tooltip>
|
||||
{media.artist && <Text color="gray">New release from {media.artist}</Text>}
|
||||
{(media.episodeNumber || media.seasonNumber) && (
|
||||
<Text color="gray">
|
||||
Season {media.seasonNumber}{' '}
|
||||
{media.episodeNumber && `episode ${media.episodeNumber}`}
|
||||
</Text>
|
||||
)}
|
||||
{media.plexUrl && (
|
||||
<Badge color="green" size="lg">
|
||||
Available on Plex
|
||||
</Badge>
|
||||
</Group>
|
||||
{media.voteAverage && (
|
||||
<Button
|
||||
radius="md"
|
||||
variant="light"
|
||||
color={media.plexUrl ? 'green' : 'cyan'}
|
||||
size="md"
|
||||
onClick={
|
||||
media.plexUrl
|
||||
? () => window.open(media.plexUrl)
|
||||
: () => {
|
||||
// TODO: implement overseerr media requests
|
||||
throw new Error('Need to implement media reqests');
|
||||
}
|
||||
}
|
||||
>
|
||||
{media.plexUrl ? 'Available on Plex' : 'Request'}
|
||||
</Button>
|
||||
)}
|
||||
{media.imdbId && (
|
||||
<Anchor href={`https://www.imdb.com/title/${media.imdbId}`} target="_blank">
|
||||
@@ -80,27 +101,6 @@ export function MediaDisplay(props: { media: IMedia }) {
|
||||
</Anchor>
|
||||
)}
|
||||
</Group>
|
||||
{media.artist && (
|
||||
<Text
|
||||
style={{
|
||||
textAlign: 'center',
|
||||
color: 'gray',
|
||||
}}
|
||||
>
|
||||
New release from {media.artist}
|
||||
</Text>
|
||||
)}
|
||||
{(media.episodeNumber || media.seasonNumber) && (
|
||||
<Text
|
||||
style={{
|
||||
textAlign: 'center',
|
||||
color: 'gray',
|
||||
}}
|
||||
>
|
||||
Season {media.seasonNumber} {media.episodeNumber && `episode ${media.episodeNumber}`}
|
||||
</Text>
|
||||
)}
|
||||
</Group>
|
||||
<Group direction="column" position="apart">
|
||||
<ScrollArea style={{ height: 280, maxWidth: 700 }}>{media.overview}</ScrollArea>
|
||||
<Group align="center" position="center" spacing="xs">
|
||||
|
||||
@@ -12,6 +12,7 @@ export default function OverseerrMediaDisplay(props: any) {
|
||||
seasonNumber: media.mediaInfo?.seasons.length,
|
||||
plexUrl: media.mediaInfo?.plexUrl,
|
||||
imdbId: media.mediaInfo?.imdbId,
|
||||
...media,
|
||||
}}
|
||||
/>
|
||||
);
|
||||
|
||||
@@ -41,6 +41,7 @@ export default function SearchBar(props: any) {
|
||||
const queryUrl = config.settings.searchUrl ?? 'https://www.google.com/search?q=';
|
||||
|
||||
const [OverseerrResults, setOverseerrResults] = useState<any[]>([]);
|
||||
const [loading, setLoading] = useState<boolean>(false);
|
||||
const [icon, setIcon] = useState(<Search />);
|
||||
const [results, setResults] = useState<any[]>([]);
|
||||
const [opened, setOpened] = useState(false);
|
||||
@@ -82,7 +83,9 @@ export default function SearchBar(props: any) {
|
||||
)
|
||||
.then((res) => {
|
||||
setOverseerrResults(res.data.results ?? []);
|
||||
setLoading(false);
|
||||
});
|
||||
setLoading(true);
|
||||
} else {
|
||||
setOverseerrResults([]);
|
||||
axios
|
||||
@@ -142,10 +145,9 @@ export default function SearchBar(props: any) {
|
||||
})}
|
||||
>
|
||||
<Popover
|
||||
opened={opened}
|
||||
opened={OverseerrResults.length > 0 && opened}
|
||||
position="bottom"
|
||||
placement="start"
|
||||
withArrow
|
||||
radius="md"
|
||||
trapFocus={false}
|
||||
transition="pop-bottom-right"
|
||||
|
||||
Reference in New Issue
Block a user