Add provider list
This commit is contained in:
@@ -2,7 +2,7 @@ import React, { useCallback, useRef, useState } from 'react';
|
||||
import type { TunerHostInfo } from '@jellyfin/sdk/lib/generated-client/models/tuner-host-info';
|
||||
import BaseCard from 'apps/dashboard/components/BaseCard';
|
||||
import DvrIcon from '@mui/icons-material/Dvr';
|
||||
import getProviderName from '../utils/getProviderName';
|
||||
import getProviderName from '../utils/getTunerName';
|
||||
import Menu from '@mui/material/Menu';
|
||||
import MenuItem from '@mui/material/MenuItem';
|
||||
import ListItemIcon from '@mui/material/ListItemIcon';
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
const getProviderConfigurationUrl = (providerId: string) => {
|
||||
switch (providerId?.toLowerCase()) {
|
||||
case 'xmltv':
|
||||
return '/dashboard/livetv/guide?type=xmltv';
|
||||
case 'schedulesdirect':
|
||||
return '/dashboard/livetv/guide?type=schedulesdirect';
|
||||
}
|
||||
};
|
||||
|
||||
export default getProviderConfigurationUrl;
|
||||
@@ -1,16 +1,12 @@
|
||||
const getTunerName = (providerId: string | null | undefined) => {
|
||||
const getProviderName = (providerId: string | null | undefined) => {
|
||||
switch (providerId?.toLowerCase()) {
|
||||
case 'm3u':
|
||||
return 'M3U';
|
||||
case 'hdhomerun':
|
||||
return 'HDHomeRun';
|
||||
case 'hauppauge':
|
||||
return 'Hauppauge';
|
||||
case 'satip':
|
||||
return 'DVB';
|
||||
case 'schedulesdirect':
|
||||
return 'Schedules Direct';
|
||||
case 'xmltv':
|
||||
return 'XMLTV';
|
||||
default:
|
||||
return 'Unknown';
|
||||
}
|
||||
};
|
||||
|
||||
export default getTunerName;
|
||||
export default getProviderName;
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
const getTunerName = (providerId: string | null | undefined) => {
|
||||
switch (providerId?.toLowerCase()) {
|
||||
case 'm3u':
|
||||
return 'M3U';
|
||||
case 'hdhomerun':
|
||||
return 'HDHomeRun';
|
||||
case 'hauppauge':
|
||||
return 'Hauppauge';
|
||||
case 'satip':
|
||||
return 'DVB';
|
||||
default:
|
||||
return 'Unknown';
|
||||
}
|
||||
};
|
||||
|
||||
export default getTunerName;
|
||||
@@ -12,7 +12,8 @@ import useLiveTasks from 'apps/dashboard/features/tasks/hooks/useLiveTasks';
|
||||
import Button from '@mui/material/Button';
|
||||
import RefreshIcon from '@mui/icons-material/Refresh';
|
||||
import AddIcon from '@mui/icons-material/Add';
|
||||
import { Link, useNavigate } from 'react-router-dom';
|
||||
import DvrIcon from '@mui/icons-material/Dvr';
|
||||
import { Form, Link, useNavigate } from 'react-router-dom';
|
||||
import { useStartTask } from 'apps/dashboard/features/tasks/api/useStartTask';
|
||||
import { TaskState } from '@jellyfin/sdk/lib/generated-client/models/task-state';
|
||||
import TaskProgress from 'apps/dashboard/features/tasks/components/TaskProgress';
|
||||
@@ -20,6 +21,13 @@ import Menu from '@mui/material/Menu';
|
||||
import MenuItem from '@mui/material/MenuItem';
|
||||
import ListItemText from '@mui/material/ListItemText';
|
||||
import Alert from '@mui/material/Alert';
|
||||
import List from '@mui/material/List';
|
||||
import ListItem from '@mui/material/ListItem';
|
||||
import ListItemLink from 'components/ListItemLink';
|
||||
import ListItemAvatar from '@mui/material/ListItemAvatar';
|
||||
import Avatar from '@mui/material/Avatar';
|
||||
import getProviderConfigurationUrl from 'apps/dashboard/features/livetv/utils/getProviderConfigurationUrl';
|
||||
import getProviderName from 'apps/dashboard/features/livetv/utils/getProviderName';
|
||||
|
||||
const CONFIG_KEY = 'livetv';
|
||||
|
||||
@@ -79,70 +87,96 @@ export const Component = () => {
|
||||
className='mainAnimatedPage type-interior'
|
||||
>
|
||||
<Box className='content-primary'>
|
||||
{(isConfigError || isTasksError) ? (
|
||||
<Alert severity='error'>{globalize.translate('HeaderError')}</Alert>
|
||||
) : (
|
||||
<Stack spacing={3}>
|
||||
<Typography variant='h2'>{globalize.translate('HeaderTunerDevices')}</Typography>
|
||||
<Form>
|
||||
{(isConfigError || isTasksError) ? (
|
||||
<Alert severity='error'>{globalize.translate('HeaderError')}</Alert>
|
||||
) : (
|
||||
<Stack spacing={3}>
|
||||
<Typography variant='h2'>{globalize.translate('HeaderTunerDevices')}</Typography>
|
||||
|
||||
<Button
|
||||
sx={{ alignSelf: 'flex-start' }}
|
||||
startIcon={<AddIcon />}
|
||||
component={Link}
|
||||
to='/dashboard/livetv/tuner'
|
||||
>
|
||||
{globalize.translate('ButtonAddTunerDevice')}
|
||||
</Button>
|
||||
|
||||
<Stack direction='row' spacing={2}>
|
||||
{ config?.TunerHosts?.map(tunerHost => (
|
||||
<TunerDeviceCard
|
||||
key={tunerHost.Id}
|
||||
tunerHost={tunerHost}
|
||||
/>
|
||||
)) }
|
||||
</Stack>
|
||||
|
||||
<Typography variant='h2'>{globalize.translate('HeaderGuideProviders')}</Typography>
|
||||
|
||||
<Stack direction='row' spacing={1.5}>
|
||||
<Button
|
||||
sx={{ alignSelf: 'flex-start' }}
|
||||
startIcon={<AddIcon />}
|
||||
onClick={showProviderMenu}
|
||||
ref={providerButtonRef}
|
||||
component={Link}
|
||||
to='/dashboard/livetv/tuner'
|
||||
>
|
||||
{globalize.translate('ButtonAddProvider')}
|
||||
{globalize.translate('ButtonAddTunerDevice')}
|
||||
</Button>
|
||||
<Button
|
||||
sx={{ alignSelf: 'flex-start' }}
|
||||
startIcon={<RefreshIcon />}
|
||||
variant='outlined'
|
||||
onClick={refreshGuideData}
|
||||
>
|
||||
{globalize.translate('ButtonRefreshGuideData')}
|
||||
</Button>
|
||||
</Stack>
|
||||
|
||||
{(refreshGuideTask && refreshGuideTask.State === TaskState.Running) && (
|
||||
<Box maxWidth={200}>
|
||||
<Stack direction='row' spacing={2}>
|
||||
{ config.TunerHosts?.map(tunerHost => (
|
||||
<TunerDeviceCard
|
||||
key={tunerHost.Id}
|
||||
tunerHost={tunerHost}
|
||||
/>
|
||||
)) }
|
||||
</Stack>
|
||||
|
||||
<Typography variant='h2'>{globalize.translate('HeaderGuideProviders')}</Typography>
|
||||
|
||||
<Stack direction='row' spacing={1.5}>
|
||||
<Button
|
||||
sx={{ alignSelf: 'flex-start' }}
|
||||
startIcon={<AddIcon />}
|
||||
onClick={showProviderMenu}
|
||||
ref={providerButtonRef}
|
||||
>
|
||||
{globalize.translate('ButtonAddProvider')}
|
||||
</Button>
|
||||
<Button
|
||||
sx={{ alignSelf: 'flex-start' }}
|
||||
startIcon={<RefreshIcon />}
|
||||
variant='outlined'
|
||||
onClick={refreshGuideData}
|
||||
>
|
||||
{globalize.translate('ButtonRefreshGuideData')}
|
||||
</Button>
|
||||
</Stack>
|
||||
|
||||
{(refreshGuideTask && refreshGuideTask.State === TaskState.Running) && (
|
||||
<TaskProgress task={refreshGuideTask} />
|
||||
</Box>
|
||||
)}
|
||||
<Menu
|
||||
anchorEl={anchorEl}
|
||||
open={isMenuOpen}
|
||||
onClose={onMenuClose}
|
||||
>
|
||||
<MenuItem onClick={navigateToSchedulesDirect}>
|
||||
<ListItemText>Schedules Direct</ListItemText>
|
||||
</MenuItem>
|
||||
<MenuItem onClick={navigateToXMLTV}>
|
||||
<ListItemText>XMLTV</ListItemText>
|
||||
</MenuItem>
|
||||
</Menu>
|
||||
</Stack>
|
||||
)}
|
||||
)}
|
||||
<Menu
|
||||
anchorEl={anchorEl}
|
||||
open={isMenuOpen}
|
||||
onClose={onMenuClose}
|
||||
>
|
||||
<MenuItem onClick={navigateToSchedulesDirect}>
|
||||
<ListItemText>Schedules Direct</ListItemText>
|
||||
</MenuItem>
|
||||
<MenuItem onClick={navigateToXMLTV}>
|
||||
<ListItemText>XMLTV</ListItemText>
|
||||
</MenuItem>
|
||||
</Menu>
|
||||
|
||||
<List sx={{ backgroundColor: 'background.paper' }}>
|
||||
{config.ListingProviders?.map(provider => (
|
||||
<ListItem disablePadding key={provider.Id}>
|
||||
<ListItemLink to={getProviderConfigurationUrl(provider.Type || '') + '&id=' + provider.Id}>
|
||||
<ListItemAvatar>
|
||||
<Avatar>
|
||||
<DvrIcon />
|
||||
</Avatar>
|
||||
</ListItemAvatar>
|
||||
<ListItemText
|
||||
primary={getProviderName(provider.Type)}
|
||||
secondary={provider.Path || provider.ListingsId}
|
||||
slotProps={{
|
||||
primary: {
|
||||
variant: 'h3'
|
||||
},
|
||||
secondary: {
|
||||
variant: 'body1'
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</ListItemLink>
|
||||
</ListItem>
|
||||
))}
|
||||
</List>
|
||||
</Stack>
|
||||
)}
|
||||
</Form>
|
||||
</Box>
|
||||
</Page>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user