mirror of
https://github.com/mediacms-io/mediacms.git
synced 2026-02-07 07:53:00 -05:00
merge main
This commit is contained in:
@@ -31,8 +31,11 @@ const VideoJSEmbed = ({
|
||||
poster,
|
||||
previewSprite,
|
||||
subtitlesInfo,
|
||||
enableAutoplay,
|
||||
inEmbed,
|
||||
showTitle,
|
||||
showRelated,
|
||||
showUserAvatar,
|
||||
linkTitle,
|
||||
hasTheaterMode,
|
||||
hasNextLink,
|
||||
nextLink,
|
||||
@@ -62,8 +65,10 @@ const VideoJSEmbed = ({
|
||||
if (typeof window !== 'undefined') {
|
||||
// Get URL parameters for autoplay, muted, and timestamp
|
||||
const urlTimestamp = getUrlParameter('t');
|
||||
const urlAutoplay = getUrlParameter('autoplay');
|
||||
const urlMuted = getUrlParameter('muted');
|
||||
const urlShowRelated = getUrlParameter('showRelated');
|
||||
const urlShowUserAvatar = getUrlParameter('showUserAvatar');
|
||||
const urlLinkTitle = getUrlParameter('linkTitle');
|
||||
|
||||
window.MEDIA_DATA = {
|
||||
data: data || {},
|
||||
@@ -71,7 +76,7 @@ const VideoJSEmbed = ({
|
||||
version: version,
|
||||
isPlayList: isPlayList,
|
||||
playerVolume: playerVolume || 0.5,
|
||||
playerSoundMuted: playerSoundMuted || (urlMuted === '1'),
|
||||
playerSoundMuted: urlMuted === '1',
|
||||
videoQuality: videoQuality || 'auto',
|
||||
videoPlaybackSpeed: videoPlaybackSpeed || 1,
|
||||
inTheaterMode: inTheaterMode || false,
|
||||
@@ -83,8 +88,11 @@ const VideoJSEmbed = ({
|
||||
poster: poster || '',
|
||||
previewSprite: previewSprite || null,
|
||||
subtitlesInfo: subtitlesInfo || [],
|
||||
enableAutoplay: enableAutoplay || (urlAutoplay === '1'),
|
||||
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),
|
||||
linkTitle: linkTitle !== undefined ? linkTitle : (urlLinkTitle === '1' || urlLinkTitle === 'true' || urlLinkTitle === null),
|
||||
hasTheaterMode: hasTheaterMode || false,
|
||||
hasNextLink: hasNextLink || false,
|
||||
nextLink: nextLink || null,
|
||||
@@ -92,8 +100,10 @@ const VideoJSEmbed = ({
|
||||
errorMessage: errorMessage || '',
|
||||
// URL parameters
|
||||
urlTimestamp: urlTimestamp ? parseInt(urlTimestamp, 10) : null,
|
||||
urlAutoplay: urlAutoplay === '1',
|
||||
urlMuted: urlMuted === '1',
|
||||
urlShowRelated: urlShowRelated === '1' || urlShowRelated === 'true',
|
||||
urlShowUserAvatar: urlShowUserAvatar === '1' || urlShowUserAvatar === 'true',
|
||||
urlLinkTitle: urlLinkTitle === '1' || urlLinkTitle === 'true',
|
||||
onClickNextCallback: onClickNextCallback || null,
|
||||
onClickPreviousCallback: onClickPreviousCallback || null,
|
||||
onStateUpdateCallback: onStateUpdateCallback || null,
|
||||
@@ -176,11 +186,17 @@ const VideoJSEmbed = ({
|
||||
// Scroll to the video player with smooth behavior
|
||||
const videoElement = document.querySelector(inEmbedRef.current ? '#video-embed' : '#video-main');
|
||||
if (videoElement) {
|
||||
videoElement.scrollIntoView({
|
||||
behavior: 'smooth',
|
||||
block: 'center',
|
||||
inline: 'nearest'
|
||||
});
|
||||
const urlScroll = getUrlParameter('scroll');
|
||||
const isIframe = window.parent !== window;
|
||||
|
||||
// Only scroll if not in an iframe, OR if explicitly requested via scroll=1 parameter
|
||||
if (!isIframe || urlScroll === '1' || urlScroll === 'true') {
|
||||
videoElement.scrollIntoView({
|
||||
behavior: 'smooth',
|
||||
block: 'center',
|
||||
inline: 'nearest'
|
||||
});
|
||||
}
|
||||
}
|
||||
} else {
|
||||
console.warn('VideoJS player not found for timestamp navigation');
|
||||
@@ -220,7 +236,14 @@ const VideoJSEmbed = ({
|
||||
|
||||
return (
|
||||
<div className="video-js-wrapper" ref={containerRef}>
|
||||
{inEmbed ? <div id="video-js-root-embed" className="video-js-root-embed" /> : <div id="video-js-root-main" className="video-js-root-main" />}
|
||||
{inEmbed ? (
|
||||
<div
|
||||
id="video-js-root-embed"
|
||||
className="video-js-root-embed"
|
||||
/>
|
||||
) : (
|
||||
<div id="video-js-root-main" className="video-js-root-main" />
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -4,10 +4,32 @@ import { LinksContext, SiteConsumer } from '../../utils/contexts/';
|
||||
import { PageStore, MediaPageStore } from '../../utils/stores/';
|
||||
import { PageActions, MediaPageActions } from '../../utils/actions/';
|
||||
import { CircleIconButton, MaterialIcon, NumericInputWithUnit } from '../_shared/';
|
||||
import VideoViewer from '../media-viewer/VideoViewer';
|
||||
|
||||
const EMBED_OPTIONS_STORAGE_KEY = 'mediacms_embed_options';
|
||||
|
||||
function loadEmbedOptions() {
|
||||
try {
|
||||
const saved = localStorage.getItem(EMBED_OPTIONS_STORAGE_KEY);
|
||||
if (saved) {
|
||||
return JSON.parse(saved);
|
||||
}
|
||||
} catch (e) {
|
||||
// Ignore localStorage errors
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function saveEmbedOptions(options) {
|
||||
try {
|
||||
localStorage.setItem(EMBED_OPTIONS_STORAGE_KEY, JSON.stringify(options));
|
||||
} catch (e) {
|
||||
// Ignore localStorage errors
|
||||
}
|
||||
}
|
||||
|
||||
export function MediaShareEmbed(props) {
|
||||
const embedVideoDimensions = PageStore.get('config-options').embedded.video.dimensions;
|
||||
const savedOptions = loadEmbedOptions();
|
||||
|
||||
const links = useContext(LinksContext);
|
||||
|
||||
@@ -18,12 +40,19 @@ export function MediaShareEmbed(props) {
|
||||
const onRightBottomRef = useRef(null);
|
||||
|
||||
const [maxHeight, setMaxHeight] = useState(window.innerHeight - 144 + 56);
|
||||
const [keepAspectRatio, setKeepAspectRatio] = useState(false);
|
||||
const [aspectRatio, setAspectRatio] = useState('16:9');
|
||||
const [embedWidthValue, setEmbedWidthValue] = useState(embedVideoDimensions.width);
|
||||
const [embedWidthUnit, setEmbedWidthUnit] = useState(embedVideoDimensions.widthUnit);
|
||||
const [embedHeightValue, setEmbedHeightValue] = useState(embedVideoDimensions.height);
|
||||
const [embedHeightUnit, setEmbedHeightUnit] = useState(embedVideoDimensions.heightUnit);
|
||||
const [keepAspectRatio, setKeepAspectRatio] = useState(savedOptions?.keepAspectRatio ?? true);
|
||||
const [showTitle, setShowTitle] = useState(savedOptions?.showTitle ?? true);
|
||||
const [showRelated, setShowRelated] = useState(savedOptions?.showRelated ?? true);
|
||||
const [showUserAvatar, setShowUserAvatar] = useState(savedOptions?.showUserAvatar ?? true);
|
||||
const [linkTitle, setLinkTitle] = useState(savedOptions?.linkTitle ?? true);
|
||||
const [responsive, setResponsive] = useState(savedOptions?.responsive ?? false);
|
||||
const [startAt, setStartAt] = useState(false);
|
||||
const [startTime, setStartTime] = useState('0:00');
|
||||
const [aspectRatio, setAspectRatio] = useState(savedOptions?.aspectRatio ?? '16:9');
|
||||
const [embedWidthValue, setEmbedWidthValue] = useState(savedOptions?.embedWidthValue ?? embedVideoDimensions.width);
|
||||
const [embedWidthUnit, setEmbedWidthUnit] = useState(savedOptions?.embedWidthUnit ?? embedVideoDimensions.widthUnit);
|
||||
const [embedHeightValue, setEmbedHeightValue] = useState(savedOptions?.embedHeightValue ?? embedVideoDimensions.height);
|
||||
const [embedHeightUnit, setEmbedHeightUnit] = useState(savedOptions?.embedHeightUnit ?? embedVideoDimensions.heightUnit);
|
||||
const [rightMiddlePositionTop, setRightMiddlePositionTop] = useState(60);
|
||||
const [rightMiddlePositionBottom, setRightMiddlePositionBottom] = useState(60);
|
||||
const [unitOptions, setUnitOptions] = useState([
|
||||
@@ -71,36 +100,65 @@ export function MediaShareEmbed(props) {
|
||||
setEmbedHeightUnit(newVal);
|
||||
}
|
||||
|
||||
function onKeepAspectRatioChange() {
|
||||
const newVal = !keepAspectRatio;
|
||||
function onShowTitleChange() {
|
||||
setShowTitle(!showTitle);
|
||||
}
|
||||
|
||||
const arr = aspectRatio.split(':');
|
||||
const x = arr[0];
|
||||
const y = arr[1];
|
||||
function onShowRelatedChange() {
|
||||
setShowRelated(!showRelated);
|
||||
}
|
||||
|
||||
setKeepAspectRatio(newVal);
|
||||
setEmbedWidthUnit(newVal ? 'px' : embedWidthUnit);
|
||||
setEmbedHeightUnit(newVal ? 'px' : embedHeightUnit);
|
||||
setEmbedHeightValue(newVal ? parseInt((embedWidthValue * y) / x, 10) : embedHeightValue);
|
||||
setUnitOptions(
|
||||
newVal
|
||||
? [{ key: 'px', label: 'px' }]
|
||||
: [
|
||||
{ key: 'px', label: 'px' },
|
||||
{ key: 'percent', label: '%' },
|
||||
]
|
||||
);
|
||||
function onShowUserAvatarChange() {
|
||||
setShowUserAvatar(!showUserAvatar);
|
||||
}
|
||||
|
||||
function onLinkTitleChange() {
|
||||
setLinkTitle(!linkTitle);
|
||||
}
|
||||
|
||||
function onResponsiveChange() {
|
||||
const nextResponsive = !responsive;
|
||||
setResponsive(nextResponsive);
|
||||
|
||||
if (!nextResponsive) {
|
||||
if (aspectRatio !== 'custom') {
|
||||
const arr = aspectRatio.split(':');
|
||||
const x = arr[0];
|
||||
const y = arr[1];
|
||||
|
||||
setKeepAspectRatio(true);
|
||||
setEmbedHeightValue(parseInt((embedWidthValue * y) / x, 10));
|
||||
} else {
|
||||
setKeepAspectRatio(false);
|
||||
}
|
||||
} else {
|
||||
setKeepAspectRatio(false);
|
||||
}
|
||||
}
|
||||
|
||||
function onStartAtChange() {
|
||||
setStartAt(!startAt);
|
||||
}
|
||||
|
||||
function onStartTimeChange(e) {
|
||||
setStartTime(e.target.value);
|
||||
}
|
||||
|
||||
function onAspectRatioChange() {
|
||||
const newVal = aspectRatioValueRef.current.value;
|
||||
|
||||
const arr = newVal.split(':');
|
||||
const x = arr[0];
|
||||
const y = arr[1];
|
||||
if (newVal === 'custom') {
|
||||
setAspectRatio(newVal);
|
||||
setKeepAspectRatio(false);
|
||||
} else {
|
||||
const arr = newVal.split(':');
|
||||
const x = arr[0];
|
||||
const y = arr[1];
|
||||
|
||||
setAspectRatio(newVal);
|
||||
setEmbedHeightValue(keepAspectRatio ? parseInt((embedWidthValue * y) / x, 10) : embedHeightValue);
|
||||
setAspectRatio(newVal);
|
||||
setKeepAspectRatio(true);
|
||||
setEmbedHeightValue(parseInt((embedWidthValue * y) / x, 10));
|
||||
}
|
||||
}
|
||||
|
||||
function onWindowResize() {
|
||||
@@ -130,13 +188,88 @@ export function MediaShareEmbed(props) {
|
||||
};
|
||||
}, []);
|
||||
|
||||
// Save embed options to localStorage when they change (except startAt/startTime)
|
||||
useEffect(() => {
|
||||
saveEmbedOptions({
|
||||
showTitle,
|
||||
showRelated,
|
||||
showUserAvatar,
|
||||
linkTitle,
|
||||
responsive,
|
||||
aspectRatio,
|
||||
embedWidthValue,
|
||||
embedWidthUnit,
|
||||
embedHeightValue,
|
||||
embedHeightUnit,
|
||||
keepAspectRatio,
|
||||
});
|
||||
}, [showTitle, showRelated, showUserAvatar, linkTitle, responsive, aspectRatio, embedWidthValue, embedWidthUnit, embedHeightValue, embedHeightUnit, keepAspectRatio]);
|
||||
|
||||
function getEmbedCode() {
|
||||
const mediaId = MediaPageStore.get('media-id');
|
||||
const params = new URLSearchParams();
|
||||
if (showTitle) params.set('showTitle', '1');
|
||||
else params.set('showTitle', '0');
|
||||
|
||||
if (showRelated) params.set('showRelated', '1');
|
||||
else params.set('showRelated', '0');
|
||||
|
||||
if (showUserAvatar) params.set('showUserAvatar', '1');
|
||||
else params.set('showUserAvatar', '0');
|
||||
|
||||
if (linkTitle) params.set('linkTitle', '1');
|
||||
else params.set('linkTitle', '0');
|
||||
|
||||
if (startAt && startTime) {
|
||||
const parts = startTime.split(':').reverse();
|
||||
let seconds = 0;
|
||||
if (parts[0]) seconds += parseInt(parts[0], 10) || 0;
|
||||
if (parts[1]) seconds += (parseInt(parts[1], 10) || 0) * 60;
|
||||
if (parts[2]) seconds += (parseInt(parts[2], 10) || 0) * 3600;
|
||||
if (seconds > 0) params.set('t', seconds);
|
||||
}
|
||||
|
||||
const separator = links.embed.includes('?') ? '&' : '?';
|
||||
const finalUrl = `${links.embed}${mediaId}${separator}${params.toString()}`;
|
||||
|
||||
if (responsive) {
|
||||
if (aspectRatio === 'custom') {
|
||||
// Use current width/height values to calculate aspect ratio for custom
|
||||
const ratio = `${embedWidthValue} / ${embedHeightValue}`;
|
||||
const maxWidth = `calc(100vh * ${embedWidthValue} / ${embedHeightValue})`;
|
||||
return `<iframe src="${finalUrl}" style="width:100%;max-width:${maxWidth};aspect-ratio:${ratio};display:block;margin:auto;border:0;" allowFullScreen></iframe>`;
|
||||
}
|
||||
const arr = aspectRatio.split(':');
|
||||
const ratio = `${arr[0]} / ${arr[1]}`;
|
||||
const maxWidth = `calc(100vh * ${arr[0]} / ${arr[1]})`;
|
||||
return `<iframe src="${finalUrl}" style="width:100%;max-width:${maxWidth};aspect-ratio:${ratio};display:block;margin:auto;border:0;" allowFullScreen></iframe>`;
|
||||
}
|
||||
|
||||
const width = 'percent' === embedWidthUnit ? embedWidthValue + '%' : embedWidthValue;
|
||||
const height = 'percent' === embedHeightUnit ? embedHeightValue + '%' : embedHeightValue;
|
||||
return `<iframe width="${width}" height="${height}" src="${finalUrl}" frameBorder="0" allowFullScreen></iframe>`;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="share-embed" style={{ maxHeight: maxHeight + 'px' }}>
|
||||
<div className="share-embed-inner">
|
||||
<div className="on-left">
|
||||
<div className="media-embed-wrap">
|
||||
<SiteConsumer>
|
||||
{(site) => <VideoViewer data={MediaPageStore.get('media-data')} siteUrl={site.url} inEmbed={true} />}
|
||||
{(site) => {
|
||||
const previewUrl = `${links.embed + MediaPageStore.get('media-id')}&showTitle=${showTitle ? '1' : '0'}&showRelated=${showRelated ? '1' : '0'}&showUserAvatar=${showUserAvatar ? '1' : '0'}&linkTitle=${linkTitle ? '1' : '0'}${startAt ? '&t=' + (startTime.split(':').reverse().reduce((acc, cur, i) => acc + (parseInt(cur, 10) || 0) * Math.pow(60, i), 0)) : ''}`;
|
||||
|
||||
const style = {};
|
||||
style.width = '100%';
|
||||
style.height = '480px';
|
||||
style.overflow = 'hidden';
|
||||
|
||||
return (
|
||||
<div style={style}>
|
||||
<iframe width="100%" height="100%" src={previewUrl} frameBorder="0" allowFullScreen></iframe>
|
||||
</div>
|
||||
);
|
||||
}}
|
||||
</SiteConsumer>
|
||||
</div>
|
||||
</div>
|
||||
@@ -158,16 +291,7 @@ export function MediaShareEmbed(props) {
|
||||
>
|
||||
<textarea
|
||||
readOnly
|
||||
value={
|
||||
'<iframe width="' +
|
||||
('percent' === embedWidthUnit ? embedWidthValue + '%' : embedWidthValue) +
|
||||
'" height="' +
|
||||
('percent' === embedHeightUnit ? embedHeightValue + '%' : embedHeightValue) +
|
||||
'" src="' +
|
||||
links.embed +
|
||||
MediaPageStore.get('media-id') +
|
||||
'" frameborder="0" allowfullscreen></iframe>'
|
||||
}
|
||||
value={getEmbedCode()}
|
||||
></textarea>
|
||||
|
||||
<div className="iframe-config">
|
||||
@@ -179,59 +303,106 @@ export function MediaShareEmbed(props) {
|
||||
</div>*/}
|
||||
|
||||
<div className="option-content">
|
||||
<div className="ratio-options">
|
||||
<div className="ratio-options" style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: '0 10px' }}>
|
||||
<div className="options-group">
|
||||
<label style={{ minHeight: '36px' }}>
|
||||
<input type="checkbox" checked={keepAspectRatio} onChange={onKeepAspectRatioChange} />
|
||||
Keep aspect ratio
|
||||
<label style={{ minHeight: '36px', whiteSpace: 'nowrap' }}>
|
||||
<input type="checkbox" checked={showTitle} onChange={onShowTitleChange} />
|
||||
Show title
|
||||
</label>
|
||||
</div>
|
||||
|
||||
{!keepAspectRatio ? null : (
|
||||
<div className="options-group">
|
||||
<select ref={aspectRatioValueRef} onChange={onAspectRatioChange} value={aspectRatio}>
|
||||
<optgroup label="Horizontal orientation">
|
||||
<option value="16:9">16:9</option>
|
||||
<option value="4:3">4:3</option>
|
||||
<option value="3:2">3:2</option>
|
||||
</optgroup>
|
||||
<optgroup label="Vertical orientation">
|
||||
<option value="9:16">9:16</option>
|
||||
<option value="3:4">3:4</option>
|
||||
<option value="2:3">2:3</option>
|
||||
</optgroup>
|
||||
<div className="options-group">
|
||||
<label style={{ minHeight: '36px', whiteSpace: 'nowrap', opacity: showTitle ? 1 : 0.5 }}>
|
||||
<input type="checkbox" checked={linkTitle} onChange={onLinkTitleChange} disabled={!showTitle} />
|
||||
Link title
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div className="options-group">
|
||||
<label style={{ minHeight: '36px', whiteSpace: 'nowrap' }}>
|
||||
<input type="checkbox" checked={showRelated} onChange={onShowRelatedChange} />
|
||||
Show related
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div className="options-group">
|
||||
<label style={{ minHeight: '36px', whiteSpace: 'nowrap', opacity: showTitle ? 1 : 0.5 }}>
|
||||
<input type="checkbox" checked={showUserAvatar} onChange={onShowUserAvatarChange} disabled={!showTitle} />
|
||||
Show user avatar
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div className="options-group" style={{ display: 'flex', alignItems: 'center' }}>
|
||||
<label style={{ minHeight: '36px', whiteSpace: 'nowrap', display: 'flex', alignItems: 'center', marginRight: '10px' }}>
|
||||
<input type="checkbox" checked={responsive} onChange={onResponsiveChange} />
|
||||
Responsive
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div className="options-group" style={{ display: 'flex', alignItems: 'center' }}>
|
||||
<label style={{ minHeight: '36px', whiteSpace: 'nowrap', display: 'flex', alignItems: 'center', marginRight: '10px' }}>
|
||||
<input type="checkbox" checked={startAt} onChange={onStartAtChange} />
|
||||
Start at
|
||||
</label>
|
||||
{startAt && (
|
||||
<input
|
||||
type="text"
|
||||
value={startTime}
|
||||
onChange={onStartTimeChange}
|
||||
style={{ width: '60px', height: '28px', fontSize: '12px', padding: '2px 5px' }}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className="options-group" style={{ display: 'flex', flexDirection: 'column', justifyContent: 'center' }}>
|
||||
<div style={{ fontSize: '12px', marginBottom: '4px', color: 'rgba(0,0,0,0.6)' }}>Aspect Ratio</div>
|
||||
<div style={{ display: 'flex', alignItems: 'center' }}>
|
||||
<select
|
||||
ref={aspectRatioValueRef}
|
||||
onChange={onAspectRatioChange}
|
||||
value={aspectRatio}
|
||||
style={{ height: '28px', fontSize: '12px' }}
|
||||
>
|
||||
<option value="16:9">16:9</option>
|
||||
<option value="4:3">4:3</option>
|
||||
<option value="3:2">3:2</option>
|
||||
<option value="custom">Custom</option>
|
||||
</select>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<br />
|
||||
|
||||
<div className="options-group">
|
||||
<NumericInputWithUnit
|
||||
valueCallback={onEmbedWidthValueChange}
|
||||
unitCallback={onEmbedWidthUnitChange}
|
||||
label={'Width'}
|
||||
defaultValue={parseInt(embedWidthValue, 10)}
|
||||
defaultUnit={embedWidthUnit}
|
||||
minValue={1}
|
||||
maxValue={99999}
|
||||
units={unitOptions}
|
||||
/>
|
||||
</div>
|
||||
{!responsive && (
|
||||
<>
|
||||
<div className="options-group">
|
||||
<NumericInputWithUnit
|
||||
valueCallback={onEmbedWidthValueChange}
|
||||
unitCallback={onEmbedWidthUnitChange}
|
||||
label={'Width'}
|
||||
defaultValue={parseInt(embedWidthValue, 10)}
|
||||
defaultUnit={embedWidthUnit}
|
||||
minValue={1}
|
||||
maxValue={99999}
|
||||
units={unitOptions}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="options-group">
|
||||
<NumericInputWithUnit
|
||||
valueCallback={onEmbedHeightValueChange}
|
||||
unitCallback={onEmbedHeightUnitChange}
|
||||
label={'Height'}
|
||||
defaultValue={parseInt(embedHeightValue, 10)}
|
||||
defaultUnit={embedHeightUnit}
|
||||
minValue={1}
|
||||
maxValue={99999}
|
||||
units={unitOptions}
|
||||
/>
|
||||
</div>
|
||||
<div className="options-group">
|
||||
<NumericInputWithUnit
|
||||
valueCallback={onEmbedHeightValueChange}
|
||||
unitCallback={onEmbedHeightUnitChange}
|
||||
label={'Height'}
|
||||
defaultValue={parseInt(embedHeightValue, 10)}
|
||||
defaultUnit={embedHeightUnit}
|
||||
minValue={1}
|
||||
maxValue={99999}
|
||||
units={unitOptions}
|
||||
/>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1930,9 +1930,21 @@
|
||||
}
|
||||
}
|
||||
|
||||
.media-embed-wrap {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: #000;
|
||||
.media-embed-wrap {
|
||||
display: block;
|
||||
|
||||
.player-container,
|
||||
.player-container-inner {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
padding-top: 0;
|
||||
background: #000;
|
||||
}
|
||||
.player-container,
|
||||
.player-container-inner {
|
||||
width: 100%;
|
||||
@@ -1946,6 +1958,10 @@
|
||||
.circle-icon-button {
|
||||
}
|
||||
|
||||
.video-js.vjs-mediacms {
|
||||
padding-top: 0;
|
||||
}
|
||||
}
|
||||
.video-js.vjs-mediacms {
|
||||
padding-top: math.div(9, 16) * 100%;
|
||||
}
|
||||
|
||||
@@ -410,8 +410,12 @@ export default class VideoViewer extends React.PureComponent {
|
||||
poster: this.videoPoster,
|
||||
previewSprite: previewSprite,
|
||||
subtitlesInfo: this.props.data.subtitles_info,
|
||||
enableAutoplay: !this.props.inEmbed,
|
||||
inEmbed: this.props.inEmbed,
|
||||
showTitle: this.props.showTitle,
|
||||
showRelated: this.props.showRelated,
|
||||
showUserAvatar: this.props.showUserAvatar,
|
||||
linkTitle: this.props.linkTitle,
|
||||
urlTimestamp: this.props.timestamp,
|
||||
hasTheaterMode: !this.props.inEmbed,
|
||||
hasNextLink: !!nextLink,
|
||||
nextLink: nextLink,
|
||||
@@ -435,9 +439,19 @@ export default class VideoViewer extends React.PureComponent {
|
||||
|
||||
VideoViewer.defaultProps = {
|
||||
inEmbed: !0,
|
||||
showTitle: !0,
|
||||
showRelated: !0,
|
||||
showUserAvatar: !0,
|
||||
linkTitle: !0,
|
||||
timestamp: null,
|
||||
siteUrl: PropTypes.string.isRequired,
|
||||
};
|
||||
|
||||
VideoViewer.propTypes = {
|
||||
inEmbed: PropTypes.bool,
|
||||
showTitle: PropTypes.bool,
|
||||
showRelated: PropTypes.bool,
|
||||
showUserAvatar: PropTypes.bool,
|
||||
linkTitle: PropTypes.bool,
|
||||
timestamp: PropTypes.number,
|
||||
};
|
||||
@@ -41,7 +41,7 @@ export const EmbedPage: React.FC = () => {
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div className="embed-wrap" style={wrapperStyles}>
|
||||
<div className="embed-wrap media-embed-wrap" style={wrapperStyles}>
|
||||
{failedMediaLoad && (
|
||||
<div className="player-container player-container-error" style={containerStyles}>
|
||||
<div className="player-container-inner" style={containerStyles}>
|
||||
@@ -59,9 +59,32 @@ export const EmbedPage: React.FC = () => {
|
||||
|
||||
{loadedVideo && (
|
||||
<SiteConsumer>
|
||||
{(site) => (
|
||||
<VideoViewer data={MediaPageStore.get('media-data')} siteUrl={site.url} containerStyles={containerStyles} />
|
||||
)}
|
||||
{(site) => {
|
||||
const urlParams = new URLSearchParams(window.location.search);
|
||||
const urlShowTitle = urlParams.get('showTitle');
|
||||
const showTitle = urlShowTitle !== '0';
|
||||
const urlShowRelated = urlParams.get('showRelated');
|
||||
const showRelated = urlShowRelated !== '0';
|
||||
const urlShowUserAvatar = urlParams.get('showUserAvatar');
|
||||
const showUserAvatar = urlShowUserAvatar !== '0';
|
||||
const urlLinkTitle = urlParams.get('linkTitle');
|
||||
const linkTitle = urlLinkTitle !== '0';
|
||||
const urlTimestamp = urlParams.get('t');
|
||||
const timestamp = urlTimestamp ? parseInt(urlTimestamp, 10) : null;
|
||||
|
||||
return (
|
||||
<VideoViewer
|
||||
data={MediaPageStore.get('media-data')}
|
||||
siteUrl={site.url}
|
||||
containerStyles={containerStyles}
|
||||
showTitle={showTitle}
|
||||
showRelated={showRelated}
|
||||
showUserAvatar={showUserAvatar}
|
||||
linkTitle={linkTitle}
|
||||
timestamp={timestamp}
|
||||
/>
|
||||
);
|
||||
}}
|
||||
</SiteConsumer>
|
||||
)}
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user