Enhancement: FloatingVideo player: the native video controls (timeline, play/pause, volume) are now hidden by default when a live stream starts and only appear when the user hovers over the player.

This commit is contained in:
SergeantPanda 2026-04-11 09:34:38 -05:00
parent 8afaa01184
commit 4a6724c94b
2 changed files with 10 additions and 7 deletions

View file

@ -49,6 +49,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Changed
- FloatingVideo player: the native video controls (timeline, play/pause, volume) are now hidden by default when a live stream starts and only appear when the user hovers over the player.
- Enhanced Swagger UI authorization dialog: registered a custom `OpenApiAuthenticationExtension` for `ApiKeyAuthentication` so drf-spectacular now generates an `ApiKeyAuth (apiKey)` entry alongside `jwtAuth`. Both entries include descriptive text linking to the relevant endpoints (`/api/accounts/token/`, `/api/accounts/api-keys/generate/`, `/api/accounts/api-keys/revoke/`).
- Refactored frontend form components (`AccountInfoModal`, `AssignChannelNumbers`, `Channel`, `ChannelBatch`, `ChannelGroup`, `Connection`, `CronBuilder`, `DummyEPG`, and `EPG`) to extract business logic into dedicated utility modules under `src/utils/forms/`. Each extracted module is covered by unit tests. Mantine compound component references (`Table.Tbody`, `Popover.Target`, `Accordion.Item`, etc.) have been updated to use flat named imports. — Thanks [@nick4810](https://github.com/nick4810)
- Improved the EPG BOM fix from v0.22.1: replaced the `lstrip(b'\xef\xbb\xbf')` / `startswith` approach with `start.find(b'<?xml')`, which locates the XML declaration regardless of any leading bytes BOM, whitespace, or other encoding markers without needing to know what those bytes are.

View file

@ -135,7 +135,8 @@ export default function FloatingVideo() {
const [isLoading, setIsLoading] = useState(false);
const [loadError, setLoadError] = useState(null);
const [showOverlay, setShowOverlay] = useState(true);
const [showOverlay, setShowOverlay] = useState(false);
const [showControls, setShowControls] = useState(false);
const [videoSize, setVideoSize] = useState(() => {
const prefs = getPlayerPrefs();
const saved = prefs.size;
@ -225,7 +226,8 @@ export default function FloatingVideo() {
setIsLoading(true);
setLoadError(null);
setShowOverlay(true); // Show overlay initially
setShowOverlay(false);
setShowControls(false);
console.log('Initializing VOD player for:', streamUrl);
@ -248,7 +250,8 @@ export default function FloatingVideo() {
console.log('Auto-play prevented:', e);
setLoadError('Auto-play was prevented. Click play to start.');
});
// Start overlay timer when video is ready
// Show overlay briefly when video is ready, then auto-hide
setShowOverlay(true);
startOverlayTimer();
};
const handleError = (e) => {
@ -300,10 +303,8 @@ export default function FloatingVideo() {
setIsLoading(true);
setLoadError(null);
setShowControls(false);
console.log('Initializing live stream player for:', streamUrl);
console.log('Access token present:', !!accessToken);
console.log('Current access token from auth store:', accessToken);
try {
if (!mpegts.getFeatureList().mseLivePlayback) {
setIsLoading(false);
@ -851,6 +852,7 @@ export default function FloatingVideo() {
<Box
style={{ position: 'relative' }}
onMouseEnter={() => {
setShowControls(true);
if (contentType === 'vod' && !isLoading) {
setShowOverlay(true);
if (overlayTimeoutRef.current) {
@ -867,7 +869,7 @@ export default function FloatingVideo() {
{/* Enhanced video element with better controls for VOD */}
<video
ref={videoRef}
controls
controls={showControls}
className="floating-video-no-drag"
style={{
width: '100%',