mirror of
https://github.com/euzu/tuliprox.git
synced 2026-10-02 05:52:26 +02:00
80 lines
2.9 KiB
TypeScript
Executable File
80 lines
2.9 KiB
TypeScript
Executable File
import React, {KeyboardEvent, useCallback, useEffect, useRef, useState} from "react";
|
|
|
|
import './source-selector.scss';
|
|
import {getIconByName} from "../../icons/icons";
|
|
import ServerConfig, {InputConfig} from "../../model/server-config";
|
|
import PopupMenu from "../popup-menu/popup-menu";
|
|
import {PlaylistRequest} from "../../model/playlist-request";
|
|
import InputField from "../input-field/input-field";
|
|
|
|
interface SourceSelectorProps {
|
|
serverConfig: ServerConfig;
|
|
onDownload: (req: PlaylistRequest) => void;
|
|
}
|
|
|
|
export default function SourceSelector(props: SourceSelectorProps) {
|
|
const textField = useRef<HTMLInputElement>(null);
|
|
const [popupVisible, setPopupVisible] = useState<{ x: number, y: number }>(undefined);
|
|
const [sources, setSources] = useState<InputConfig[]>([]);
|
|
const [selected, setSelected] = useState<InputConfig>(undefined);
|
|
|
|
const {serverConfig, onDownload} = props;
|
|
|
|
const handleDownload = useCallback(() => {
|
|
const value = textField.current.value;
|
|
if (value && value.trim().length > 0) {
|
|
// eslint-disable-next-line
|
|
if (value.trim() == selected?.name) {
|
|
onDownload({input_id: selected.id});
|
|
} else {
|
|
onDownload({url: value.trim()});
|
|
}
|
|
}
|
|
}, [onDownload, selected]);
|
|
|
|
const handleKeyPress = useCallback((event: KeyboardEvent<any>) => {
|
|
if (event.key === 'Enter') {
|
|
handleDownload();
|
|
}
|
|
}, [handleDownload]);
|
|
|
|
const closePopup = useCallback(() => {
|
|
setPopupVisible(undefined);
|
|
}, []);
|
|
|
|
const openPopup = useCallback((evt: any) => {
|
|
const rect = evt.target.getBoundingClientRect();
|
|
const top = rect.y + rect.height;
|
|
setPopupVisible({x: evt.clientX, y: top});
|
|
}, []);
|
|
|
|
const handleMenuClick = useCallback((evt: any) => {
|
|
const idx = evt.target.dataset.idx;
|
|
if (idx != null) {
|
|
setPopupVisible(undefined);
|
|
setSelected(sources[idx]);
|
|
textField.current.value = sources[idx].name || sources[idx].url;
|
|
}
|
|
}, [sources]);
|
|
|
|
useEffect(()=> {
|
|
if (serverConfig) {
|
|
setSources(serverConfig.sources?.flatMap(source => source.inputs))
|
|
}
|
|
}, [serverConfig]);
|
|
|
|
return <div className={'source-selector'}>
|
|
<InputField label={'Source'}>
|
|
<input onKeyUp={handleKeyPress} ref={textField}/>
|
|
<button title={'Download'} onClick={handleDownload}>{getIconByName('CloudDownload')}</button>
|
|
<button title={'Input List'} onClick={openPopup}>{getIconByName('ArrowDown')}</button>
|
|
</InputField>
|
|
<PopupMenu position={popupVisible} onHide={closePopup}>
|
|
<ul>
|
|
{sources.map((s, idx) =>
|
|
<li key={s.id + '_' + idx} data-idx={idx} onClick={handleMenuClick}>{s.name || s.url}</li>)}
|
|
</ul>
|
|
</PopupMenu>
|
|
</div>
|
|
}
|