SwipeableDrawer improvements
Fix css stuf Split mobile and small popout window styles Fix failed logic that broke desktop player
This commit is contained in:
parent
55e0a7effe
commit
b3ed0027ff
19 changed files with 489 additions and 250 deletions
|
@ -33,6 +33,7 @@ import ClaimPreviewHidden from './claim-preview-no-mature';
|
||||||
import ClaimPreviewNoContent from './claim-preview-no-content';
|
import ClaimPreviewNoContent from './claim-preview-no-content';
|
||||||
import { ENABLE_NO_SOURCE_CLAIMS } from 'config';
|
import { ENABLE_NO_SOURCE_CLAIMS } from 'config';
|
||||||
import CollectionEditButtons from 'component/collectionEditButtons';
|
import CollectionEditButtons from 'component/collectionEditButtons';
|
||||||
|
import { useIsMobile } from 'effects/use-screensize';
|
||||||
|
|
||||||
const AbandonedChannelPreview = lazyImport(() =>
|
const AbandonedChannelPreview = lazyImport(() =>
|
||||||
import('component/abandonedChannelPreview' /* webpackChunkName: "abandonedChannelPreview" */)
|
import('component/abandonedChannelPreview' /* webpackChunkName: "abandonedChannelPreview" */)
|
||||||
|
@ -153,6 +154,8 @@ const ClaimPreview = forwardRef<any, {}>((props: Props, ref: any) => {
|
||||||
unavailableUris,
|
unavailableUris,
|
||||||
} = props;
|
} = props;
|
||||||
|
|
||||||
|
const isMobile = useIsMobile();
|
||||||
|
|
||||||
const isCollection = claim && claim.value_type === 'collection';
|
const isCollection = claim && claim.value_type === 'collection';
|
||||||
const collectionClaimId = isCollection && claim && claim.claim_id;
|
const collectionClaimId = isCollection && claim && claim.claim_id;
|
||||||
const listId = collectionId || collectionClaimId;
|
const listId = collectionId || collectionClaimId;
|
||||||
|
@ -434,13 +437,11 @@ const ClaimPreview = forwardRef<any, {}>((props: Props, ref: any) => {
|
||||||
)}
|
)}
|
||||||
{claim && (
|
{claim && (
|
||||||
<React.Fragment>
|
<React.Fragment>
|
||||||
{typeof properties === 'function' ? (
|
{typeof properties === 'function'
|
||||||
properties(claim)
|
? properties(claim)
|
||||||
) : properties !== undefined ? (
|
: properties !== undefined
|
||||||
properties
|
? properties
|
||||||
) : (
|
: !isMobile && <ClaimTags uri={uri} type={type} />}
|
||||||
<ClaimTags uri={uri} type={type} />
|
|
||||||
)}
|
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -308,8 +308,8 @@ function CommentList(props: Props) {
|
||||||
|
|
||||||
<ul
|
<ul
|
||||||
className={classnames({
|
className={classnames({
|
||||||
comments: isMediumScreen || expandedComments,
|
comments: !isMediumScreen || expandedComments,
|
||||||
'comments--contracted': !isMediumScreen && !expandedComments,
|
'comments--contracted': isMediumScreen && !expandedComments,
|
||||||
})}
|
})}
|
||||||
>
|
>
|
||||||
{readyToDisplayComments && pinnedComments && getCommentElems(pinnedComments)}
|
{readyToDisplayComments && pinnedComments && getCommentElems(pinnedComments)}
|
||||||
|
|
|
@ -9,6 +9,7 @@ import {
|
||||||
selectSuperChatTotalAmountForUri,
|
selectSuperChatTotalAmountForUri,
|
||||||
selectPinnedCommentsForUri,
|
selectPinnedCommentsForUri,
|
||||||
} from 'redux/selectors/comments';
|
} from 'redux/selectors/comments';
|
||||||
|
import { selectThemePath } from 'redux/selectors/settings';
|
||||||
import LivestreamChatLayout from './view';
|
import LivestreamChatLayout from './view';
|
||||||
|
|
||||||
const select = (state, props) => {
|
const select = (state, props) => {
|
||||||
|
@ -20,6 +21,7 @@ const select = (state, props) => {
|
||||||
pinnedComments: selectPinnedCommentsForUri(state, uri),
|
pinnedComments: selectPinnedCommentsForUri(state, uri),
|
||||||
superChats: selectSuperChatsForUri(state, uri),
|
superChats: selectSuperChatsForUri(state, uri),
|
||||||
superChatsTotalAmount: selectSuperChatTotalAmountForUri(state, uri),
|
superChatsTotalAmount: selectSuperChatTotalAmountForUri(state, uri),
|
||||||
|
theme: selectThemePath(state),
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,6 @@ import { Global } from '@emotion/react';
|
||||||
|
|
||||||
import { Menu, MenuButton, MenuList, MenuItem } from '@reach/menu-button';
|
import { Menu, MenuButton, MenuList, MenuItem } from '@reach/menu-button';
|
||||||
import { useHistory } from 'react-router-dom';
|
import { useHistory } from 'react-router-dom';
|
||||||
import { useIsMobile } from 'effects/use-screensize';
|
|
||||||
import usePersistedState from 'effects/use-persisted-state';
|
import usePersistedState from 'effects/use-persisted-state';
|
||||||
import * as ICONS from 'constants/icons';
|
import * as ICONS from 'constants/icons';
|
||||||
import Icon from 'component/common/icon';
|
import Icon from 'component/common/icon';
|
||||||
|
@ -14,20 +13,27 @@ type Props = {
|
||||||
isPopoutWindow?: boolean,
|
isPopoutWindow?: boolean,
|
||||||
superchatsHidden?: boolean,
|
superchatsHidden?: boolean,
|
||||||
noSuperchats?: boolean,
|
noSuperchats?: boolean,
|
||||||
|
isMobile?: boolean,
|
||||||
hideChat?: () => void,
|
hideChat?: () => void,
|
||||||
setPopoutWindow?: (any) => void,
|
setPopoutWindow?: (any) => void,
|
||||||
toggleSuperchats?: () => void,
|
toggleSuperchats?: () => void,
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function LivestreamMenu(props: Props) {
|
export default function LivestreamMenu(props: Props) {
|
||||||
const { isPopoutWindow, superchatsHidden, noSuperchats, hideChat, setPopoutWindow, toggleSuperchats } = props;
|
const {
|
||||||
|
isPopoutWindow,
|
||||||
|
superchatsHidden,
|
||||||
|
noSuperchats,
|
||||||
|
isMobile,
|
||||||
|
hideChat,
|
||||||
|
setPopoutWindow,
|
||||||
|
toggleSuperchats,
|
||||||
|
} = props;
|
||||||
|
|
||||||
const {
|
const {
|
||||||
location: { pathname },
|
location: { pathname },
|
||||||
} = useHistory();
|
} = useHistory();
|
||||||
|
|
||||||
const isMobile = useIsMobile();
|
|
||||||
|
|
||||||
const [showTimestamps, setShowTimestamps] = usePersistedState('live-timestamps', false);
|
const [showTimestamps, setShowTimestamps] = usePersistedState('live-timestamps', false);
|
||||||
|
|
||||||
function handlePopout() {
|
function handlePopout() {
|
||||||
|
@ -42,19 +48,9 @@ export default function LivestreamMenu(props: Props) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const MenuGlobalStyles = () => (
|
|
||||||
<Global
|
|
||||||
styles={{
|
|
||||||
':root': {
|
|
||||||
'--live-timestamp-opacity': showTimestamps ? '0.5' : '0',
|
|
||||||
},
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<MenuGlobalStyles />
|
<MenuGlobalStyles showTimestamps={showTimestamps} />
|
||||||
|
|
||||||
<Menu>
|
<Menu>
|
||||||
<MenuButton className="menu__button">
|
<MenuButton className="menu__button">
|
||||||
|
@ -103,3 +99,21 @@ export default function LivestreamMenu(props: Props) {
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type GlobalStylesProps = {
|
||||||
|
showTimestamps?: boolean,
|
||||||
|
};
|
||||||
|
|
||||||
|
const MenuGlobalStyles = (globalStylesProps: GlobalStylesProps) => {
|
||||||
|
const { showTimestamps } = globalStylesProps;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Global
|
||||||
|
styles={{
|
||||||
|
':root': {
|
||||||
|
'--live-timestamp-opacity': showTimestamps ? '0.5' : '0',
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
|
@ -11,14 +11,17 @@ import OptimizedImage from 'component/optimizedImage';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import Tooltip from 'component/common/tooltip';
|
import Tooltip from 'component/common/tooltip';
|
||||||
import UriIndicator from 'component/uriIndicator';
|
import UriIndicator from 'component/uriIndicator';
|
||||||
|
import Slide from '@mui/material/Slide';
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
superChats: Array<Comment>,
|
superChats: Array<Comment>,
|
||||||
|
superchatsHidden?: boolean,
|
||||||
|
isMobile?: boolean,
|
||||||
toggleSuperChat: () => void,
|
toggleSuperChat: () => void,
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function LivestreamSuperchats(props: Props) {
|
export default function LivestreamSuperchats(props: Props) {
|
||||||
const { superChats: superChatsByAmount, toggleSuperChat } = props;
|
const { superChats: superChatsByAmount, superchatsHidden, isMobile, toggleSuperChat } = props;
|
||||||
|
|
||||||
const superChatTopTen = React.useMemo(() => {
|
const superChatTopTen = React.useMemo(() => {
|
||||||
return superChatsByAmount ? superChatsByAmount.slice(0, 10) : superChatsByAmount;
|
return superChatsByAmount ? superChatsByAmount.slice(0, 10) : superChatsByAmount;
|
||||||
|
@ -29,8 +32,13 @@ export default function LivestreamSuperchats(props: Props) {
|
||||||
const showMore = superChatTopTen && superChatsByAmount && superChatTopTen.length < superChatsByAmount.length;
|
const showMore = superChatTopTen && superChatsByAmount && superChatTopTen.length < superChatsByAmount.length;
|
||||||
|
|
||||||
return !superChatTopTen ? null : (
|
return !superChatTopTen ? null : (
|
||||||
<div className="livestreamSuperchats__wrapper">
|
<Slider isMobile={isMobile} superchatsHidden={superchatsHidden}>
|
||||||
<div className="livestreamSuperchats__inner">
|
<div
|
||||||
|
className={classnames('livestream-superchats__wrapper', {
|
||||||
|
'livestream-superchats__wrapper--mobile': isMobile,
|
||||||
|
})}
|
||||||
|
>
|
||||||
|
<div className="livestream-superchats">
|
||||||
{superChatTopTen.map((superChat: Comment) => {
|
{superChatTopTen.map((superChat: Comment) => {
|
||||||
const { comment, comment_id, channel_url, support_amount, is_fiat } = superChat;
|
const { comment, comment_id, channel_url, support_amount, is_fiat } = superChat;
|
||||||
const isSticker = stickerSuperChats && stickerSuperChats.includes(superChat);
|
const isSticker = stickerSuperChats && stickerSuperChats.includes(superChat);
|
||||||
|
@ -38,7 +46,11 @@ export default function LivestreamSuperchats(props: Props) {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Tooltip title={isSticker ? stickerImg : comment} key={comment_id}>
|
<Tooltip title={isSticker ? stickerImg : comment} key={comment_id}>
|
||||||
<div className="livestream__superchat">
|
<div
|
||||||
|
className={classnames('livestream-superchat', {
|
||||||
|
'livestream-superchat--mobile': isMobile,
|
||||||
|
})}
|
||||||
|
>
|
||||||
<ChannelThumbnail uri={channel_url} xsmall />
|
<ChannelThumbnail uri={channel_url} xsmall />
|
||||||
|
|
||||||
<div
|
<div
|
||||||
|
@ -72,11 +84,30 @@ export default function LivestreamSuperchats(props: Props) {
|
||||||
label={__('Show More')}
|
label={__('Show More')}
|
||||||
button="inverse"
|
button="inverse"
|
||||||
className="close-button"
|
className="close-button"
|
||||||
onClick={toggleSuperChat}
|
onClick={() => toggleSuperChat()}
|
||||||
iconRight={ICONS.MORE}
|
iconRight={ICONS.MORE}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</Slider>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type SliderProps = {
|
||||||
|
superchatsHidden?: boolean,
|
||||||
|
isMobile?: boolean,
|
||||||
|
children: any,
|
||||||
|
};
|
||||||
|
|
||||||
|
const Slider = (sliderProps: SliderProps) => {
|
||||||
|
const { superchatsHidden, isMobile, children } = sliderProps;
|
||||||
|
|
||||||
|
return isMobile ? (
|
||||||
|
<Slide direction="left" in={!superchatsHidden} mountOnEnter unmountOnExit>
|
||||||
|
{children}
|
||||||
|
</Slide>
|
||||||
|
) : (
|
||||||
|
<>{children}</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
|
@ -1,6 +1,11 @@
|
||||||
// @flow
|
// @flow
|
||||||
import 'scss/component/_livestream-chat.scss';
|
import 'scss/component/_livestream-chat.scss';
|
||||||
|
|
||||||
|
// $FlowFixMe
|
||||||
|
import { Global } from '@emotion/react';
|
||||||
|
// $FlowFixMe
|
||||||
|
import { grey } from '@mui/material/colors';
|
||||||
|
|
||||||
import { formatLbryUrlForWeb } from 'util/url';
|
import { formatLbryUrlForWeb } from 'util/url';
|
||||||
import { useIsMobile } from 'effects/use-screensize';
|
import { useIsMobile } from 'effects/use-screensize';
|
||||||
import * as ICONS from 'constants/icons';
|
import * as ICONS from 'constants/icons';
|
||||||
|
@ -16,6 +21,7 @@ import React from 'react';
|
||||||
import Spinner from 'component/spinner';
|
import Spinner from 'component/spinner';
|
||||||
import Yrbl from 'component/yrbl';
|
import Yrbl from 'component/yrbl';
|
||||||
import { getTipValues } from 'util/livestream';
|
import { getTipValues } from 'util/livestream';
|
||||||
|
import Slide from '@mui/material/Slide';
|
||||||
|
|
||||||
const VIEW_MODES = {
|
const VIEW_MODES = {
|
||||||
CHAT: 'chat',
|
CHAT: 'chat',
|
||||||
|
@ -35,6 +41,7 @@ type Props = {
|
||||||
hideHeader?: boolean,
|
hideHeader?: boolean,
|
||||||
superchatsHidden?: boolean,
|
superchatsHidden?: boolean,
|
||||||
customViewMode?: string,
|
customViewMode?: string,
|
||||||
|
theme: string,
|
||||||
doCommentList: (string, string, number, number) => void,
|
doCommentList: (string, string, number, number) => void,
|
||||||
doResolveUris: (Array<string>, boolean) => void,
|
doResolveUris: (Array<string>, boolean) => void,
|
||||||
doSuperChatList: (string) => void,
|
doSuperChatList: (string) => void,
|
||||||
|
@ -52,12 +59,13 @@ export default function LivestreamChatLayout(props: Props) {
|
||||||
hideHeader,
|
hideHeader,
|
||||||
superchatsHidden,
|
superchatsHidden,
|
||||||
customViewMode,
|
customViewMode,
|
||||||
|
theme,
|
||||||
doCommentList,
|
doCommentList,
|
||||||
doResolveUris,
|
doResolveUris,
|
||||||
doSuperChatList,
|
doSuperChatList,
|
||||||
} = props;
|
} = props;
|
||||||
|
|
||||||
const isMobile = useIsMobile();
|
const isMobile = useIsMobile() && !isPopoutWindow;
|
||||||
|
|
||||||
const discussionElement = document.querySelector('.livestream__comments');
|
const discussionElement = document.querySelector('.livestream__comments');
|
||||||
|
|
||||||
|
@ -225,6 +233,7 @@ export default function LivestreamChatLayout(props: Props) {
|
||||||
isPopoutWindow={isPopoutWindow}
|
isPopoutWindow={isPopoutWindow}
|
||||||
hideChat={() => setChatHidden(true)}
|
hideChat={() => setChatHidden(true)}
|
||||||
setPopoutWindow={(v) => setPopoutWindow(v)}
|
setPopoutWindow={(v) => setPopoutWindow(v)}
|
||||||
|
isMobile={isMobile}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -247,13 +256,42 @@ export default function LivestreamChatLayout(props: Props) {
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<div ref={commentsRef} className="livestreamComments__wrapper">
|
<div ref={commentsRef} className="livestreamComments__wrapper">
|
||||||
<div className="livestream-comments__top-actions">
|
<div
|
||||||
{viewMode === VIEW_MODES.CHAT && superChatsByAmount && !superchatsHidden && (
|
className={classnames('livestream-comments__top-actions', {
|
||||||
<LivestreamSuperchats superChats={superChatsByAmount} toggleSuperChat={toggleSuperChat} />
|
'livestream-comments__top-actions--mobile': isMobile,
|
||||||
|
})}
|
||||||
|
>
|
||||||
|
{isMobile && ((pinnedComment && showPinned) || (superChatsByAmount && !superchatsHidden)) && (
|
||||||
|
<MobileDrawerTopGradient theme={theme} />
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{pinnedComment && showPinned && viewMode === VIEW_MODES.CHAT && (
|
{viewMode === VIEW_MODES.CHAT && superChatsByAmount && (
|
||||||
<div className="livestreamPinned__wrapper">
|
<LivestreamSuperchats
|
||||||
|
superChats={superChatsByAmount}
|
||||||
|
toggleSuperChat={toggleSuperChat}
|
||||||
|
superchatsHidden={superchatsHidden}
|
||||||
|
isMobile={isMobile}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{pinnedComment &&
|
||||||
|
viewMode === VIEW_MODES.CHAT &&
|
||||||
|
(isMobile ? (
|
||||||
|
<Slide direction="left" in={showPinned} mountOnEnter unmountOnExit>
|
||||||
|
<div className="livestream-pinned__wrapper--mobile">
|
||||||
|
<LivestreamComment
|
||||||
|
comment={pinnedComment}
|
||||||
|
key={pinnedComment.comment_id}
|
||||||
|
uri={uri}
|
||||||
|
pushMention={setMention}
|
||||||
|
handleDismissPin={() => setShowPinned(false)}
|
||||||
|
isMobile
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</Slide>
|
||||||
|
) : (
|
||||||
|
showPinned && (
|
||||||
|
<div className="livestream-pinned__wrapper">
|
||||||
<LivestreamComment
|
<LivestreamComment
|
||||||
comment={pinnedComment}
|
comment={pinnedComment}
|
||||||
key={pinnedComment.comment_id}
|
key={pinnedComment.comment_id}
|
||||||
|
@ -262,7 +300,6 @@ export default function LivestreamChatLayout(props: Props) {
|
||||||
handleDismissPin={() => setShowPinned(false)}
|
handleDismissPin={() => setShowPinned(false)}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
{!isMobile && (
|
|
||||||
<Button
|
<Button
|
||||||
title={__('Dismiss pinned comment')}
|
title={__('Dismiss pinned comment')}
|
||||||
button="inverse"
|
button="inverse"
|
||||||
|
@ -270,9 +307,9 @@ export default function LivestreamChatLayout(props: Props) {
|
||||||
onClick={() => setShowPinned(false)}
|
onClick={() => setShowPinned(false)}
|
||||||
icon={ICONS.REMOVE}
|
icon={ICONS.REMOVE}
|
||||||
/>
|
/>
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
)}
|
)
|
||||||
|
))}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{viewMode === VIEW_MODES.SUPERCHAT && resolvingSuperChats ? (
|
{viewMode === VIEW_MODES.SUPERCHAT && resolvingSuperChats ? (
|
||||||
|
@ -280,7 +317,12 @@ export default function LivestreamChatLayout(props: Props) {
|
||||||
<Spinner />
|
<Spinner />
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<LivestreamComments uri={uri} commentsToDisplay={commentsToDisplay} pushMention={setMention} />
|
<LivestreamComments
|
||||||
|
uri={uri}
|
||||||
|
commentsToDisplay={commentsToDisplay}
|
||||||
|
pushMention={setMention}
|
||||||
|
isMobile={isMobile}
|
||||||
|
/>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{scrollPos < 0 && (
|
{scrollPos < 0 && (
|
||||||
|
@ -308,3 +350,28 @@ export default function LivestreamChatLayout(props: Props) {
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type GradientProps = {
|
||||||
|
theme: string,
|
||||||
|
};
|
||||||
|
|
||||||
|
const MobileDrawerTopGradient = (gradientProps: GradientProps) => {
|
||||||
|
const { theme } = gradientProps;
|
||||||
|
|
||||||
|
const DrawerGlobalStyles = () => (
|
||||||
|
<Global
|
||||||
|
styles={{
|
||||||
|
'.livestream__top-gradient::after': {
|
||||||
|
background: `linear-gradient(180deg, ${theme === 'light' ? grey[300] : grey[900]} 0, transparent 65%)`,
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<DrawerGlobalStyles />
|
||||||
|
<div className="livestream__top-gradient" />
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
|
@ -26,11 +26,12 @@ type Props = {
|
||||||
claim: StreamClaim,
|
claim: StreamClaim,
|
||||||
myChannelIds: ?Array<string>,
|
myChannelIds: ?Array<string>,
|
||||||
stakedLevel: number,
|
stakedLevel: number,
|
||||||
|
isMobile?: boolean,
|
||||||
handleDismissPin?: () => void,
|
handleDismissPin?: () => void,
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function LivestreamComment(props: Props) {
|
export default function LivestreamComment(props: Props) {
|
||||||
const { comment, forceUpdate, uri, claim, myChannelIds, stakedLevel, handleDismissPin } = props;
|
const { comment, forceUpdate, uri, claim, myChannelIds, stakedLevel, isMobile, handleDismissPin } = props;
|
||||||
|
|
||||||
const {
|
const {
|
||||||
channel_url: authorUri,
|
channel_url: authorUri,
|
||||||
|
@ -65,6 +66,7 @@ export default function LivestreamComment(props: Props) {
|
||||||
'livestream__comment--superchat': supportAmount > 0,
|
'livestream__comment--superchat': supportAmount > 0,
|
||||||
'livestream__comment--sticker': isSticker,
|
'livestream__comment--sticker': isSticker,
|
||||||
'livestream__comment--mentioned': hasUserMention,
|
'livestream__comment--mentioned': hasUserMention,
|
||||||
|
'livestream__comment--mobile': isMobile,
|
||||||
})}
|
})}
|
||||||
>
|
>
|
||||||
{supportAmount > 0 && (
|
{supportAmount > 0 && (
|
||||||
|
|
|
@ -11,10 +11,11 @@ type Props = {
|
||||||
commentsToDisplay: Array<Comment>,
|
commentsToDisplay: Array<Comment>,
|
||||||
fetchingComments: boolean,
|
fetchingComments: boolean,
|
||||||
uri: string,
|
uri: string,
|
||||||
|
isMobile?: boolean,
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function LivestreamComments(props: Props) {
|
export default function LivestreamComments(props: Props) {
|
||||||
const { commentsToDisplay, fetchingComments, uri } = props;
|
const { commentsToDisplay, fetchingComments, uri, isMobile } = props;
|
||||||
|
|
||||||
const [forceUpdate, setForceUpdate] = React.useState(0);
|
const [forceUpdate, setForceUpdate] = React.useState(0);
|
||||||
|
|
||||||
|
@ -49,7 +50,13 @@ export default function LivestreamComments(props: Props) {
|
||||||
.slice(0)
|
.slice(0)
|
||||||
.reverse()
|
.reverse()
|
||||||
.map((comment) => (
|
.map((comment) => (
|
||||||
<LivestreamComment comment={comment} key={comment.comment_id} uri={uri} forceUpdate={forceUpdate} />
|
<LivestreamComment
|
||||||
|
comment={comment}
|
||||||
|
key={comment.comment_id}
|
||||||
|
uri={uri}
|
||||||
|
forceUpdate={forceUpdate}
|
||||||
|
isMobile={isMobile}
|
||||||
|
/>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
// @flow
|
// @flow
|
||||||
|
import 'scss/component/_swipeable-drawer.scss';
|
||||||
|
|
||||||
import { lazyImport } from 'util/lazyImport';
|
import { lazyImport } from 'util/lazyImport';
|
||||||
import { useIsMobile } from 'effects/use-screensize';
|
import { useIsMobile } from 'effects/use-screensize';
|
||||||
import { Menu, MenuList, MenuButton, MenuItem } from '@reach/menu-button';
|
import { Menu, MenuList, MenuButton, MenuItem } from '@reach/menu-button';
|
||||||
|
@ -8,9 +10,9 @@ import React from 'react';
|
||||||
import { PRIMARY_PLAYER_WRAPPER_CLASS } from 'page/file/view';
|
import { PRIMARY_PLAYER_WRAPPER_CLASS } from 'page/file/view';
|
||||||
import FileRenderInitiator from 'component/fileRenderInitiator';
|
import FileRenderInitiator from 'component/fileRenderInitiator';
|
||||||
import LivestreamIframeRender from './iframe-render';
|
import LivestreamIframeRender from './iframe-render';
|
||||||
import Button from 'component/button';
|
|
||||||
import * as ICONS from 'constants/icons';
|
import * as ICONS from 'constants/icons';
|
||||||
import SwipeableDrawer from 'component/swipeableDrawer';
|
import SwipeableDrawer from 'component/swipeableDrawer';
|
||||||
|
import { DrawerExpandButton } from 'component/swipeableDrawer/view';
|
||||||
import LivestreamMenu from 'component/livestreamChatLayout/livestream-menu';
|
import LivestreamMenu from 'component/livestreamChatLayout/livestream-menu';
|
||||||
import Icon from 'component/common/icon';
|
import Icon from 'component/common/icon';
|
||||||
import CreditAmount from 'component/common/credit-amount';
|
import CreditAmount from 'component/common/credit-amount';
|
||||||
|
@ -57,31 +59,6 @@ export default function LivestreamLayout(props: Props) {
|
||||||
if (!claim || !claim.signing_channel) return null;
|
if (!claim || !claim.signing_channel) return null;
|
||||||
|
|
||||||
const { name: channelName, claim_id: channelClaimId } = claim.signing_channel;
|
const { name: channelName, claim_id: channelClaimId } = claim.signing_channel;
|
||||||
const { superChatsFiatAmount, superChatsLBCAmount } = getTipValues(superChats);
|
|
||||||
|
|
||||||
const ChatModeSelector = () => (
|
|
||||||
<Menu>
|
|
||||||
<MenuButton>
|
|
||||||
<span className="swipeable-drawer__title-menu">
|
|
||||||
{chatViewMode === VIEW_MODES.CHAT ? __('Live Chat') : __('Super Chats')}
|
|
||||||
<Icon icon={ICONS.DOWN} />
|
|
||||||
</span>
|
|
||||||
</MenuButton>
|
|
||||||
|
|
||||||
<MenuList className="menu__list--header">
|
|
||||||
<MenuItem className="menu__link" onSelect={() => setChatViewMode(VIEW_MODES.CHAT)}>
|
|
||||||
{__('Live Chat')}
|
|
||||||
</MenuItem>
|
|
||||||
|
|
||||||
<MenuItem className="menu__link" onSelect={() => setChatViewMode(VIEW_MODES.SUPERCHAT)}>
|
|
||||||
<div className="recommended-content__toggles">
|
|
||||||
<CreditAmount amount={superChatsLBCAmount || 0} size={8} /> /
|
|
||||||
<CreditAmount amount={superChatsFiatAmount || 0} size={8} isFiat /> {__('Tipped')}
|
|
||||||
</div>
|
|
||||||
</MenuItem>
|
|
||||||
</MenuList>
|
|
||||||
</Menu>
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
@ -132,12 +109,19 @@ export default function LivestreamLayout(props: Props) {
|
||||||
<SwipeableDrawer
|
<SwipeableDrawer
|
||||||
open={Boolean(showChat)}
|
open={Boolean(showChat)}
|
||||||
toggleDrawer={() => setShowChat(!showChat)}
|
toggleDrawer={() => setShowChat(!showChat)}
|
||||||
title={<ChatModeSelector />}
|
title={
|
||||||
|
<ChatModeSelector
|
||||||
|
superChats={superChats}
|
||||||
|
chatViewMode={chatViewMode}
|
||||||
|
setChatViewMode={(mode) => setChatViewMode(mode)}
|
||||||
|
/>
|
||||||
|
}
|
||||||
actions={
|
actions={
|
||||||
<LivestreamMenu
|
<LivestreamMenu
|
||||||
noSuperchats={!superChats || superChats.length === 0}
|
noSuperchats={!superChats || superChats.length === 0}
|
||||||
superchatsHidden={superchatsHidden}
|
superchatsHidden={superchatsHidden}
|
||||||
toggleSuperchats={() => setSuperchatsHidden(!superchatsHidden)}
|
toggleSuperchats={() => setSuperchatsHidden(!superchatsHidden)}
|
||||||
|
isMobile
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
|
@ -148,17 +132,9 @@ export default function LivestreamLayout(props: Props) {
|
||||||
customViewMode={chatViewMode}
|
customViewMode={chatViewMode}
|
||||||
/>
|
/>
|
||||||
</SwipeableDrawer>
|
</SwipeableDrawer>
|
||||||
</React.Suspense>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{isMobile && (
|
<DrawerExpandButton label={__('Open Live Chat')} toggleDrawer={() => setShowChat(!showChat)} />
|
||||||
<Button
|
</React.Suspense>
|
||||||
className="swipeable-drawer__expand-button"
|
|
||||||
label="Open Live Chat"
|
|
||||||
button="primary"
|
|
||||||
icon={ICONS.CHAT}
|
|
||||||
onClick={() => setShowChat(!showChat)}
|
|
||||||
/>
|
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<FileTitleSection uri={uri} livestream isLive={showLivestream} />
|
<FileTitleSection uri={uri} livestream isLive={showLivestream} />
|
||||||
|
@ -166,3 +142,36 @@ export default function LivestreamLayout(props: Props) {
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const ChatModeSelector = (chatSelectorProps: any) => {
|
||||||
|
const { superChats, chatViewMode, setChatViewMode } = chatSelectorProps;
|
||||||
|
const { superChatsFiatAmount, superChatsLBCAmount } = getTipValues(superChats);
|
||||||
|
|
||||||
|
if (!superChats) {
|
||||||
|
return __('Live Chat');
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Menu>
|
||||||
|
<MenuButton>
|
||||||
|
<span className="swipeable-drawer__title-menu">
|
||||||
|
{chatViewMode === VIEW_MODES.CHAT ? __('Live Chat') : __('Super Chats')}
|
||||||
|
<Icon icon={ICONS.DOWN} />
|
||||||
|
</span>
|
||||||
|
</MenuButton>
|
||||||
|
|
||||||
|
<MenuList className="menu__list--header">
|
||||||
|
<MenuItem className="menu__link" onSelect={() => setChatViewMode(VIEW_MODES.CHAT)}>
|
||||||
|
{__('Live Chat')}
|
||||||
|
</MenuItem>
|
||||||
|
|
||||||
|
<MenuItem className="menu__link" onSelect={() => setChatViewMode(VIEW_MODES.SUPERCHAT)}>
|
||||||
|
<div className="recommended-content__toggles">
|
||||||
|
<CreditAmount amount={superChatsLBCAmount || 0} size={8} /> /
|
||||||
|
<CreditAmount amount={superChatsFiatAmount || 0} size={8} isFiat /> {__('Tipped')}
|
||||||
|
</div>
|
||||||
|
</MenuItem>
|
||||||
|
</MenuList>
|
||||||
|
</Menu>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
// @flow
|
// @flow
|
||||||
|
import 'scss/component/_swipeable-drawer.scss';
|
||||||
|
|
||||||
// $FlowFixMe
|
// $FlowFixMe
|
||||||
import { Global } from '@emotion/react';
|
import { Global } from '@emotion/react';
|
||||||
// $FlowFixMe
|
// $FlowFixMe
|
||||||
|
@ -14,7 +16,7 @@ const DRAWER_PULLER_HEIGHT = 42;
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
children: Node,
|
children: Node,
|
||||||
open: Boolean,
|
open: boolean,
|
||||||
theme: string,
|
theme: string,
|
||||||
mobilePlayerDimensions?: { height: number },
|
mobilePlayerDimensions?: { height: number },
|
||||||
title: any,
|
title: any,
|
||||||
|
@ -60,22 +62,6 @@ export default function SwipeableDrawer(props: Props) {
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|
||||||
const Puller = () => (
|
|
||||||
<span className="swipeable-drawer__puller" style={{ backgroundColor: theme === 'light' ? grey[300] : grey[800] }} />
|
|
||||||
);
|
|
||||||
|
|
||||||
const HeaderContents = () => (
|
|
||||||
<div className="swipeable-drawer__header-content">
|
|
||||||
{title}
|
|
||||||
|
|
||||||
<div className="swipeable-drawer__header-actions">
|
|
||||||
{actions}
|
|
||||||
|
|
||||||
<Button icon={ICONS.REMOVE} iconSize={16} onClick={toggleDrawer} />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<DrawerGlobalStyles />
|
<DrawerGlobalStyles />
|
||||||
|
@ -93,8 +79,8 @@ export default function SwipeableDrawer(props: Props) {
|
||||||
>
|
>
|
||||||
{open && (
|
{open && (
|
||||||
<div className="swipeable-drawer__header" style={{ top: -DRAWER_PULLER_HEIGHT }}>
|
<div className="swipeable-drawer__header" style={{ top: -DRAWER_PULLER_HEIGHT }}>
|
||||||
<Puller />
|
<Puller theme={theme} />
|
||||||
<HeaderContents />
|
<HeaderContents title={title} actions={actions} toggleDrawer={toggleDrawer} />
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
@ -103,3 +89,56 @@ export default function SwipeableDrawer(props: Props) {
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type PullerProps = {
|
||||||
|
theme: string,
|
||||||
|
};
|
||||||
|
|
||||||
|
const Puller = (pullerProps: PullerProps) => {
|
||||||
|
const { theme } = pullerProps;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<span className="swipeable-drawer__puller" style={{ backgroundColor: theme === 'light' ? grey[300] : grey[800] }} />
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
type HeaderProps = {
|
||||||
|
title: any,
|
||||||
|
actions?: any,
|
||||||
|
toggleDrawer: () => void,
|
||||||
|
};
|
||||||
|
|
||||||
|
const HeaderContents = (headerProps: HeaderProps) => {
|
||||||
|
const { title, actions, toggleDrawer } = headerProps;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="swipeable-drawer__header-content">
|
||||||
|
{title}
|
||||||
|
|
||||||
|
<div className="swipeable-drawer__header-actions">
|
||||||
|
{actions}
|
||||||
|
|
||||||
|
<Button icon={ICONS.REMOVE} iconSize={16} onClick={toggleDrawer} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
type ExpandButtonProps = {
|
||||||
|
label: any,
|
||||||
|
toggleDrawer: () => void,
|
||||||
|
};
|
||||||
|
|
||||||
|
export const DrawerExpandButton = (expandButtonProps: ExpandButtonProps) => {
|
||||||
|
const { label, toggleDrawer } = expandButtonProps;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Button
|
||||||
|
className="swipeable-drawer__expand-button"
|
||||||
|
label={label}
|
||||||
|
button="primary"
|
||||||
|
icon={ICONS.CHAT}
|
||||||
|
onClick={toggleDrawer}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
|
@ -16,7 +16,7 @@ import Button from 'component/button';
|
||||||
import I18nMessage from 'component/i18nMessage';
|
import I18nMessage from 'component/i18nMessage';
|
||||||
import Empty from 'component/common/empty';
|
import Empty from 'component/common/empty';
|
||||||
import SwipeableDrawer from 'component/swipeableDrawer';
|
import SwipeableDrawer from 'component/swipeableDrawer';
|
||||||
import * as ICONS from 'constants/icons';
|
import { DrawerExpandButton } from 'component/swipeableDrawer/view';
|
||||||
import { useIsMobile } from 'effects/use-screensize';
|
import { useIsMobile } from 'effects/use-screensize';
|
||||||
|
|
||||||
const CommentsList = lazyImport(() => import('component/commentsList' /* webpackChunkName: "comments" */));
|
const CommentsList = lazyImport(() => import('component/commentsList' /* webpackChunkName: "comments" */));
|
||||||
|
@ -199,7 +199,7 @@ export default function FilePage(props: Props) {
|
||||||
|
|
||||||
{!isMarkdown && (
|
{!isMarkdown && (
|
||||||
<div className="file-page__secondary-content">
|
<div className="file-page__secondary-content">
|
||||||
<>
|
<section className="file-page__media-actions">
|
||||||
{claimIsMine && isLivestream && (
|
{claimIsMine && isLivestream && (
|
||||||
<div className="livestream__creator-message">
|
<div className="livestream__creator-message">
|
||||||
<h4>{__('Only visible to you')}</h4>
|
<h4>{__('Only visible to you')}</h4>
|
||||||
|
@ -215,7 +215,9 @@ export default function FilePage(props: Props) {
|
||||||
|
|
||||||
{RENDER_MODES.FLOATING_MODES.includes(renderMode) && <FileTitleSection uri={uri} />}
|
{RENDER_MODES.FLOATING_MODES.includes(renderMode) && <FileTitleSection uri={uri} />}
|
||||||
|
|
||||||
|
<React.Suspense fallback={null}>
|
||||||
{isMobile ? (
|
{isMobile ? (
|
||||||
|
<>
|
||||||
<SwipeableDrawer
|
<SwipeableDrawer
|
||||||
open={Boolean(showComments)}
|
open={Boolean(showComments)}
|
||||||
toggleDrawer={() => setShowComments(!showComments)}
|
toggleDrawer={() => setShowComments(!showComments)}
|
||||||
|
@ -223,20 +225,14 @@ export default function FilePage(props: Props) {
|
||||||
>
|
>
|
||||||
{commentsListElement}
|
{commentsListElement}
|
||||||
</SwipeableDrawer>
|
</SwipeableDrawer>
|
||||||
|
|
||||||
|
<DrawerExpandButton label={commentsListTitle} toggleDrawer={() => setShowComments(!showComments)} />
|
||||||
|
</>
|
||||||
) : (
|
) : (
|
||||||
commentsListElement
|
commentsListElement
|
||||||
)}
|
)}
|
||||||
</>
|
</React.Suspense>
|
||||||
|
</section>
|
||||||
{isMobile && (
|
|
||||||
<Button
|
|
||||||
className="swipeable-drawer__expand-button"
|
|
||||||
label={commentsListTitle}
|
|
||||||
button="primary"
|
|
||||||
icon={ICONS.CHAT}
|
|
||||||
onClick={() => setShowComments(!showComments)}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{!isMarkdown && videoTheaterMode && <RightSideContent {...rightSideProps} />}
|
{!isMarkdown && videoTheaterMode && <RightSideContent {...rightSideProps} />}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -68,5 +68,4 @@
|
||||||
@import 'component/stripe-card';
|
@import 'component/stripe-card';
|
||||||
@import 'component/wallet-tip-send';
|
@import 'component/wallet-tip-send';
|
||||||
@import 'component/swipe-list';
|
@import 'component/swipe-list';
|
||||||
@import 'component/swipeable-drawer';
|
|
||||||
@import 'component/utils';
|
@import 'component/utils';
|
||||||
|
|
|
@ -293,11 +293,36 @@
|
||||||
padding-bottom: 0;
|
padding-bottom: 0;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
|
|
||||||
|
.card__title-section {
|
||||||
|
padding: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
h1 {
|
h1 {
|
||||||
font-size: 1.2rem;
|
font-size: 1.2rem;
|
||||||
font-weight: var(--font-weight-bold);
|
font-weight: var(--font-weight-bold);
|
||||||
line-height: 1.25;
|
line-height: 1.25;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
font-size: 1.2rem;
|
||||||
|
line-height: 1.25;
|
||||||
|
}
|
||||||
|
|
||||||
|
.recommended-content__toggles {
|
||||||
|
button {
|
||||||
|
height: unset;
|
||||||
|
padding: 2px var(--spacing-xxs);
|
||||||
|
|
||||||
|
.button__content {
|
||||||
|
height: unset;
|
||||||
|
|
||||||
|
span {
|
||||||
|
font-size: var(--font-small);
|
||||||
|
line-height: 1.25;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -43,11 +43,11 @@ $recent-msg-button__height: 2rem;
|
||||||
height: 95vh !important;
|
height: 95vh !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.livestreamSuperchats__wrapper {
|
.livestream-superchats__wrapper {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.livestreamPinned__wrapper {
|
.livestream-pinned__wrapper {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -168,7 +168,7 @@ $recent-msg-button__height: 2rem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.livestreamSuperchats__wrapper {
|
.livestream-superchats__wrapper {
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
position: relative;
|
position: relative;
|
||||||
overflow-x: scroll;
|
overflow-x: scroll;
|
||||||
|
@ -181,8 +181,11 @@ $recent-msg-button__height: 2rem;
|
||||||
padding: var(--spacing-xs);
|
padding: var(--spacing-xs);
|
||||||
width: var(--livestream-comments-width);
|
width: var(--livestream-comments-width);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.livestream-superchats__wrapper--mobile {
|
||||||
|
@extend .livestream-superchats__wrapper;
|
||||||
|
|
||||||
@media (max-width: $breakpoint-small) {
|
|
||||||
z-index: 1300;
|
z-index: 1300;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
|
@ -194,11 +197,10 @@ $recent-msg-button__height: 2rem;
|
||||||
width: 0px;
|
width: 0px;
|
||||||
height: 0px;
|
height: 0px;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.livestream-comments__top-actions {
|
.livestream-comments__top-actions--mobile {
|
||||||
@media (max-width: $breakpoint-small) {
|
width: 100%;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
display: grid;
|
display: grid;
|
||||||
padding: var(--spacing-xxs);
|
padding: var(--spacing-xxs);
|
||||||
|
@ -207,10 +209,26 @@ $recent-msg-button__height: 2rem;
|
||||||
> div:not(:first-child) {
|
> div:not(:first-child) {
|
||||||
margin-top: var(--spacing-xxs);
|
margin-top: var(--spacing-xxs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.livestream__top-gradient {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
position: absolute;
|
||||||
|
|
||||||
|
&:after {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0;
|
||||||
|
opacity: 1;
|
||||||
|
content: '';
|
||||||
|
height: 100%;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.livestreamPinned__wrapper {
|
.livestream-pinned__wrapper {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
@ -237,8 +255,11 @@ $recent-msg-button__height: 2rem;
|
||||||
padding: var(--spacing-xs);
|
padding: var(--spacing-xs);
|
||||||
width: var(--livestream-comments-width);
|
width: var(--livestream-comments-width);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.livestream-pinned__wrapper--mobile {
|
||||||
|
@extend .livestream-pinned__wrapper;
|
||||||
|
|
||||||
@media (max-width: $breakpoint-small) {
|
|
||||||
z-index: 1300;
|
z-index: 1300;
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
|
@ -277,7 +298,6 @@ $recent-msg-button__height: 2rem;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
padding-left: var(--spacing-xxs);
|
padding-left: var(--spacing-xxs);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.livestreamSuperchat__amount--large {
|
.livestreamSuperchat__amount--large {
|
||||||
|
@ -288,7 +308,7 @@ $recent-msg-button__height: 2rem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.livestreamSuperchats__inner {
|
.livestream-superchats {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|
||||||
.close-button {
|
.close-button {
|
||||||
|
@ -296,7 +316,7 @@ $recent-msg-button__height: 2rem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.livestream__superchat {
|
.livestream-superchat {
|
||||||
display: flex;
|
display: flex;
|
||||||
margin-right: var(--spacing-xs);
|
margin-right: var(--spacing-xs);
|
||||||
padding: var(--spacing-xxs);
|
padding: var(--spacing-xxs);
|
||||||
|
@ -347,8 +367,11 @@ $recent-msg-button__height: 2rem;
|
||||||
.channel-name {
|
.channel-name {
|
||||||
max-width: 5rem;
|
max-width: 5rem;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.livestream-superchat--mobile {
|
||||||
|
@extend .livestream-superchat;
|
||||||
|
|
||||||
@media (max-width: $breakpoint-small) {
|
|
||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
padding: 5px;
|
padding: 5px;
|
||||||
padding-bottom: 2px;
|
padding-bottom: 2px;
|
||||||
|
@ -356,7 +379,6 @@ $recent-msg-button__height: 2rem;
|
||||||
span {
|
span {
|
||||||
font-size: var(--font-xxsmall);
|
font-size: var(--font-xxsmall);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.livestreamSuperchat__info {
|
.livestreamSuperchat__info {
|
||||||
|
|
|
@ -30,8 +30,11 @@
|
||||||
.channel-name {
|
.channel-name {
|
||||||
font-size: var(--font-xsmall);
|
font-size: var(--font-xsmall);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.livestream__comment--mobile {
|
||||||
|
@extend .livestream__comment;
|
||||||
|
|
||||||
@media (max-width: $breakpoint-small) {
|
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
|
|
||||||
|
@ -45,7 +48,6 @@
|
||||||
p {
|
p {
|
||||||
font-size: var(--font-xxsmall) !important;
|
font-size: var(--font-xxsmall) !important;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.livestream__comment--mentioned {
|
.livestream__comment--mentioned {
|
||||||
|
|
|
@ -169,6 +169,12 @@
|
||||||
margin-left: 0;
|
margin-left: 0;
|
||||||
margin-top: var(--spacing-l);
|
margin-top: var(--spacing-l);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@media (max-width: $breakpoint-small) {
|
||||||
|
.card__header--between {
|
||||||
|
padding: var(--spacing-xxs);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.file-page__recommended-collection {
|
.file-page__recommended-collection {
|
||||||
|
|
|
@ -160,6 +160,10 @@
|
||||||
width: unset;
|
width: unset;
|
||||||
height: 2rem;
|
height: 2rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.icon--Plus {
|
||||||
|
top: -2px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,10 @@
|
||||||
top: 2px !important;
|
top: 2px !important;
|
||||||
right: 2px !important;
|
right: 2px !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
span {
|
||||||
|
color: var(--color-text);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.swipeable-drawer__puller {
|
.swipeable-drawer__puller {
|
||||||
|
@ -40,6 +44,10 @@
|
||||||
.swipeable-drawer__header-actions {
|
.swipeable-drawer__header-actions {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|
||||||
|
button {
|
||||||
|
padding: 0.3rem;
|
||||||
|
}
|
||||||
|
|
||||||
button:not(:last-child) {
|
button:not(:last-child) {
|
||||||
margin-right: var(--spacing-xxs);
|
margin-right: var(--spacing-xxs);
|
||||||
}
|
}
|
||||||
|
@ -48,7 +56,7 @@
|
||||||
.swipeable-drawer__expand-button {
|
.swipeable-drawer__expand-button {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
margin: var(--spacing-xxs) 0;
|
margin: var(--spacing-xxs) 0;
|
||||||
border-radius: 0;
|
border-radius: 0 !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.swipeable-drawer__expand {
|
.swipeable-drawer__expand {
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
.MuiOutlinedInput-root {
|
.MuiOutlinedInput-root {
|
||||||
font-size: var(--font-xsmall) !important;
|
font-size: var(--font-xsmall) !important;
|
||||||
flex-wrap: nowrap !important;
|
flex-wrap: nowrap !important;
|
||||||
|
color: var(--color-text) !important;
|
||||||
|
|
||||||
textarea {
|
textarea {
|
||||||
border: none;
|
border: none;
|
||||||
|
@ -38,6 +39,10 @@
|
||||||
height: unset;
|
height: unset;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
span {
|
||||||
|
color: var(--color-text) !important;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue