mirror of
https://github.com/Dispatcharr/Dispatcharr.git
synced 2026-07-28 04:24:33 +00:00
virtual list for logos so they don't all load in at the same time
This commit is contained in:
parent
739e726bb9
commit
c947f56a6c
1 changed files with 76 additions and 18 deletions
|
|
@ -29,6 +29,7 @@ import {
|
|||
ScrollArea,
|
||||
Tooltip,
|
||||
NumberInput,
|
||||
Image,
|
||||
} from '@mantine/core';
|
||||
import { ListOrdered, SquarePlus, SquareX, X } from 'lucide-react';
|
||||
import useEPGsStore from '../../store/epgs';
|
||||
|
|
@ -39,6 +40,7 @@ const Channel = ({ channel = null, isOpen, onClose }) => {
|
|||
const theme = useMantineTheme();
|
||||
|
||||
const listRef = useRef(null);
|
||||
const logoListRef = useRef(null);
|
||||
|
||||
const { channelGroups, logos, fetchLogos } = useChannelsStore();
|
||||
const streams = useStreamsStore((state) => state.streams);
|
||||
|
|
@ -50,8 +52,11 @@ const Channel = ({ channel = null, isOpen, onClose }) => {
|
|||
const [channelStreams, setChannelStreams] = useState([]);
|
||||
const [channelGroupModelOpen, setChannelGroupModalOpen] = useState(false);
|
||||
const [epgPopoverOpened, setEpgPopoverOpened] = useState(false);
|
||||
const [logoPopoverOpened, setLogoPopoverOpened] = useState(false);
|
||||
const [selectedEPG, setSelectedEPG] = useState({});
|
||||
const [tvgFilter, setTvgFilter] = useState('');
|
||||
const [logoFilter, setLogoFilter] = useState('');
|
||||
const [logoOptions, setLogoOptions] = useState([]);
|
||||
|
||||
const addStream = (stream) => {
|
||||
const streamSet = new Set(channelStreams);
|
||||
|
|
@ -120,6 +125,7 @@ const Channel = ({ channel = null, isOpen, onClose }) => {
|
|||
setLogoPreview(null);
|
||||
setSubmitting(false);
|
||||
setTvgFilter('');
|
||||
setLogoFilter('');
|
||||
onClose();
|
||||
},
|
||||
});
|
||||
|
|
@ -147,9 +153,14 @@ const Channel = ({ channel = null, isOpen, onClose }) => {
|
|||
} else {
|
||||
formik.resetForm();
|
||||
setTvgFilter('');
|
||||
setLogoFilter('');
|
||||
}
|
||||
}, [channel, tvgsById]);
|
||||
|
||||
useEffect(() => {
|
||||
setLogoOptions([{ id: '0', name: 'Default' }].concat(Object.values(logos)));
|
||||
}, [logos]);
|
||||
|
||||
const renderLogoOption = ({ option, checked }) => {
|
||||
return (
|
||||
<Center style={{ width: '100%' }}>
|
||||
|
|
@ -298,6 +309,10 @@ const Channel = ({ channel = null, isOpen, onClose }) => {
|
|||
tvg.tvg_id.toLowerCase().includes(tvgFilter.toLowerCase())
|
||||
);
|
||||
|
||||
const filteredLogos = logoOptions.filter((logo) =>
|
||||
logo.name.toLowerCase().includes(logoFilter.toLowerCase())
|
||||
);
|
||||
|
||||
return (
|
||||
<>
|
||||
<Modal
|
||||
|
|
@ -388,24 +403,67 @@ const Channel = ({ channel = null, isOpen, onClose }) => {
|
|||
|
||||
<Stack justify="flex-start" style={{ flex: 1 }}>
|
||||
<Group justify="space-between">
|
||||
<Select
|
||||
id="logo_id"
|
||||
name="logo_id"
|
||||
label="Logo"
|
||||
searchable
|
||||
value={formik.values.logo_id}
|
||||
onChange={(value) => {
|
||||
formik.setFieldValue('logo_id', value);
|
||||
}}
|
||||
error={formik.errors.logo_id ? formik.touched.logo_id : ''}
|
||||
size="xs"
|
||||
data={Object.values(logos).map((logo) => ({
|
||||
label: logo.name,
|
||||
value: `${logo.id}`,
|
||||
}))}
|
||||
renderOption={renderLogoOption}
|
||||
comboboxProps={{ width: 75, position: 'bottom-start' }}
|
||||
/>
|
||||
<Popover
|
||||
opened={logoPopoverOpened}
|
||||
onChange={setLogoPopoverOpened}
|
||||
// position="bottom-start"
|
||||
withArrow
|
||||
>
|
||||
<Popover.Target>
|
||||
<TextInput
|
||||
id="logo_id"
|
||||
name="logo_id"
|
||||
label="Logo"
|
||||
readOnly
|
||||
value={logos[formik.values.logo_id]?.name || 'Default'}
|
||||
onClick={() => setLogoPopoverOpened(true)}
|
||||
size="xs"
|
||||
/>
|
||||
</Popover.Target>
|
||||
|
||||
<Popover.Dropdown onMouseDown={(e) => e.stopPropagation()}>
|
||||
<Group>
|
||||
<TextInput
|
||||
placeholder="Filter"
|
||||
value={logoFilter}
|
||||
onChange={(event) =>
|
||||
setLogoFilter(event.currentTarget.value)
|
||||
}
|
||||
mb="xs"
|
||||
size="xs"
|
||||
/>
|
||||
</Group>
|
||||
|
||||
<ScrollArea style={{ height: 200 }}>
|
||||
<List
|
||||
height={200} // Set max height for visible items
|
||||
itemCount={filteredLogos.length}
|
||||
itemSize={20} // Adjust row height for each item
|
||||
width="100%"
|
||||
ref={logoListRef}
|
||||
>
|
||||
{({ index, style }) => (
|
||||
<div style={style}>
|
||||
<Center>
|
||||
<img
|
||||
src={filteredLogos[index].cache_url || logo}
|
||||
height="20"
|
||||
style={{ maxWidth: 80 }}
|
||||
onClick={() => {
|
||||
formik.setFieldValue(
|
||||
'logo_id',
|
||||
filteredLogos[index].id
|
||||
);
|
||||
}}
|
||||
/>
|
||||
</Center>
|
||||
</div>
|
||||
)}
|
||||
</List>
|
||||
</ScrollArea>
|
||||
</Popover.Dropdown>
|
||||
</Popover>
|
||||
|
||||
<img
|
||||
src={
|
||||
logos[formik.values.logo_id]
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue