mirror of
https://github.com/mediacms-io/mediacms.git
synced 2026-01-20 07:12:58 -05:00
feat: add showUserAvatar option to video player and embed UI
- Added 'showUserAvatar' parameter to control author avatar visibility in embed info overlay - Implemented UI toggle in MediaShareEmbed for the 'showUserAvatar' option - Propagated 'showUserAvatar' through EmbedPage, VideoViewer, and VideoJSEmbed - Updated test iframe index with all 8 combinations of showTitle, showRelated, and showUserAvatar
This commit is contained in:
@@ -16,6 +16,7 @@ class EmbedInfoOverlay extends Component {
|
||||
this.videoUrl = options.videoUrl || '';
|
||||
this.showTitle = options.showTitle !== undefined ? options.showTitle : true;
|
||||
this.showRelated = options.showRelated !== undefined ? options.showRelated : true;
|
||||
this.showUserAvatar = options.showUserAvatar !== undefined ? options.showUserAvatar : true;
|
||||
|
||||
// Initialize after player is ready
|
||||
this.player().ready(() => {
|
||||
@@ -59,7 +60,7 @@ class EmbedInfoOverlay extends Component {
|
||||
`;
|
||||
|
||||
// Create avatar container
|
||||
if (this.authorThumbnail) {
|
||||
if (this.authorThumbnail && this.showUserAvatar) {
|
||||
const avatarContainer = document.createElement('div');
|
||||
avatarContainer.className = 'embed-avatar-container';
|
||||
avatarContainer.style.cssText = `
|
||||
|
||||
@@ -170,7 +170,7 @@ const enableStandardButtonTooltips = (player) => {
|
||||
}, 500); // Delay to ensure all components are ready
|
||||
};
|
||||
|
||||
function VideoJSPlayer({ videoId = 'default-video', showTitle = true, showRelated = true }) {
|
||||
function VideoJSPlayer({ videoId = 'default-video', showTitle = true, showRelated = true, showUserAvatar = true }) {
|
||||
const videoRef = useRef(null);
|
||||
const playerRef = useRef(null); // Track the player instance
|
||||
const userPreferences = useRef(new UserPreferences()); // User preferences instance
|
||||
@@ -209,9 +209,22 @@ function VideoJSPlayer({ videoId = 'default-video', showTitle = true, showRelate
|
||||
return showRelated;
|
||||
}, [isEmbedPlayer, showRelated]);
|
||||
|
||||
// Read showUserAvatar from URL parameter if available (for embed players)
|
||||
const getShowUserAvatarFromURL = useMemo(() => {
|
||||
if (isEmbedPlayer && typeof window !== 'undefined') {
|
||||
const urlParams = new URLSearchParams(window.location.search);
|
||||
const urlShowUserAvatar = urlParams.get('showUserAvatar');
|
||||
if (urlShowUserAvatar !== null) {
|
||||
return urlShowUserAvatar === '1' || urlShowUserAvatar === 'true';
|
||||
}
|
||||
}
|
||||
return showUserAvatar;
|
||||
}, [isEmbedPlayer, showUserAvatar]);
|
||||
|
||||
// Use URL parameter value if available, otherwise use prop value
|
||||
const finalShowTitle = isEmbedPlayer ? getShowTitleFromURL : showTitle;
|
||||
const finalShowRelated = isEmbedPlayer ? getShowRelatedFromURL : showRelated;
|
||||
const finalShowUserAvatar = isEmbedPlayer ? getShowUserAvatarFromURL : showUserAvatar;
|
||||
|
||||
// Utility function to detect touch devices
|
||||
const isTouchDevice = useMemo(() => {
|
||||
@@ -1318,6 +1331,7 @@ function VideoJSPlayer({ videoId = 'default-video', showTitle = true, showRelate
|
||||
relatedVideos,
|
||||
goToNextVideo,
|
||||
showRelated: finalShowRelated,
|
||||
showUserAvatar: finalShowUserAvatar,
|
||||
});
|
||||
customComponents.current.endScreenHandler = endScreenHandler; // Store for cleanup
|
||||
|
||||
@@ -2239,6 +2253,7 @@ function VideoJSPlayer({ videoId = 'default-video', showTitle = true, showRelate
|
||||
videoUrl: currentVideo.url,
|
||||
showTitle: finalShowTitle,
|
||||
showRelated: finalShowRelated,
|
||||
showUserAvatar: finalShowUserAvatar,
|
||||
});
|
||||
}
|
||||
// END: Add Embed Info Overlay Component
|
||||
|
||||
@@ -71,6 +71,7 @@ export class EndScreenHandler {
|
||||
relatedVideos,
|
||||
goToNextVideo,
|
||||
showRelated,
|
||||
showUserAvatar,
|
||||
} = this.options;
|
||||
|
||||
// For embed players, show big play button when video ends
|
||||
|
||||
@@ -35,6 +35,7 @@ const VideoJSEmbed = ({
|
||||
inEmbed,
|
||||
showTitle,
|
||||
showRelated,
|
||||
showUserAvatar,
|
||||
hasTheaterMode,
|
||||
hasNextLink,
|
||||
nextLink,
|
||||
@@ -67,6 +68,7 @@ const VideoJSEmbed = ({
|
||||
const urlAutoplay = getUrlParameter('autoplay');
|
||||
const urlMuted = getUrlParameter('muted');
|
||||
const urlShowRelated = getUrlParameter('showRelated');
|
||||
const urlShowUserAvatar = getUrlParameter('showUserAvatar');
|
||||
|
||||
window.MEDIA_DATA = {
|
||||
data: data || {},
|
||||
@@ -90,6 +92,7 @@ const VideoJSEmbed = ({
|
||||
inEmbed: inEmbed || false,
|
||||
showTitle: showTitle || false,
|
||||
showRelated: showRelated !== undefined ? showRelated : (urlShowRelated === '1' || urlShowRelated === 'true' || urlShowRelated === null),
|
||||
showUserAvatar: showUserAvatar !== undefined ? showUserAvatar : (urlShowUserAvatar === '1' || urlShowUserAvatar === 'true' || urlShowUserAvatar === null),
|
||||
hasTheaterMode: hasTheaterMode || false,
|
||||
hasNextLink: hasNextLink || false,
|
||||
nextLink: nextLink || null,
|
||||
@@ -100,6 +103,7 @@ const VideoJSEmbed = ({
|
||||
urlAutoplay: urlAutoplay === '1',
|
||||
urlMuted: urlMuted === '1',
|
||||
urlShowRelated: urlShowRelated === '1' || urlShowRelated === 'true',
|
||||
urlShowUserAvatar: urlShowUserAvatar === '1' || urlShowUserAvatar === 'true',
|
||||
onClickNextCallback: onClickNextCallback || null,
|
||||
onClickPreviousCallback: onClickPreviousCallback || null,
|
||||
onStateUpdateCallback: onStateUpdateCallback || null,
|
||||
|
||||
@@ -21,6 +21,7 @@ export function MediaShareEmbed(props) {
|
||||
const [keepAspectRatio, setKeepAspectRatio] = useState(false);
|
||||
const [showTitle, setShowTitle] = useState(false);
|
||||
const [showRelated, setShowRelated] = useState(true);
|
||||
const [showUserAvatar, setShowUserAvatar] = useState(true);
|
||||
const [aspectRatio, setAspectRatio] = useState('16:9');
|
||||
const [embedWidthValue, setEmbedWidthValue] = useState(embedVideoDimensions.width);
|
||||
const [embedWidthUnit, setEmbedWidthUnit] = useState(embedVideoDimensions.widthUnit);
|
||||
@@ -102,6 +103,10 @@ export function MediaShareEmbed(props) {
|
||||
setShowRelated(!showRelated);
|
||||
}
|
||||
|
||||
function onShowUserAvatarChange() {
|
||||
setShowUserAvatar(!showUserAvatar);
|
||||
}
|
||||
|
||||
function onAspectRatioChange() {
|
||||
const newVal = aspectRatioValueRef.current.value;
|
||||
|
||||
@@ -147,8 +152,8 @@ export function MediaShareEmbed(props) {
|
||||
<div className="media-embed-wrap">
|
||||
<SiteConsumer>
|
||||
{(site) => <>
|
||||
{/* <VideoViewer key={`embed-${showTitle}-${showRelated}`} data={MediaPageStore.get('media-data')} siteUrl={site.url} inEmbed={true} showTitle={showTitle} showRelated={showRelated} /> */}
|
||||
<iframe width="100%" height="480px" src={`${links.embed + MediaPageStore.get('media-id')}&showTitle=${showTitle ? '1' : '0'}&showRelated=${showRelated ? '1' : '0'}`} frameborder="0" allowfullscreen></iframe>
|
||||
{/* <VideoViewer key={`embed-${showTitle}-${showRelated}-${showUserAvatar}`} data={MediaPageStore.get('media-data')} siteUrl={site.url} inEmbed={true} showTitle={showTitle} showRelated={showRelated} showUserAvatar={showUserAvatar} /> */}
|
||||
<iframe width="100%" height="480px" src={`${links.embed + MediaPageStore.get('media-id')}&showTitle=${showTitle ? '1' : '0'}&showRelated=${showRelated ? '1' : '0'}&showUserAvatar=${showUserAvatar ? '1' : '0'}`} frameborder="0" allowfullscreen></iframe>
|
||||
</>}
|
||||
</SiteConsumer>
|
||||
</div>
|
||||
@@ -182,6 +187,7 @@ export function MediaShareEmbed(props) {
|
||||
(links.embed.includes('?') ? '&' : '?') +
|
||||
'showTitle=' + (showTitle ? '1' : '0') +
|
||||
'&showRelated=' + (showRelated ? '1' : '0') +
|
||||
'&showUserAvatar=' + (showUserAvatar ? '1' : '0') +
|
||||
'" frameborder="0" allowfullscreen></iframe>'
|
||||
}
|
||||
></textarea>
|
||||
@@ -210,6 +216,13 @@ export function MediaShareEmbed(props) {
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div className="options-group">
|
||||
<label style={{ minHeight: '36px' }}>
|
||||
<input type="checkbox" checked={showUserAvatar} onChange={onShowUserAvatarChange} />
|
||||
Show user avatar
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div className="options-group">
|
||||
<label style={{ minHeight: '36px' }}>
|
||||
<input type="checkbox" checked={keepAspectRatio} onChange={onKeepAspectRatioChange} />
|
||||
|
||||
@@ -414,6 +414,7 @@ export default class VideoViewer extends React.PureComponent {
|
||||
inEmbed: this.props.inEmbed,
|
||||
showTitle: this.props.showTitle,
|
||||
showRelated: this.props.showRelated,
|
||||
showUserAvatar: this.props.showUserAvatar,
|
||||
hasTheaterMode: !this.props.inEmbed,
|
||||
hasNextLink: !!nextLink,
|
||||
nextLink: nextLink,
|
||||
@@ -437,9 +438,15 @@ export default class VideoViewer extends React.PureComponent {
|
||||
|
||||
VideoViewer.defaultProps = {
|
||||
inEmbed: !0,
|
||||
showTitle: !0,
|
||||
showRelated: !0,
|
||||
showUserAvatar: !0,
|
||||
siteUrl: PropTypes.string.isRequired,
|
||||
};
|
||||
|
||||
VideoViewer.propTypes = {
|
||||
inEmbed: PropTypes.bool,
|
||||
showTitle: PropTypes.bool,
|
||||
showRelated: PropTypes.bool,
|
||||
showUserAvatar: PropTypes.bool,
|
||||
};
|
||||
@@ -63,6 +63,7 @@ export const EmbedPage: React.FC = () => {
|
||||
const urlParams = new URLSearchParams(window.location.search);
|
||||
const showTitle = urlParams.get('showTitle') !== '0';
|
||||
const showRelated = urlParams.get('showRelated') !== '0';
|
||||
const showUserAvatar = urlParams.get('showUserAvatar') !== '0';
|
||||
return (
|
||||
<VideoViewer
|
||||
data={MediaPageStore.get('media-data')}
|
||||
@@ -70,6 +71,7 @@ export const EmbedPage: React.FC = () => {
|
||||
containerStyles={containerStyles}
|
||||
showTitle={showTitle}
|
||||
showRelated={showRelated}
|
||||
showUserAvatar={showUserAvatar}
|
||||
/>
|
||||
);
|
||||
}}
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user