added controls to player

This commit is contained in:
dank074 2021-09-20 03:02:51 -05:00
parent 433c795325
commit 3e9c685987
2 changed files with 116 additions and 32 deletions

View File

@ -22,6 +22,7 @@
"react-slider": "^1.3.1", "react-slider": "^1.3.1",
"react-transition-group": "^4.4.2", "react-transition-group": "^4.4.2",
"react-virtualized": "^9.22.3", "react-virtualized": "^9.22.3",
"react-youtube": "^7.13.1",
"typescript": "^4.3.5", "typescript": "^4.3.5",
"web-vitals": "^1.1.2" "web-vitals": "^1.1.2"
}, },

View File

@ -1,16 +1,21 @@
import { ControlYoutubeDisplayPlaybackMessageComposer, SetYoutubeDisplayPlaylistMessageComposer, YoutubeControlVideoMessageEvent, YoutubeDisplayPlaylist, YoutubeDisplayPlaylistsEvent, YoutubeDisplayVideoMessageEvent } from '@nitrots/nitro-renderer'; import { ControlYoutubeDisplayPlaybackMessageComposer, SetYoutubeDisplayPlaylistMessageComposer, YoutubeControlVideoMessageEvent, YoutubeDisplayPlaylist, YoutubeDisplayPlaylistsEvent, YoutubeDisplayVideoMessageEvent } from '@nitrots/nitro-renderer';
import { FC, useCallback, useState } from 'react'; import { FC, useCallback, useMemo, useState } from 'react';
import YouTube, { Options } from 'react-youtube';
import { LocalizeText } from '../../../../../api'; import { LocalizeText } from '../../../../../api';
import { RoomWidgetUpdateYoutubeDisplayEvent } from '../../../../../api/nitro/room/widgets/events/RoomWidgetUpdateYoutubeDisplayEvent'; import { RoomWidgetUpdateYoutubeDisplayEvent } from '../../../../../api/nitro/room/widgets/events/RoomWidgetUpdateYoutubeDisplayEvent';
import { FurnitureYoutubeDisplayWidgetHandler } from '../../../../../api/nitro/room/widgets/handlers/FurnitureYoutubeDisplayWidgetHandler'; import { FurnitureYoutubeDisplayWidgetHandler } from '../../../../../api/nitro/room/widgets/handlers/FurnitureYoutubeDisplayWidgetHandler';
import { CreateEventDispatcherHook, CreateMessageHook, SendMessageHook } from '../../../../../hooks'; import { BatchUpdates, CreateEventDispatcherHook, CreateMessageHook, SendMessageHook } from '../../../../../hooks';
import { NitroCardContentView, NitroCardHeaderView, NitroCardView } from '../../../../../layout'; import { NitroCardContentView, NitroCardHeaderView, NitroCardView } from '../../../../../layout';
import { useRoomContext } from '../../../context/RoomContext'; import { useRoomContext } from '../../../context/RoomContext';
import { YoutubeVideoPlaybackStateEnum } from './utils/YoutubeVideoPlaybackStateEnum';
export const FurnitureYoutubeDisplayView: FC<{}> = props => export const FurnitureYoutubeDisplayView: FC<{}> = props =>
{ {
const [objectId, setObjectId] = useState(-1); const [objectId, setObjectId] = useState(-1);
const [videoUrl, setVideoUrl] = useState<string>(null); const [videoId, setVideoId] = useState<string>(null);
const [videoStart, setVideoStart] = useState<number>(null);
const [videoEnd, setVideoEnd] = useState<number>(null);
const [currentVideoState, setCurrentVideoState] = useState(-1);
const [selectedItem, setSelectedItem] = useState<string>(null); const [selectedItem, setSelectedItem] = useState<string>(null);
const [playlists, setPlaylists] = useState<YoutubeDisplayPlaylist[]>(null); const [playlists, setPlaylists] = useState<YoutubeDisplayPlaylist[]>(null);
const [hasControl, setHasControl] = useState(false); const [hasControl, setHasControl] = useState(false);
@ -31,10 +36,13 @@ export const FurnitureYoutubeDisplayView: FC<{}> = props =>
const close = useCallback(() => const close = useCallback(() =>
{ {
setObjectId(-1); setObjectId(-1);
setVideoUrl(null)
setSelectedItem(null); setSelectedItem(null);
setPlaylists(null); setPlaylists(null);
setHasControl(false); setHasControl(false);
setVideoId(null);
setVideoEnd(null);
setVideoStart(null);
setCurrentVideoState(-1);
}, []); }, []);
CreateEventDispatcherHook(RoomWidgetUpdateYoutubeDisplayEvent.UPDATE_YOUTUBE_DISPLAY, eventDispatcher, onRoomWidgetUpdateYoutubeDisplayEvent); CreateEventDispatcherHook(RoomWidgetUpdateYoutubeDisplayEvent.UPDATE_YOUTUBE_DISPLAY, eventDispatcher, onRoomWidgetUpdateYoutubeDisplayEvent);
@ -47,15 +55,13 @@ export const FurnitureYoutubeDisplayView: FC<{}> = props =>
if(objectId !== parser.furniId) return; if(objectId !== parser.furniId) return;
if(parser.endAtSeconds > 0 || parser.startAtSeconds > 0) BatchUpdates(() =>
{ {
setVideoUrl(`https://www.youtube.com/embed/${parser.videoId}?start=${parser.startAtSeconds}&end=${parser.endAtSeconds}&autoplay=1&disablekb=1&controls=0&origin=${window.origin}&modestbranding=1`); setVideoId(parser.videoId);
} setVideoStart(parser.startAtSeconds);
else setVideoEnd(parser.endAtSeconds);
{ setCurrentVideoState(parser.state);
setVideoUrl(`https://www.youtube.com/embed/${parser.videoId}?autoplay=1&disablekb=1&controls=0&origin=${window.origin}&modestbranding=1`); });
}
}, [objectId]); }, [objectId]);
const onPlaylists = useCallback((event: YoutubeDisplayPlaylistsEvent) => const onPlaylists = useCallback((event: YoutubeDisplayPlaylistsEvent) =>
@ -66,9 +72,15 @@ export const FurnitureYoutubeDisplayView: FC<{}> = props =>
if(objectId !== parser.furniId) return; if(objectId !== parser.furniId) return;
setPlaylists(parser.playlists); BatchUpdates(() =>
setSelectedItem(parser.selectedPlaylistId); {
setVideoUrl(null); setPlaylists(parser.playlists);
setSelectedItem(parser.selectedPlaylistId);
setVideoId(null);
setCurrentVideoState(-1);
setVideoEnd(null);
setVideoStart(null);
});
}, [objectId]); }, [objectId]);
const onControlVideo = useCallback((event: YoutubeControlVideoMessageEvent) => const onControlVideo = useCallback((event: YoutubeControlVideoMessageEvent) =>
@ -76,28 +88,29 @@ export const FurnitureYoutubeDisplayView: FC<{}> = props =>
if(objectId === -1) return; if(objectId === -1) return;
const parser = event.getParser(); const parser = event.getParser();
console.log(parser);
if(objectId !== parser.furniId) return; if(objectId !== parser.furniId) return;
switch(parser.commandId) switch(parser.commandId)
{ {
case 1: case 1:
//this._currentVideoPlaybackState = YoutubeVideoPlaybackStateEnum._Str_5825; setCurrentVideoState(YoutubeVideoPlaybackStateEnum.PLAYING);
//this._player.playVideo(); if(player.getPlayerState() !== YoutubeVideoPlaybackStateEnum.PLAYING)
return; player.playVideo();
break;
case 2: case 2:
//this._currentVideoPlaybackState = YoutubeVideoPlaybackStateEnum._Str_6168; setCurrentVideoState(YoutubeVideoPlaybackStateEnum.PAUSED);
//this._player.pauseVideo(); if(player.getPlayerState() !== YoutubeVideoPlaybackStateEnum.PAUSED)
return; player.pauseVideo();
break;
} }
}, [objectId]); }, [objectId, player]);
CreateMessageHook(YoutubeDisplayVideoMessageEvent, onVideo); CreateMessageHook(YoutubeDisplayVideoMessageEvent, onVideo);
CreateMessageHook(YoutubeDisplayPlaylistsEvent, onPlaylists); CreateMessageHook(YoutubeDisplayPlaylistsEvent, onPlaylists);
CreateMessageHook(YoutubeControlVideoMessageEvent, onControlVideo); CreateMessageHook(YoutubeControlVideoMessageEvent, onControlVideo);
const processAction = useCallback( (action: string) => const processAction = useCallback((action: string) =>
{ {
switch(action) switch(action)
{ {
@ -107,10 +120,16 @@ export const FurnitureYoutubeDisplayView: FC<{}> = props =>
case 'playlist_next': case 'playlist_next':
SendMessageHook(new ControlYoutubeDisplayPlaybackMessageComposer(objectId, FurnitureYoutubeDisplayWidgetHandler.CONTROL_COMMAND_NEXT_VIDEO)); SendMessageHook(new ControlYoutubeDisplayPlaybackMessageComposer(objectId, FurnitureYoutubeDisplayWidgetHandler.CONTROL_COMMAND_NEXT_VIDEO));
break; break;
case 'video_click': case 'video_pause':
if(hasControl && videoUrl && videoUrl.length) if(hasControl && videoId && videoId.length)
{ {
// pause or play SendMessageHook(new ControlYoutubeDisplayPlaybackMessageComposer(objectId, FurnitureYoutubeDisplayWidgetHandler.CONTROL_COMMAND_PAUSE_VIDEO));
}
break;
case 'video_play':
if(hasControl && videoId && videoId.length)
{
SendMessageHook(new ControlYoutubeDisplayPlaybackMessageComposer(objectId, FurnitureYoutubeDisplayWidgetHandler.CONTROL_COMMAND_CONTINUE_VIDEO));
} }
break; break;
default: default:
@ -123,7 +142,71 @@ export const FurnitureYoutubeDisplayView: FC<{}> = props =>
SendMessageHook(new SetYoutubeDisplayPlaylistMessageComposer(objectId, action)); SendMessageHook(new SetYoutubeDisplayPlaylistMessageComposer(objectId, action));
setSelectedItem(action); setSelectedItem(action);
} }
}, [hasControl, objectId, selectedItem, videoUrl]); }, [hasControl, objectId, selectedItem, videoId]);
const onReady = useCallback((event: any) =>
{
setPlayer(event.target);
}, []);
const onStateChange = useCallback((event: any) =>
{
setPlayer(event.target);
if(objectId)
{
switch(event.target.getPlayerState())
{
case -1:
case 1:
if(currentVideoState === 2)
{
//event.target.pauseVideo();
}
if(currentVideoState !== 1)
{
processAction('video_play');
}
return;
case 2:
if(currentVideoState !== 2)
{
processAction('video_pause');
}
}
}
}, [currentVideoState, objectId, processAction]);
const getYoutubeOpts = useMemo( () =>
{
if(!videoStart && !videoEnd)
{
return {
height: '390',
width: '435',
playerVars: {
autoplay: 1,
disablekb: 1,
controls: 0,
origin: window.origin,
modestbranding: 1
}
}
}
return {
height: '390',
width: '435',
playerVars: {
autoplay: 1,
disablekb: 1,
controls: 0,
origin: window.origin,
modestbranding: 1,
start: videoStart,
end: videoEnd
}
}
}, [videoEnd, videoStart]);
if((objectId === -1)) return null; if((objectId === -1)) return null;
@ -133,10 +216,10 @@ export const FurnitureYoutubeDisplayView: FC<{}> = props =>
<NitroCardContentView> <NitroCardContentView>
<div className="row w-100 h-100"> <div className="row w-100 h-100">
<div className="youtube-video-container col-9"> <div className="youtube-video-container col-9">
{videoUrl && videoUrl.length > 0 && {(videoId && videoId.length > 0) &&
<iframe title="yt" width="100%" height="100%" src={videoUrl} frameBorder="0" allowFullScreen allow="autoplay" /> <YouTube videoId={videoId} opts={getYoutubeOpts as Options} onReady={onReady} onStateChange={onStateChange} />
} }
{(!videoUrl || videoUrl.length === 0) && {(!videoId || videoId.length === 0) &&
<div className="empty-video w-100 h-100 justify-content-center align-items-center d-flex">{LocalizeText('widget.furni.video_viewer.no_videos')}</div> <div className="empty-video w-100 h-100 justify-content-center align-items-center d-flex">{LocalizeText('widget.furni.video_viewer.no_videos')}</div>
} }
</div> </div>
@ -149,7 +232,7 @@ export const FurnitureYoutubeDisplayView: FC<{}> = props =>
<div className="playlist-list"> <div className="playlist-list">
{playlists && playlists.map(entry => {playlists && playlists.map(entry =>
{ {
return <div className={'playlist-entry cursor-pointer ' + (entry.video === selectedItem ? 'selected' : '')} key={entry.video} onClick={() => processAction(entry.video)}><b>{entry.title}</b> - {entry.description}</div> return <div className={'playlist-entry cursor-pointer ' + (entry.video === selectedItem ? 'selected' : '')} key={entry.video} onClick={() => processAction(entry.video)}><b>{entry.title}</b> - {entry.description}</div>
})} })}
</div> </div>
</div> </div>