mirror of
https://github.com/owncast/owncast.git
synced 2024-11-29 11:39:08 +03:00
Give chat a min-height that other elements yield to on mobile clients (#2676)
* Add className prop to some components * Give mobile chatbox height priority over other elements * Optimize for mobile landscape mode * Make thumbnail background black * Fix overflow issues on narrow screens * Adjust layout for offline mode on mobile * Fix main content width on Desktop * Fix offline layout for desktop
This commit is contained in:
parent
c9773091a2
commit
25119561fb
11 changed files with 176 additions and 118 deletions
|
@ -3,19 +3,46 @@
|
||||||
.root {
|
.root {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: 1fr auto;
|
grid-template-columns: 1fr auto;
|
||||||
|
grid-template-rows: 100%;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
background-color: var(--theme-color-background-main);
|
background-color: var(--theme-color-background-main);
|
||||||
|
height: 100%;
|
||||||
|
min-height: 0;
|
||||||
|
|
||||||
@include screen(desktop) {
|
@include screen(desktop) {
|
||||||
height: var(--content-height);
|
height: var(--content-height);
|
||||||
}
|
}
|
||||||
|
|
||||||
.mainSection {
|
.mainSection {
|
||||||
display: flex;
|
display: grid;
|
||||||
flex-direction: column;
|
grid-template-rows: min-content // Skeleton when app is loading
|
||||||
|
minmax(30px, min-content) // player
|
||||||
|
min-content // status bar when live
|
||||||
|
min-content // mid section
|
||||||
|
minmax(250px, 1fr) // mobile content
|
||||||
|
;
|
||||||
|
grid-template-columns: 100%;
|
||||||
|
|
||||||
|
&.offline {
|
||||||
|
grid-template-rows: min-content // Skeleton when app is loading
|
||||||
|
min-content // offline banner
|
||||||
|
min-content // status bar when live
|
||||||
|
min-content // mid section
|
||||||
|
minmax(250px, 1fr) // mobile content
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
@include screen(tablet) {
|
||||||
|
grid-template-columns: 100vw;
|
||||||
|
}
|
||||||
|
|
||||||
@include screen(desktop) {
|
@include screen(desktop) {
|
||||||
overflow-y: scroll;
|
overflow-y: scroll;
|
||||||
|
grid-template-rows: unset;
|
||||||
|
|
||||||
|
&.offline {
|
||||||
|
grid-template-rows: unset;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,10 +54,6 @@
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.topSection {
|
|
||||||
padding: 0;
|
|
||||||
background-color: var(--theme-color-components-video-background);
|
|
||||||
}
|
|
||||||
.lowerSection {
|
.lowerSection {
|
||||||
padding: 0em 2%;
|
padding: 0em 2%;
|
||||||
margin-bottom: 2em;
|
margin-bottom: 2em;
|
||||||
|
@ -44,6 +67,14 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.topSectionElement {
|
||||||
|
background-color: var(--theme-color-components-video-background);
|
||||||
|
}
|
||||||
|
|
||||||
|
.statusBar {
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
.leftCol {
|
.leftCol {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
@ -53,13 +84,6 @@
|
||||||
display: grid;
|
display: grid;
|
||||||
}
|
}
|
||||||
|
|
||||||
.main {
|
|
||||||
display: grid;
|
|
||||||
flex: 1;
|
|
||||||
height: 100%;
|
|
||||||
grid-template-rows: 1fr auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.replacementBar {
|
.replacementBar {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
|
|
|
@ -2,6 +2,7 @@ import { useRecoilState, useRecoilValue } from 'recoil';
|
||||||
import { Skeleton } from 'antd';
|
import { Skeleton } from 'antd';
|
||||||
import { FC, useEffect, useState } from 'react';
|
import { FC, useEffect, useState } from 'react';
|
||||||
import dynamic from 'next/dynamic';
|
import dynamic from 'next/dynamic';
|
||||||
|
import classnames from 'classnames';
|
||||||
import { LOCAL_STORAGE_KEYS, getLocalStorage, setLocalStorage } from '../../../utils/localStorage';
|
import { LOCAL_STORAGE_KEYS, getLocalStorage, setLocalStorage } from '../../../utils/localStorage';
|
||||||
import isPushNotificationSupported from '../../../utils/browserPushNotifications';
|
import isPushNotificationSupported from '../../../utils/browserPushNotifications';
|
||||||
|
|
||||||
|
@ -331,105 +332,110 @@ export const Content: FC = () => {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className={styles.main}>
|
<div className={styles.root}>
|
||||||
<div className={styles.root}>
|
<div className={classnames(styles.mainSection, { [styles.offline]: !online })}>
|
||||||
<div className={styles.mainSection}>
|
{appState.appLoading ? (
|
||||||
<div className={styles.topSection}>
|
<Skeleton loading active paragraph={{ rows: 7 }} className={styles.topSectionElement} />
|
||||||
{appState.appLoading && <Skeleton loading active paragraph={{ rows: 7 }} />}
|
) : (
|
||||||
{online && (
|
<div className="skeleton-placeholder" />
|
||||||
<OwncastPlayer
|
)}
|
||||||
source="/hls/stream.m3u8"
|
{online && (
|
||||||
online={online}
|
<OwncastPlayer
|
||||||
title={streamTitle || name}
|
source="/hls/stream.m3u8"
|
||||||
/>
|
online={online}
|
||||||
)}
|
title={streamTitle || name}
|
||||||
{!online && !appState.appLoading && (
|
className={styles.topSectionElement}
|
||||||
<div id="offline-message">
|
/>
|
||||||
<OfflineBanner
|
)}
|
||||||
showsHeader={false}
|
{!online && !appState.appLoading && (
|
||||||
streamName={name}
|
<div id="offline-message">
|
||||||
customText={offlineMessage}
|
<OfflineBanner
|
||||||
notificationsEnabled={browserNotificationsEnabled}
|
showsHeader={false}
|
||||||
fediverseAccount={fediverseAccount}
|
streamName={name}
|
||||||
lastLive={lastDisconnectTime}
|
customText={offlineMessage}
|
||||||
onNotifyClick={() => setShowNotifyModal(true)}
|
notificationsEnabled={browserNotificationsEnabled}
|
||||||
onFollowClick={() => setShowFollowModal(true)}
|
fediverseAccount={fediverseAccount}
|
||||||
/>
|
lastLive={lastDisconnectTime}
|
||||||
</div>
|
onNotifyClick={() => setShowNotifyModal(true)}
|
||||||
)}
|
onFollowClick={() => setShowFollowModal(true)}
|
||||||
{isStreamLive && (
|
className={styles.topSectionElement}
|
||||||
<Statusbar
|
/>
|
||||||
online={online}
|
|
||||||
lastConnectTime={lastConnectTime}
|
|
||||||
lastDisconnectTime={lastDisconnectTime}
|
|
||||||
viewerCount={viewerCount}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
<div className={styles.midSection}>
|
)}
|
||||||
<div className={styles.buttonsLogoTitleSection}>
|
{isStreamLive ? (
|
||||||
{!isMobile && (
|
<Statusbar
|
||||||
<ActionButtonRow>
|
online={online}
|
||||||
{externalActionButtons}
|
lastConnectTime={lastConnectTime}
|
||||||
{supportFediverseFeatures && (
|
lastDisconnectTime={lastDisconnectTime}
|
||||||
<FollowButton size="small" onClick={() => setShowFollowModal(true)} />
|
viewerCount={viewerCount}
|
||||||
)}
|
className={classnames(styles.topSectionElement, styles.statusBar)}
|
||||||
{supportsBrowserNotifications && (
|
/>
|
||||||
<NotifyReminderPopup
|
) : (
|
||||||
open={showNotifyReminder}
|
<div className="statusbar-placeholder" />
|
||||||
notificationClicked={() => setShowNotifyModal(true)}
|
)}
|
||||||
notificationClosed={() => disableNotifyReminderPopup()}
|
<div className={styles.midSection}>
|
||||||
>
|
<div className={styles.buttonsLogoTitleSection}>
|
||||||
<NotifyButton onClick={() => setShowNotifyModal(true)} />
|
{!isMobile && (
|
||||||
</NotifyReminderPopup>
|
<ActionButtonRow>
|
||||||
)}
|
{externalActionButtons}
|
||||||
</ActionButtonRow>
|
{supportFediverseFeatures && (
|
||||||
)}
|
<FollowButton size="small" onClick={() => setShowFollowModal(true)} />
|
||||||
|
)}
|
||||||
|
{supportsBrowserNotifications && (
|
||||||
|
<NotifyReminderPopup
|
||||||
|
open={showNotifyReminder}
|
||||||
|
notificationClicked={() => setShowNotifyModal(true)}
|
||||||
|
notificationClosed={() => disableNotifyReminderPopup()}
|
||||||
|
>
|
||||||
|
<NotifyButton onClick={() => setShowNotifyModal(true)} />
|
||||||
|
</NotifyReminderPopup>
|
||||||
|
)}
|
||||||
|
</ActionButtonRow>
|
||||||
|
)}
|
||||||
|
|
||||||
<Modal
|
<Modal
|
||||||
title="Browser Notifications"
|
title="Browser Notifications"
|
||||||
open={showNotifyModal}
|
open={showNotifyModal}
|
||||||
afterClose={() => disableNotifyReminderPopup()}
|
afterClose={() => disableNotifyReminderPopup()}
|
||||||
handleCancel={() => disableNotifyReminderPopup()}
|
handleCancel={() => disableNotifyReminderPopup()}
|
||||||
>
|
>
|
||||||
<BrowserNotifyModal />
|
<BrowserNotifyModal />
|
||||||
</Modal>
|
</Modal>
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
{isMobile ? (
|
|
||||||
<MobileContent
|
|
||||||
name={name}
|
|
||||||
streamTitle={streamTitle}
|
|
||||||
summary={summary}
|
|
||||||
tags={tags}
|
|
||||||
socialHandles={socialHandles}
|
|
||||||
extraPageContent={extraPageContent}
|
|
||||||
messages={messages}
|
|
||||||
currentUser={currentUser}
|
|
||||||
showChat={showChat}
|
|
||||||
actions={externalActions}
|
|
||||||
setExternalActionToDisplay={externalActionSelected}
|
|
||||||
setShowNotifyPopup={setShowNotifyModal}
|
|
||||||
setShowFollowModal={setShowFollowModal}
|
|
||||||
supportFediverseFeatures={supportFediverseFeatures}
|
|
||||||
supportsBrowserNotifications={supportsBrowserNotifications}
|
|
||||||
/>
|
|
||||||
) : (
|
|
||||||
<DesktopContent
|
|
||||||
name={name}
|
|
||||||
streamTitle={streamTitle}
|
|
||||||
summary={summary}
|
|
||||||
tags={tags}
|
|
||||||
socialHandles={socialHandles}
|
|
||||||
extraPageContent={extraPageContent}
|
|
||||||
setShowFollowModal={setShowFollowModal}
|
|
||||||
supportFediverseFeatures={supportFediverseFeatures}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
{!isMobile && <Footer version={version} />}
|
|
||||||
</div>
|
</div>
|
||||||
{showChat && !isMobile && <Sidebar />}
|
{isMobile ? (
|
||||||
|
<MobileContent
|
||||||
|
name={name}
|
||||||
|
streamTitle={streamTitle}
|
||||||
|
summary={summary}
|
||||||
|
tags={tags}
|
||||||
|
socialHandles={socialHandles}
|
||||||
|
extraPageContent={extraPageContent}
|
||||||
|
messages={messages}
|
||||||
|
currentUser={currentUser}
|
||||||
|
showChat={showChat}
|
||||||
|
actions={externalActions}
|
||||||
|
setExternalActionToDisplay={externalActionSelected}
|
||||||
|
setShowNotifyPopup={setShowNotifyModal}
|
||||||
|
setShowFollowModal={setShowFollowModal}
|
||||||
|
supportFediverseFeatures={supportFediverseFeatures}
|
||||||
|
supportsBrowserNotifications={supportsBrowserNotifications}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<DesktopContent
|
||||||
|
name={name}
|
||||||
|
streamTitle={streamTitle}
|
||||||
|
summary={summary}
|
||||||
|
tags={tags}
|
||||||
|
socialHandles={socialHandles}
|
||||||
|
extraPageContent={extraPageContent}
|
||||||
|
setShowFollowModal={setShowFollowModal}
|
||||||
|
supportFediverseFeatures={supportFediverseFeatures}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
{!isMobile && <Footer version={version} />}
|
||||||
</div>
|
</div>
|
||||||
|
{showChat && !isMobile && <Sidebar />}
|
||||||
</div>
|
</div>
|
||||||
{externalActionToDisplay && (
|
{externalActionToDisplay && (
|
||||||
<ExternalModal
|
<ExternalModal
|
||||||
|
|
|
@ -8,6 +8,7 @@ export type CrossfadeImageProps = {
|
||||||
height: string;
|
height: string;
|
||||||
objectFit?: ObjectFit;
|
objectFit?: ObjectFit;
|
||||||
duration?: string;
|
duration?: string;
|
||||||
|
className?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
const imgStyle: React.CSSProperties = {
|
const imgStyle: React.CSSProperties = {
|
||||||
|
@ -22,6 +23,7 @@ export const CrossfadeImage: FC<CrossfadeImageProps> = ({
|
||||||
height,
|
height,
|
||||||
objectFit = 'fill',
|
objectFit = 'fill',
|
||||||
duration = '1s',
|
duration = '1s',
|
||||||
|
className,
|
||||||
}) => {
|
}) => {
|
||||||
const spanStyle: React.CSSProperties = useMemo(
|
const spanStyle: React.CSSProperties = useMemo(
|
||||||
() => ({
|
() => ({
|
||||||
|
@ -52,7 +54,7 @@ export const CrossfadeImage: FC<CrossfadeImageProps> = ({
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<span style={spanStyle}>
|
<span style={spanStyle} className={className}>
|
||||||
{[...srcs, nextSrc].map(
|
{[...srcs, nextSrc].map(
|
||||||
(singleSrc, index) =>
|
(singleSrc, index) =>
|
||||||
singleSrc !== '' && (
|
singleSrc !== '' && (
|
||||||
|
|
|
@ -38,7 +38,9 @@
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
width: 70vw;
|
// 6rem is an overapproximation of the width of
|
||||||
|
// the user menu
|
||||||
|
max-width: min(70vw, calc(100vw - 6rem));
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
line-height: 1.4;
|
line-height: 1.4;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@ import { Divider } from 'antd';
|
||||||
import { FC } from 'react';
|
import { FC } from 'react';
|
||||||
import formatDistanceToNow from 'date-fns/formatDistanceToNow';
|
import formatDistanceToNow from 'date-fns/formatDistanceToNow';
|
||||||
import dynamic from 'next/dynamic';
|
import dynamic from 'next/dynamic';
|
||||||
|
import classNames from 'classnames';
|
||||||
import styles from './OfflineBanner.module.scss';
|
import styles from './OfflineBanner.module.scss';
|
||||||
|
|
||||||
// Lazy loaded components
|
// Lazy loaded components
|
||||||
|
@ -20,6 +21,7 @@ export type OfflineBannerProps = {
|
||||||
showsHeader?: boolean;
|
showsHeader?: boolean;
|
||||||
onNotifyClick?: () => void;
|
onNotifyClick?: () => void;
|
||||||
onFollowClick?: () => void;
|
onFollowClick?: () => void;
|
||||||
|
className?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const OfflineBanner: FC<OfflineBannerProps> = ({
|
export const OfflineBanner: FC<OfflineBannerProps> = ({
|
||||||
|
@ -31,6 +33,7 @@ export const OfflineBanner: FC<OfflineBannerProps> = ({
|
||||||
showsHeader = true,
|
showsHeader = true,
|
||||||
onNotifyClick,
|
onNotifyClick,
|
||||||
onFollowClick,
|
onFollowClick,
|
||||||
|
className,
|
||||||
}) => {
|
}) => {
|
||||||
let text;
|
let text;
|
||||||
if (customText) {
|
if (customText) {
|
||||||
|
@ -74,7 +77,7 @@ export const OfflineBanner: FC<OfflineBannerProps> = ({
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div id="offline-banner" className={styles.outerContainer}>
|
<div id="offline-banner" className={classNames(styles.outerContainer, className)}>
|
||||||
<div className={styles.innerContainer}>
|
<div className={styles.innerContainer}>
|
||||||
{showsHeader && (
|
{showsHeader && (
|
||||||
<>
|
<>
|
||||||
|
|
|
@ -2,6 +2,7 @@ import formatDistanceToNow from 'date-fns/formatDistanceToNow';
|
||||||
import intervalToDuration from 'date-fns/intervalToDuration';
|
import intervalToDuration from 'date-fns/intervalToDuration';
|
||||||
import { FC, useEffect, useState } from 'react';
|
import { FC, useEffect, useState } from 'react';
|
||||||
import dynamic from 'next/dynamic';
|
import dynamic from 'next/dynamic';
|
||||||
|
import classNames from 'classnames';
|
||||||
import styles from './Statusbar.module.scss';
|
import styles from './Statusbar.module.scss';
|
||||||
import { pluralize } from '../../../utils/helpers';
|
import { pluralize } from '../../../utils/helpers';
|
||||||
|
|
||||||
|
@ -16,6 +17,7 @@ export type StatusbarProps = {
|
||||||
lastConnectTime?: Date;
|
lastConnectTime?: Date;
|
||||||
lastDisconnectTime?: Date;
|
lastDisconnectTime?: Date;
|
||||||
viewerCount: number;
|
viewerCount: number;
|
||||||
|
className?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
function makeDurationString(lastConnectTime: Date): string {
|
function makeDurationString(lastConnectTime: Date): string {
|
||||||
|
@ -43,6 +45,7 @@ export const Statusbar: FC<StatusbarProps> = ({
|
||||||
lastConnectTime,
|
lastConnectTime,
|
||||||
lastDisconnectTime,
|
lastDisconnectTime,
|
||||||
viewerCount,
|
viewerCount,
|
||||||
|
className,
|
||||||
}) => {
|
}) => {
|
||||||
const [, setNow] = useState(new Date());
|
const [, setNow] = useState(new Date());
|
||||||
|
|
||||||
|
@ -75,7 +78,7 @@ export const Statusbar: FC<StatusbarProps> = ({
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.statusbar} role="status">
|
<div className={classNames(styles.statusbar, className)} role="status">
|
||||||
<div>{onlineMessage}</div>
|
<div>{onlineMessage}</div>
|
||||||
<div>{rightSideMessage}</div>
|
<div>{rightSideMessage}</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
aspect-ratio: 16 / 9;
|
aspect-ratio: 16 / 9;
|
||||||
|
|
||||||
@media (max-width: 1200px) {
|
@media (max-width: 1200px) {
|
||||||
height: unset;
|
height: 100%;
|
||||||
max-height: 75vh;
|
max-height: 75vh;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@ import React, { FC, useEffect } from 'react';
|
||||||
import { useRecoilState, useRecoilValue } from 'recoil';
|
import { useRecoilState, useRecoilValue } from 'recoil';
|
||||||
import { useHotkeys } from 'react-hotkeys-hook';
|
import { useHotkeys } from 'react-hotkeys-hook';
|
||||||
import { VideoJsPlayerOptions } from 'video.js';
|
import { VideoJsPlayerOptions } from 'video.js';
|
||||||
|
import classNames from 'classnames';
|
||||||
import { VideoJS } from '../VideoJS/VideoJS';
|
import { VideoJS } from '../VideoJS/VideoJS';
|
||||||
import ViewerPing from '../viewer-ping';
|
import ViewerPing from '../viewer-ping';
|
||||||
import { VideoPoster } from '../VideoPoster/VideoPoster';
|
import { VideoPoster } from '../VideoPoster/VideoPoster';
|
||||||
|
@ -26,6 +27,7 @@ export type OwncastPlayerProps = {
|
||||||
online: boolean;
|
online: boolean;
|
||||||
initiallyMuted?: boolean;
|
initiallyMuted?: boolean;
|
||||||
title: string;
|
title: string;
|
||||||
|
className?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
async function getVideoSettings() {
|
async function getVideoSettings() {
|
||||||
|
@ -45,6 +47,7 @@ export const OwncastPlayer: FC<OwncastPlayerProps> = ({
|
||||||
online,
|
online,
|
||||||
initiallyMuted = false,
|
initiallyMuted = false,
|
||||||
title,
|
title,
|
||||||
|
className,
|
||||||
}) => {
|
}) => {
|
||||||
const playerRef = React.useRef(null);
|
const playerRef = React.useRef(null);
|
||||||
const [videoPlaying, setVideoPlaying] = useRecoilState<boolean>(isVideoPlayingAtom);
|
const [videoPlaying, setVideoPlaying] = useRecoilState<boolean>(isVideoPlayingAtom);
|
||||||
|
@ -308,7 +311,7 @@ export const OwncastPlayer: FC<OwncastPlayerProps> = ({
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.container} id="player">
|
<div className={classNames(styles.container, className)} id="player">
|
||||||
{online && (
|
{online && (
|
||||||
<div className={styles.player}>
|
<div className={styles.player}>
|
||||||
<VideoJS options={videoJsOptions} onReady={handlePlayerReady} aria-label={title} />
|
<VideoJS options={videoJsOptions} onReady={handlePlayerReady} aria-label={title} />
|
||||||
|
|
|
@ -11,7 +11,18 @@
|
||||||
.vjs-big-play-button {
|
.vjs-big-play-button {
|
||||||
z-index: 10;
|
z-index: 10;
|
||||||
color: var(--theme-color-action);
|
color: var(--theme-color-action);
|
||||||
font-size: 8rem !important;
|
|
||||||
|
// Setting the font size resizes the video.js
|
||||||
|
// BigPlayButton due to its style definitions
|
||||||
|
// (see https://github.com/videojs/video.js/blob/b306ce614e70e6d3305348d1b69e1434031d73ef/src/css/components/_big-play.scss)
|
||||||
|
// 30vmin determined by trial & error to not cause
|
||||||
|
// overflow with weird (small) x or y dimensions.
|
||||||
|
// min and max are also arbitrary; max was the old
|
||||||
|
// constant value. feel free to change if necessary,
|
||||||
|
// but check short and narrow screen sizes for overflow
|
||||||
|
// issues.
|
||||||
|
font-size: clamp(1rem, 30vmin, 8rem) !important;
|
||||||
|
|
||||||
border-color: transparent !important;
|
border-color: transparent !important;
|
||||||
border-radius: var(--theme-rounded-corners) !important;
|
border-radius: var(--theme-rounded-corners) !important;
|
||||||
background-color: transparent !important;
|
background-color: transparent !important;
|
||||||
|
@ -58,10 +69,10 @@
|
||||||
font-family: VideoJS, serif;
|
font-family: VideoJS, serif;
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
}
|
|
||||||
|
|
||||||
.vjs-icon-placeholder::before {
|
&::before {
|
||||||
content: '\f110';
|
content: '\f110';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,10 @@
|
||||||
.poster {
|
.poster {
|
||||||
background-color: black;
|
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.image {
|
||||||
|
background-color: black;
|
||||||
|
}
|
||||||
|
|
|
@ -36,6 +36,7 @@ export const VideoPoster: FC<VideoPosterProps> = ({ online, initialSrc, src: bas
|
||||||
objectFit="contain"
|
objectFit="contain"
|
||||||
height="auto"
|
height="auto"
|
||||||
width="100%"
|
width="100%"
|
||||||
|
className={styles.image}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
Loading…
Reference in a new issue