142 lines
5.9 KiB
TypeScript
142 lines
5.9 KiB
TypeScript
|
'use client';
|
||
|
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"
|
||
|
import { faPatreon } from "@fortawesome/free-brands-svg-icons";
|
||
|
import { faGlobe, faTriangleExclamation } from "@fortawesome/free-solid-svg-icons";
|
||
|
import { useState, useEffect } from 'react';
|
||
|
|
||
|
interface IVSSProps {
|
||
|
isMux: boolean;
|
||
|
isB2: boolean;
|
||
|
isIPFSSource: boolean;
|
||
|
isIPFS240: boolean;
|
||
|
isEntitledToCDN: boolean;
|
||
|
setSelectedVideoSource: (option: string) => void;
|
||
|
selectedVideoSource: string;
|
||
|
}
|
||
|
|
||
|
export function VideoSourceSelector({
|
||
|
isMux,
|
||
|
isB2,
|
||
|
isIPFSSource,
|
||
|
isIPFS240,
|
||
|
isEntitledToCDN,
|
||
|
selectedVideoSource,
|
||
|
setSelectedVideoSource,
|
||
|
}: IVSSProps): React.JSX.Element {
|
||
|
|
||
|
// Check for user's entitlements and saved preference when component mounts
|
||
|
useEffect(() => {
|
||
|
// Function to determine the best video source based on entitlements and preferences
|
||
|
const determineBestVideoSource = () => {
|
||
|
if (isEntitledToCDN) {
|
||
|
if (selectedVideoSource === 'Mux' && isMux) {
|
||
|
return 'Mux';
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// if the user has B2 as their preference or they have no preference, use B2
|
||
|
if (selectedVideoSource === 'B2' || !selectedVideoSource) {
|
||
|
return 'B2'
|
||
|
}
|
||
|
|
||
|
// use IPFS only if the user has opted to use it
|
||
|
if (selectedVideoSource === 'IPFSSource' && isIPFSSource) {
|
||
|
return 'IPFSSource';
|
||
|
} else if (isIPFS240) {
|
||
|
return 'IPFS240';
|
||
|
}
|
||
|
// If no sources are available, return an empty string
|
||
|
return '';
|
||
|
};
|
||
|
|
||
|
// If selectedVideoSource is unset, find the value to use
|
||
|
if (selectedVideoSource === '') {
|
||
|
// Load the user's saved preference from storage (e.g., local storage)
|
||
|
const savedPreference = localStorage.getItem('videoSourcePreference');
|
||
|
|
||
|
// Check if the saved preference is valid based on entitlements and available sources
|
||
|
if (savedPreference === 'Mux' && isMux && isEntitledToCDN) {
|
||
|
setSelectedVideoSource('Mux');
|
||
|
} else if (savedPreference === 'B2') {
|
||
|
setSelectedVideoSource('B2');
|
||
|
} else if (savedPreference === 'IPFSSource') {
|
||
|
setSelectedVideoSource('IPFSSource');
|
||
|
} else if (savedPreference === 'IPFS240') {
|
||
|
if (isIPFS240) {
|
||
|
setSelectedVideoSource('IPFS240');
|
||
|
} else {
|
||
|
setSelectedVideoSource('IPFSSource');
|
||
|
}
|
||
|
} else {
|
||
|
// Determine the best video source if the saved preference is invalid or not available
|
||
|
const bestSource = determineBestVideoSource();
|
||
|
setSelectedVideoSource(bestSource);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
}, [isMux, isB2, isIPFSSource, isIPFS240, isEntitledToCDN, selectedVideoSource, setSelectedVideoSource]);
|
||
|
|
||
|
// Handle button click to change the selected video source
|
||
|
const handleSourceClick = (source: string) => {
|
||
|
if (
|
||
|
(source === 'Mux' && isMux && isEntitledToCDN) ||
|
||
|
(source === 'B2' && isB2) ||
|
||
|
(source === 'IPFSSource') ||
|
||
|
(source === 'IPFS240')
|
||
|
) {
|
||
|
setSelectedVideoSource(source);
|
||
|
// Save the user's preference to storage (e.g., local storage)
|
||
|
localStorage.setItem('videoSourcePreference', source);
|
||
|
}
|
||
|
};
|
||
|
|
||
|
return (
|
||
|
<>
|
||
|
<div className="box">
|
||
|
<nav className="level is-text-centered">
|
||
|
<div className="nav-heading">
|
||
|
Video Source Selector
|
||
|
</div>
|
||
|
{(!isMux && !isB2 && !isIPFSSource && !isIPFS240) && <div className="nav-item">
|
||
|
<div className="notification is-danger">
|
||
|
<span><FontAwesomeIcon icon={faTriangleExclamation}></FontAwesomeIcon> No video sources available</span>
|
||
|
</div>
|
||
|
</div>}
|
||
|
{(isMux) && <div className="nav-item">
|
||
|
<button onClick={() => handleSourceClick('Mux')} disabled={!isEntitledToCDN} className={`button ${selectedVideoSource === 'Mux' && 'is-active'}`}>
|
||
|
<span className="icon">
|
||
|
<FontAwesomeIcon icon={faPatreon} className="fab fa-patreon" />
|
||
|
</span>
|
||
|
<span>CDN 1</span>
|
||
|
</button>
|
||
|
</div>}
|
||
|
{(isB2) && <div className="nav-item">
|
||
|
<button onClick={() => handleSourceClick('B2')} className={`button ${selectedVideoSource === 'B2' && 'is-active'}`}>
|
||
|
<span className="icon">
|
||
|
<FontAwesomeIcon icon={faGlobe} className="fab fa-globe" />
|
||
|
</span>
|
||
|
<span>CDN 2</span>
|
||
|
</button>
|
||
|
</div>}
|
||
|
{(isIPFSSource) && <div className="nav-item">
|
||
|
<button onClick={() => handleSourceClick('IPFSSource')} className={`button ${(selectedVideoSource === 'IPFSSource') && 'is-active'}`}>
|
||
|
<span className="icon">
|
||
|
<FontAwesomeIcon icon={faGlobe} className="fas fa-globe" />
|
||
|
</span>
|
||
|
<span>IPFS Src</span>
|
||
|
</button>
|
||
|
</div>}
|
||
|
{(isIPFS240) && <div className="nav-item">
|
||
|
<button onClick={() => handleSourceClick('IPFS240')} className={`button ${(selectedVideoSource === 'IPFS240') && 'is-active'}`}>
|
||
|
<span className="icon">
|
||
|
<FontAwesomeIcon icon={faGlobe} className="fas fa-globe" />
|
||
|
</span>
|
||
|
<span>IPFS 240p</span>
|
||
|
</button>
|
||
|
</div>}
|
||
|
</nav>
|
||
|
</div>
|
||
|
</>
|
||
|
)
|
||
|
}
|