mirror of
https://github.com/Dispatcharr/Dispatcharr.git
synced 2026-01-23 10:45:27 +00:00
fixed first m3u channel group load bug, added searchable selection for tvg-id
This commit is contained in:
parent
b9cae416ec
commit
edf2e360ee
7 changed files with 66 additions and 17 deletions
|
|
@ -9,6 +9,7 @@ import useStreamsStore from './store/streams';
|
|||
import { notifications } from '@mantine/notifications';
|
||||
import useChannelsStore from './store/channels';
|
||||
import usePlaylistsStore from './store/playlists';
|
||||
import useEPGsStore from './store/epgs';
|
||||
|
||||
export const WebsocketContext = createContext(false, null, () => {});
|
||||
|
||||
|
|
@ -19,6 +20,7 @@ export const WebsocketProvider = ({ children }) => {
|
|||
const { fetchStreams } = useStreamsStore();
|
||||
const { setChannelStats, fetchChannelGroups } = useChannelsStore();
|
||||
const { setRefreshProgress } = usePlaylistsStore();
|
||||
const { fetchEPGData } = useEPGsStore();
|
||||
|
||||
const ws = useRef(null);
|
||||
|
||||
|
|
@ -65,6 +67,7 @@ export const WebsocketProvider = ({ children }) => {
|
|||
if (event.data.progress == 100) {
|
||||
fetchStreams();
|
||||
fetchChannelGroups();
|
||||
fetchEPGData();
|
||||
}
|
||||
setRefreshProgress(event.data.account, event.data.progress);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -581,6 +581,18 @@ export default class API {
|
|||
return retval;
|
||||
}
|
||||
|
||||
static async getEPGData() {
|
||||
const response = await fetch(`${host}/api/epg/epgdata/`, {
|
||||
headers: {
|
||||
Authorization: `Bearer ${await API.getAuthToken()}`,
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
});
|
||||
|
||||
const retval = await response.json();
|
||||
return retval;
|
||||
}
|
||||
|
||||
// Notice there's a duplicated "refreshPlaylist" method above;
|
||||
// you might want to rename or remove one if it's not needed.
|
||||
|
||||
|
|
|
|||
|
|
@ -21,14 +21,17 @@ import {
|
|||
Center,
|
||||
Grid,
|
||||
Flex,
|
||||
Select,
|
||||
} from '@mantine/core';
|
||||
import { SquarePlus } from 'lucide-react';
|
||||
import useEPGsStore from '../../store/epgs';
|
||||
|
||||
const Channel = ({ channel = null, isOpen, onClose }) => {
|
||||
const channelGroups = useChannelsStore((state) => state.channelGroups);
|
||||
const streams = useStreamsStore((state) => state.streams);
|
||||
const { profiles: streamProfiles } = useStreamProfilesStore();
|
||||
const { playlists } = usePlaylistsStore();
|
||||
const { tvgs } = useEPGsStore();
|
||||
|
||||
const [logoFile, setLogoFile] = useState(null);
|
||||
const [logoPreview, setLogoPreview] = useState(logo);
|
||||
|
|
@ -60,7 +63,7 @@ const Channel = ({ channel = null, isOpen, onClose }) => {
|
|||
name: '',
|
||||
channel_number: '',
|
||||
channel_group_id: '',
|
||||
stream_profile_id: null,
|
||||
stream_profile_id: '0',
|
||||
tvg_id: '',
|
||||
tvg_name: '',
|
||||
},
|
||||
|
|
@ -74,7 +77,6 @@ const Channel = ({ channel = null, isOpen, onClose }) => {
|
|||
values.stream_profile_id = null;
|
||||
}
|
||||
|
||||
console.log(values);
|
||||
if (channel?.id) {
|
||||
await API.updateChannel({
|
||||
id: channel.id,
|
||||
|
|
@ -104,7 +106,7 @@ const Channel = ({ channel = null, isOpen, onClose }) => {
|
|||
name: channel.name,
|
||||
channel_number: channel.channel_number,
|
||||
channel_group_id: channel.channel_group?.id,
|
||||
stream_profile_id: channel.stream_profile_id,
|
||||
stream_profile_id: channel.stream_profile_id || '0',
|
||||
tvg_id: channel.tvg_id,
|
||||
tvg_name: channel.tvg_name,
|
||||
});
|
||||
|
|
@ -248,6 +250,8 @@ const Channel = ({ channel = null, isOpen, onClose }) => {
|
|||
return <></>;
|
||||
}
|
||||
|
||||
console.log(streamProfiles);
|
||||
|
||||
return (
|
||||
<>
|
||||
<Modal opened={isOpen} onClose={onClose} size={800} title="Channel">
|
||||
|
|
@ -265,7 +269,7 @@ const Channel = ({ channel = null, isOpen, onClose }) => {
|
|||
|
||||
<Grid>
|
||||
<Grid.Col span={11}>
|
||||
<NativeSelect
|
||||
<Select
|
||||
id="channel_group_id"
|
||||
name="channel_group_id"
|
||||
label="Channel Group"
|
||||
|
|
@ -276,7 +280,7 @@ const Channel = ({ channel = null, isOpen, onClose }) => {
|
|||
? formik.touched.channel_group_id
|
||||
: ''
|
||||
}
|
||||
data={channelGroups.map((option, index) => ({
|
||||
data={Object.values(channelGroups).map((option, index) => ({
|
||||
value: `${option.id}`,
|
||||
label: option.name,
|
||||
}))}
|
||||
|
|
@ -296,18 +300,20 @@ const Channel = ({ channel = null, isOpen, onClose }) => {
|
|||
</Grid.Col>
|
||||
</Grid>
|
||||
|
||||
<NativeSelect
|
||||
<Select
|
||||
id="stream_profile_id"
|
||||
label="Stream Profile"
|
||||
name="stream_profile_id"
|
||||
value={formik.values.stream_profile_id}
|
||||
onChange={formik.handleChange}
|
||||
onChange={(value) => {
|
||||
formik.setFieldValue('stream_profile_id', value); // Update Formik's state with the new value
|
||||
}}
|
||||
error={
|
||||
formik.errors.stream_profile_id
|
||||
? formik.touched.stream_profile_id
|
||||
: ''
|
||||
}
|
||||
data={[{ value: null, label: '(use default)' }].concat(
|
||||
data={[{ value: '0', label: '(use default)' }].concat(
|
||||
streamProfiles.map((option) => ({
|
||||
value: `${option.id}`,
|
||||
label: option.name,
|
||||
|
|
@ -339,13 +345,20 @@ const Channel = ({ channel = null, isOpen, onClose }) => {
|
|||
error={formik.errors.tvg_name ? formik.touched.tvg_name : ''}
|
||||
/>
|
||||
|
||||
<TextInput
|
||||
<Select
|
||||
id="tvg_id"
|
||||
name="tvg_id"
|
||||
label="TVG ID"
|
||||
searchable
|
||||
value={formik.values.tvg_id}
|
||||
onChange={formik.handleChange}
|
||||
error={formik.errors.tvg_id ? formik.touched.tvg_id : ''}
|
||||
onChange={(value) => {
|
||||
formik.setFieldValue('tvg_id', value); // Update Formik's state with the new value
|
||||
}}
|
||||
error={formik.errors.tvg_id}
|
||||
data={tvgs.map((tvg) => ({
|
||||
value: tvg.name,
|
||||
label: tvg.tvg_id,
|
||||
}))}
|
||||
/>
|
||||
|
||||
<TextInput
|
||||
|
|
|
|||
|
|
@ -18,9 +18,12 @@ import {
|
|||
Space,
|
||||
} from '@mantine/core';
|
||||
import M3UGroupFilter from './M3UGroupFilter';
|
||||
import useChannelsStore from '../../store/channels';
|
||||
|
||||
const M3U = ({ playlist = null, isOpen, onClose, playlistCreated = false }) => {
|
||||
const userAgents = useUserAgentsStore((state) => state.userAgents);
|
||||
const { userAgents } = useUserAgentsStore();
|
||||
const { fetchChannelGroups } = useChannelsStore();
|
||||
|
||||
const [file, setFile] = useState(null);
|
||||
const [profileModalOpen, setProfileModalOpen] = useState(false);
|
||||
const [groupFilterModalOpen, setGroupFilterModalOpen] = useState(false);
|
||||
|
|
@ -59,6 +62,8 @@ const M3U = ({ playlist = null, isOpen, onClose, playlistCreated = false }) => {
|
|||
...values,
|
||||
uploaded_file: file,
|
||||
});
|
||||
|
||||
await fetchChannelGroups();
|
||||
}
|
||||
|
||||
resetForm();
|
||||
|
|
|
|||
|
|
@ -31,7 +31,10 @@ const M3UGroupFilter = ({ playlist = null, isOpen, onClose }) => {
|
|||
const [groupFilter, setGroupFilter] = useState('');
|
||||
|
||||
useEffect(() => {
|
||||
console.log(playlist.channel_groups);
|
||||
if (Object.keys(channelGroups).length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
setGroupStates(
|
||||
playlist.channel_groups.map((group) => ({
|
||||
...group,
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@ const useAuthStore = create((set, get) => ({
|
|||
useUserAgentsStore.getState().fetchUserAgents(),
|
||||
usePlaylistsStore.getState().fetchPlaylists(),
|
||||
useEPGsStore.getState().fetchEPGs(),
|
||||
useEPGsStore.getState().fetchEPGData(),
|
||||
useStreamProfilesStore.getState().fetchProfiles(),
|
||||
useSettingsStore.getState().fetchSettings(),
|
||||
]);
|
||||
|
|
|
|||
|
|
@ -1,8 +1,9 @@
|
|||
import { create } from "zustand";
|
||||
import api from "../api";
|
||||
import { create } from 'zustand';
|
||||
import api from '../api';
|
||||
|
||||
const useEPGsStore = create((set) => ({
|
||||
epgs: [],
|
||||
tvgs: [],
|
||||
isLoading: false,
|
||||
error: null,
|
||||
|
||||
|
|
@ -12,8 +13,19 @@ const useEPGsStore = create((set) => ({
|
|||
const epgs = await api.getEPGs();
|
||||
set({ epgs: epgs, isLoading: false });
|
||||
} catch (error) {
|
||||
console.error("Failed to fetch epgs:", error);
|
||||
set({ error: "Failed to load epgs.", isLoading: false });
|
||||
console.error('Failed to fetch epgs:', error);
|
||||
set({ error: 'Failed to load epgs.', isLoading: false });
|
||||
}
|
||||
},
|
||||
|
||||
fetchEPGData: async () => {
|
||||
set({ isLoading: true, error: null });
|
||||
try {
|
||||
const tvgs = await api.getEPGData();
|
||||
set({ tvgs: tvgs, isLoading: false });
|
||||
} catch (error) {
|
||||
console.error('Failed to fetch tvgs:', error);
|
||||
set({ error: 'Failed to load tvgs.', isLoading: false });
|
||||
}
|
||||
},
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue