From f6cdce3cf574bcc6db41c934ca6a9dee9209a4a2 Mon Sep 17 00:00:00 2001 From: euzu Date: Fri, 18 Apr 2025 19:07:47 +0200 Subject: [PATCH] small refactoring webplayer api --- frontend/src/api/playlist-api-service.ts | 8 ++-- .../playlist-browser/playlist-browser.tsx | 4 +- .../component/playlist-tree/playlist-tree.tsx | 37 ++++++++++++++++++- .../playlist-viewer/playlist-viewer.tsx | 7 +++- .../component/video-player/video-player.tsx | 2 +- frontend/src/service/playlist-service.ts | 4 +- src/api/endpoints/v1_api.rs | 4 +- 7 files changed, 53 insertions(+), 13 deletions(-) diff --git a/frontend/src/api/playlist-api-service.ts b/frontend/src/api/playlist-api-service.ts index 1463adde3..e92af8379 100644 --- a/frontend/src/api/playlist-api-service.ts +++ b/frontend/src/api/playlist-api-service.ts @@ -6,13 +6,14 @@ import {PlaylistCategories, PlaylistItem} from "../model/playlist"; const PLAYLIST_API_PATH = 'playlist'; const TARGET_UPDATE_API_PATH = 'playlist/update'; const REVERSE_URL_API_PATH = 'playlist/reverse'; +const WEBPLAYER_URL_API_PATH = 'playlist/webplayer'; export default interface PlaylistApiService extends ApiService { getPlaylist(req: PlaylistRequest): Observable; updateTargets(targets: string[]): Observable; - getReverseUrl(item: PlaylistItem, req: PlaylistRequest): Observable; + getWebPlayerUrl(item: PlaylistItem, req: PlaylistRequest): Observable; } export class DefaultPlaylistApiService extends DefaultApiService implements PlaylistApiService { @@ -28,7 +29,8 @@ export class DefaultPlaylistApiService extends DefaultApiService implements Play return this.post(TARGET_UPDATE_API_PATH, targets); } - getReverseUrl(item: PlaylistItem, req: PlaylistRequest): Observable { - return this.post(REVERSE_URL_API_PATH + '/' + req.sourceId, item); + getWebPlayerUrl(item: PlaylistItem, req: PlaylistRequest): Observable { + return this.post(WEBPLAYER_URL_API_PATH + '/' + req.sourceId, item); } + } diff --git a/frontend/src/component/playlist-browser/playlist-browser.tsx b/frontend/src/component/playlist-browser/playlist-browser.tsx index 09cd9e656..0de622fab 100644 --- a/frontend/src/component/playlist-browser/playlist-browser.tsx +++ b/frontend/src/component/playlist-browser/playlist-browser.tsx @@ -122,7 +122,9 @@ export default function PlaylistBrowser(props: PlaylistBrowserProps) { - void; onPlay?: (playlistItem: PlaylistItem) => void; @@ -21,8 +24,9 @@ interface PlaylistTreeProps { } export default function PlaylistTree(props: PlaylistTreeProps) { - const {serverConfig, data, onCopy, onPlay, onDownload, onWebSearch} = props; + const {serverConfig, data, playlistRequest, onCopy, onPlay, onDownload, onWebSearch} = props; + const services = useServices(); const [, setForceUpdate] = useState(undefined); const expanded = useRef({}); const {enqueueSnackbar/*, closeSnackbar*/} = useSnackbar(); @@ -59,9 +63,35 @@ export default function PlaylistTree(props: PlaylistTreeProps) { setForceUpdate({}); }, []); + const handleClipboardRealUrl = useCallback((e: any) => { + const item = getPlaylistItemById(e.target.dataset.item); + if (item) { + let virtual_id = undefined; + switch (playlistRequest.rtype) { + case PlaylistRequestType.TARGET: + virtual_id = item.virtual_id; + break; + case PlaylistRequestType.INPUT: + case PlaylistRequestType.XTREAM: + case PlaylistRequestType.M3U: + break; + } + if (virtual_id) { + onCopy(item); + copyToClipboard(''+virtual_id).pipe(first()).subscribe({ + next: value => enqueueSnackbar(value ? "URL copied to clipboard" : "Copy to clipboard failed!", {variant: value ? 'success' : 'error'}), + error: _ => enqueueSnackbar("Copy to clipboard failed!", {variant: 'error'}), + complete: noop, + }); + } + } + }, [enqueueSnackbar, getPlaylistItemById, onCopy, playlistRequest, services]); + const handleClipboardUrl = useCallback((e: any) => { const item = getPlaylistItemById(e.target.dataset.item); if (item) { + + onCopy(item); copyToClipboard(item.url).pipe(first()).subscribe({ next: value => enqueueSnackbar(value ? "URL copied to clipboard" : "Copy to clipboard failed!", {variant: value ? 'success' : 'error'}), @@ -119,6 +149,9 @@ export default function PlaylistTree(props: PlaylistTreeProps) {
{getIconByName('LinkRounded')}
+
+ {getIconByName('LinkRounded')} +
{onPlay &&
{getIconByName('PlayArrow')}
} diff --git a/frontend/src/component/playlist-viewer/playlist-viewer.tsx b/frontend/src/component/playlist-viewer/playlist-viewer.tsx index 173e95eee..2cbf883ad 100755 --- a/frontend/src/component/playlist-viewer/playlist-viewer.tsx +++ b/frontend/src/component/playlist-viewer/playlist-viewer.tsx @@ -100,6 +100,7 @@ interface PlaylistViewerProps { playlist: PlaylistCategories; searchChannel: Observable; videoChannel: Observable<[PlaylistItem, PlaylistRequest]>; + playlistRequest: PlaylistRequest; onProgress: (value: boolean) => void; onCopy: (playlistItem: PlaylistItem) => void; onPlay?: (playlistItem: PlaylistItem) => void; @@ -108,7 +109,7 @@ interface PlaylistViewerProps { } export default function PlaylistViewer(props: PlaylistViewerProps) { - const {serverConfig, playlist, searchChannel, videoChannel, + const {serverConfig, playlist, playlistRequest, searchChannel, videoChannel, onProgress, onCopy, onPlay, onDownload, onWebSearch} = props; const {enqueueSnackbar/*, closeSnackbar*/} = useSnackbar(); const [data, setData] = useState(EmptyPlaylistCategories); @@ -161,7 +162,9 @@ export default function PlaylistViewer(props: PlaylistViewerProps) { case 'player' : return default: - return { if (playlistItem.item_type === PlaylistItemType.LiveHls) { playVideo(playlistItem, playlistItem.url); } else { - services.playlist().getReverseUrl(playlistItem, playlistRequest).pipe(first()).subscribe({ + services.playlist().getWebPlayerUrl(playlistItem, playlistRequest).pipe(first()).subscribe({ next: (url: string) => { playVideo(playlistItem, url); }, diff --git a/frontend/src/service/playlist-service.ts b/frontend/src/service/playlist-service.ts index eb9ddccec..8ed8014eb 100644 --- a/frontend/src/service/playlist-service.ts +++ b/frontend/src/service/playlist-service.ts @@ -55,8 +55,8 @@ export default class PlaylistService { return this.playlistApiService.updateTargets(targets); } - getReverseUrl(item: PlaylistItem, req: PlaylistRequest): Observable { - return this.playlistApiService.getReverseUrl(item, req); + getWebPlayerUrl(item: PlaylistItem, req: PlaylistRequest): Observable { + return this.playlistApiService.getWebPlayerUrl(item, req); } } diff --git a/src/api/endpoints/v1_api.rs b/src/api/endpoints/v1_api.rs index 944b3fb34..cdc0f5389 100644 --- a/src/api/endpoints/v1_api.rs +++ b/src/api/endpoints/v1_api.rs @@ -216,7 +216,7 @@ async fn playlist_content( } } -async fn playlist_reverse( +async fn playlist_webplayer( axum::extract::Path(target_id): axum::extract::Path, axum::extract::State(app_state): axum::extract::State>, axum::extract::Json(playlist_item): axum::extract::Json, @@ -302,7 +302,7 @@ pub fn v1_api_register(web_auth_enabled: bool, app_state: Arc, web_ui_ .route("/config/main", axum::routing::post(save_config_main)) .route("/config/user", axum::routing::post(save_config_api_proxy_user)) .route("/config/apiproxy", axum::routing::post(save_config_api_proxy_config)) - .route("/playlist/reverse/{target_id}", axum::routing::post(playlist_reverse)) + .route("/playlist/webplayer/{target_id}", axum::routing::post(playlist_webplayer)) .route("/playlist/update", axum::routing::post(playlist_update)) .route("/playlist", axum::routing::post(playlist_content)) .route("/file/download", axum::routing::post(download_api::queue_download_file))