feat: use api for initial information
This commit is contained in:
@@ -4,7 +4,7 @@ const Channel = require('../models/Channel');
|
||||
|
||||
class ChannelService {
|
||||
constructor() {
|
||||
this.channels = [new Channel('DEFAULT_CHANNEL', process.env.DEFAULT_CHANNEL_URL, "https://images.unsplash.com/photo-1534308143481-c55f00be8bd7?w=64&h=64&fit=crop&crop=faces")];
|
||||
this.channels = [new Channel('DEFAULT_CHANNEL', process.env.DEFAULT_CHANNEL_URL, "https://upload.wikimedia.org/wikipedia/commons/thumb/5/56/Das_Erste-Logo_klein.svg/768px-Das_Erste-Logo_klein.svg.png")];
|
||||
this.currentChannel = this.channels[0];
|
||||
}
|
||||
|
||||
|
||||
@@ -6,35 +6,11 @@ import Chat from './components/chat/Chat';
|
||||
import AddChannelModal from './components/AddChannelModal';
|
||||
import { Channel } from './types';
|
||||
import socketService from './services/SocketService';
|
||||
import apiService from './services/ApiService';
|
||||
|
||||
function App() {
|
||||
const [channels, setChannels] = useState<Channel[]>([
|
||||
{
|
||||
id: 100,
|
||||
name: 'Das Erste',
|
||||
url: 'https://mcdn.daserste.de/daserste/de/master1080p5000.m3u8',
|
||||
avatar: 'https://upload.wikimedia.org/wikipedia/commons/thumb/5/56/Das_Erste-Logo_klein.svg/768px-Das_Erste-Logo_klein.svg.png'
|
||||
},
|
||||
{
|
||||
id: 200,
|
||||
name: 'ZDF',
|
||||
url: 'https://mcdn.daserste.de/daserste/de/master1080p5000.m3u8',
|
||||
avatar: 'https://upload.wikimedia.org/wikipedia/commons/thumb/c/c1/ZDF_logo.svg/2560px-ZDF_logo.svg.png'
|
||||
},
|
||||
{
|
||||
id: 300,
|
||||
name: 'Creative Studio',
|
||||
url: 'https://mcdn.daserste.de/daserste/de/master1080p5000.m3u8',
|
||||
avatar: 'https://images.unsplash.com/photo-1534308143481-c55f00be8bd7?w=64&h=64&fit=crop&crop=faces'
|
||||
},
|
||||
{
|
||||
id: 400,
|
||||
name: 'Creative Studio',
|
||||
url: 'https://mcdn.daserste.de/daserste/de/master1080p5000.m3u8',
|
||||
avatar: 'https://images.unsplash.com/photo-1534308143481-c55f00be8bd7?w=64&h=64&fit=crop&crop=faces'
|
||||
},
|
||||
]);
|
||||
const [selectedChannel, setSelectedChannel] = useState<Channel>(channels[0]);
|
||||
const [channels, setChannels] = useState<Channel[]>([]);
|
||||
const [selectedChannel, setSelectedChannel] = useState<Channel | null>(null);
|
||||
|
||||
const [isModalOpen, setIsModalOpen] = useState(false);
|
||||
const [searchQuery, setSearchQuery] = useState('');
|
||||
@@ -42,6 +18,17 @@ function App() {
|
||||
|
||||
useEffect(() => {
|
||||
|
||||
apiService
|
||||
.request<Channel[]>('/channels/', 'GET')
|
||||
.then((data) => setChannels(data))
|
||||
.catch((error) => console.error('Error loading channels:', error));
|
||||
|
||||
apiService
|
||||
.request<Channel | null>('/channels/current', 'GET')
|
||||
.then((data) => setSelectedChannel(data))
|
||||
.catch((error) => console.error('Error loading current channel:', error));
|
||||
|
||||
|
||||
socketService.connect();
|
||||
|
||||
console.log('Subscribing to events');
|
||||
|
||||
@@ -4,7 +4,7 @@ import socketService from '../services/SocketService';
|
||||
|
||||
interface ChannelListProps {
|
||||
channels: Channel[];
|
||||
selectedChannel: Channel;
|
||||
selectedChannel: Channel | null;
|
||||
}
|
||||
|
||||
function ChannelList({ channels, selectedChannel}: ChannelListProps) {
|
||||
@@ -20,7 +20,7 @@ function ChannelList({ channels, selectedChannel}: ChannelListProps) {
|
||||
key={channel.id}
|
||||
onClick={() => onSelectChannel(channel)}
|
||||
className={`group relative p-2 rounded-lg transition-all ${
|
||||
selectedChannel.id === channel.id
|
||||
selectedChannel?.id === channel.id
|
||||
? 'bg-blue-500 bg-opacity-20 ring-2 ring-blue-500'
|
||||
: 'hover:bg-gray-700'
|
||||
}`}
|
||||
|
||||
@@ -3,7 +3,7 @@ import Hls from 'hls.js';
|
||||
import { Channel } from '../types';
|
||||
|
||||
interface VideoPlayerProps {
|
||||
channel: Channel;
|
||||
channel: Channel | null;
|
||||
}
|
||||
|
||||
function VideoPlayer({ channel }: VideoPlayerProps) {
|
||||
@@ -11,7 +11,7 @@ function VideoPlayer({ channel }: VideoPlayerProps) {
|
||||
const hlsRef = useRef<Hls | null>(null);
|
||||
|
||||
useEffect(() => {
|
||||
if (!videoRef.current) return;
|
||||
if (!videoRef.current || !channel?.url) return;
|
||||
const video = videoRef.current;
|
||||
|
||||
if (Hls.isSupported()) {
|
||||
@@ -84,7 +84,7 @@ function VideoPlayer({ channel }: VideoPlayerProps) {
|
||||
hlsRef.current.destroy();
|
||||
}
|
||||
};
|
||||
}, [channel.url]);
|
||||
}, [channel?.url]);
|
||||
|
||||
const handleVideoClick = (event: React.MouseEvent<HTMLVideoElement>) => {
|
||||
if (videoRef.current?.muted) {
|
||||
|
||||
41
frontend/src/services/ApiService.ts
Normal file
41
frontend/src/services/ApiService.ts
Normal file
@@ -0,0 +1,41 @@
|
||||
const API_BASE_URL = import.meta.env.ITE_BACKEND_URL || '';
|
||||
|
||||
type HttpMethod = 'GET' | 'POST' | 'PUT' | 'DELETE';
|
||||
|
||||
const apiService = {
|
||||
/**
|
||||
* Execute API request
|
||||
* @param path - Path (e.g. "/channels/")
|
||||
* @param method - HTTP-Method (GET, POST, etc.)
|
||||
* @param body - The request body (e.g. POST)
|
||||
* @returns Ein Promise with the parsed JSON response to class T
|
||||
*/
|
||||
async request<T>(path: string, method: HttpMethod = 'GET', body?: unknown): Promise<T> {
|
||||
try {
|
||||
const options: RequestInit = {
|
||||
method,
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
};
|
||||
|
||||
if (body) {
|
||||
options.body = JSON.stringify(body);
|
||||
}
|
||||
|
||||
const response = await fetch(`${API_BASE_URL}${path}`, options);
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`HTTP error! Status: ${response.status}`);
|
||||
}
|
||||
|
||||
const data = (await response.json()) as T;
|
||||
return data;
|
||||
} catch (error) {
|
||||
console.error(`Error in API request to ${path}:`, error);
|
||||
throw error;
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
export default apiService;
|
||||
@@ -11,7 +11,7 @@ class SocketService {
|
||||
if (this.socket?.connected) return;
|
||||
|
||||
console.log('Connecting to WebSocket server');
|
||||
this.socket = io(import.meta.env.BACKEND_WS_URL);
|
||||
this.socket = io(import.meta.env.ITE_BACKEND_URL);
|
||||
|
||||
this.socket.on('connect', () => {
|
||||
console.log('Connected to WebSocket server');
|
||||
|
||||
Reference in New Issue
Block a user