SwipeableDrawer improvements

Fix css stuf

Split mobile and small popout window styles

Fix failed logic that broke desktop player
This commit is contained in:
Rafael 2022-02-02 09:48:24 -03:00 committed by Thomas Zarebczan
parent 55e0a7effe
commit b3ed0027ff
19 changed files with 489 additions and 250 deletions

View file

@ -33,6 +33,7 @@ import ClaimPreviewHidden from './claim-preview-no-mature';
import ClaimPreviewNoContent from './claim-preview-no-content';
import { ENABLE_NO_SOURCE_CLAIMS } from 'config';
import CollectionEditButtons from 'component/collectionEditButtons';
import { useIsMobile } from 'effects/use-screensize';
const AbandonedChannelPreview = lazyImport(() =>
import('component/abandonedChannelPreview' /* webpackChunkName: "abandonedChannelPreview" */)
@ -153,6 +154,8 @@ const ClaimPreview = forwardRef<any, {}>((props: Props, ref: any) => {
unavailableUris,
} = props;
const isMobile = useIsMobile();
const isCollection = claim && claim.value_type === 'collection';
const collectionClaimId = isCollection && claim && claim.claim_id;
const listId = collectionId || collectionClaimId;
@ -434,13 +437,11 @@ const ClaimPreview = forwardRef<any, {}>((props: Props, ref: any) => {
)}
{claim && (
<React.Fragment>
{typeof properties === 'function' ? (
properties(claim)
) : properties !== undefined ? (
properties
) : (
<ClaimTags uri={uri} type={type} />
)}
{typeof properties === 'function'
? properties(claim)
: properties !== undefined
? properties
: !isMobile && <ClaimTags uri={uri} type={type} />}
</React.Fragment>
)}
</div>

View file

@ -308,8 +308,8 @@ function CommentList(props: Props) {
<ul
className={classnames({
comments: isMediumScreen || expandedComments,
'comments--contracted': !isMediumScreen && !expandedComments,
comments: !isMediumScreen || expandedComments,
'comments--contracted': isMediumScreen && !expandedComments,
})}
>
{readyToDisplayComments && pinnedComments && getCommentElems(pinnedComments)}

View file

@ -9,6 +9,7 @@ import {
selectSuperChatTotalAmountForUri,
selectPinnedCommentsForUri,
} from 'redux/selectors/comments';
import { selectThemePath } from 'redux/selectors/settings';
import LivestreamChatLayout from './view';
const select = (state, props) => {
@ -20,6 +21,7 @@ const select = (state, props) => {
pinnedComments: selectPinnedCommentsForUri(state, uri),
superChats: selectSuperChatsForUri(state, uri),
superChatsTotalAmount: selectSuperChatTotalAmountForUri(state, uri),
theme: selectThemePath(state),
};
};

View file

@ -4,7 +4,6 @@ import { Global } from '@emotion/react';
import { Menu, MenuButton, MenuList, MenuItem } from '@reach/menu-button';
import { useHistory } from 'react-router-dom';
import { useIsMobile } from 'effects/use-screensize';
import usePersistedState from 'effects/use-persisted-state';
import * as ICONS from 'constants/icons';
import Icon from 'component/common/icon';
@ -14,20 +13,27 @@ type Props = {
isPopoutWindow?: boolean,
superchatsHidden?: boolean,
noSuperchats?: boolean,
isMobile?: boolean,
hideChat?: () => void,
setPopoutWindow?: (any) => void,
toggleSuperchats?: () => void,
};
export default function LivestreamMenu(props: Props) {
const { isPopoutWindow, superchatsHidden, noSuperchats, hideChat, setPopoutWindow, toggleSuperchats } = props;
const {
isPopoutWindow,
superchatsHidden,
noSuperchats,
isMobile,
hideChat,
setPopoutWindow,
toggleSuperchats,
} = props;
const {
location: { pathname },
} = useHistory();
const isMobile = useIsMobile();
const [showTimestamps, setShowTimestamps] = usePersistedState('live-timestamps', false);
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 (
<>
<MenuGlobalStyles />
<MenuGlobalStyles showTimestamps={showTimestamps} />
<Menu>
<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',
},
}}
/>
);
};

View file

@ -11,14 +11,17 @@ import OptimizedImage from 'component/optimizedImage';
import React from 'react';
import Tooltip from 'component/common/tooltip';
import UriIndicator from 'component/uriIndicator';
import Slide from '@mui/material/Slide';
type Props = {
superChats: Array<Comment>,
superchatsHidden?: boolean,
isMobile?: boolean,
toggleSuperChat: () => void,
};
export default function LivestreamSuperchats(props: Props) {
const { superChats: superChatsByAmount, toggleSuperChat } = props;
const { superChats: superChatsByAmount, superchatsHidden, isMobile, toggleSuperChat } = props;
const superChatTopTen = React.useMemo(() => {
return superChatsByAmount ? superChatsByAmount.slice(0, 10) : superChatsByAmount;
@ -29,54 +32,82 @@ export default function LivestreamSuperchats(props: Props) {
const showMore = superChatTopTen && superChatsByAmount && superChatTopTen.length < superChatsByAmount.length;
return !superChatTopTen ? null : (
<div className="livestreamSuperchats__wrapper">
<div className="livestreamSuperchats__inner">
{superChatTopTen.map((superChat: Comment) => {
const { comment, comment_id, channel_url, support_amount, is_fiat } = superChat;
const isSticker = stickerSuperChats && stickerSuperChats.includes(superChat);
const stickerImg = <OptimizedImage src={getStickerUrl(comment)} waitLoad loading="lazy" />;
return (
<Tooltip title={isSticker ? stickerImg : comment} key={comment_id}>
<div className="livestream__superchat">
<ChannelThumbnail uri={channel_url} xsmall />
<Slider isMobile={isMobile} superchatsHidden={superchatsHidden}>
<div
className={classnames('livestream-superchats__wrapper', {
'livestream-superchats__wrapper--mobile': isMobile,
})}
>
<div className="livestream-superchats">
{superChatTopTen.map((superChat: Comment) => {
const { comment, comment_id, channel_url, support_amount, is_fiat } = superChat;
const isSticker = stickerSuperChats && stickerSuperChats.includes(superChat);
const stickerImg = <OptimizedImage src={getStickerUrl(comment)} waitLoad loading="lazy" />;
return (
<Tooltip title={isSticker ? stickerImg : comment} key={comment_id}>
<div
className={classnames('livestreamSuperchat__info', {
'livestreamSuperchat__info--sticker': isSticker,
'livestreamSuperchat__info--notSticker': stickerSuperChats && !isSticker,
className={classnames('livestream-superchat', {
'livestream-superchat--mobile': isMobile,
})}
>
<div className="livestreamSuperchat__info--user">
<UriIndicator uri={channel_url} link />
<ChannelThumbnail uri={channel_url} xsmall />
<CreditAmount
hideTitle
size={10}
className="livestreamSuperchat__amount--large"
amount={support_amount}
isFiat={is_fiat}
/>
<div
className={classnames('livestreamSuperchat__info', {
'livestreamSuperchat__info--sticker': isSticker,
'livestreamSuperchat__info--notSticker': stickerSuperChats && !isSticker,
})}
>
<div className="livestreamSuperchat__info--user">
<UriIndicator uri={channel_url} link />
<CreditAmount
hideTitle
size={10}
className="livestreamSuperchat__amount--large"
amount={support_amount}
isFiat={is_fiat}
/>
</div>
{isSticker && <div className="livestreamSuperchat__info--image">{stickerImg}</div>}
</div>
{isSticker && <div className="livestreamSuperchat__info--image">{stickerImg}</div>}
</div>
</div>
</Tooltip>
);
})}
</Tooltip>
);
})}
{showMore && (
<Button
title={__('Show More...')}
label={__('Show More')}
button="inverse"
className="close-button"
onClick={toggleSuperChat}
iconRight={ICONS.MORE}
/>
)}
{showMore && (
<Button
title={__('Show More...')}
label={__('Show More')}
button="inverse"
className="close-button"
onClick={() => toggleSuperChat()}
iconRight={ICONS.MORE}
/>
)}
</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}</>
);
};

View file

@ -1,6 +1,11 @@
// @flow
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 { useIsMobile } from 'effects/use-screensize';
import * as ICONS from 'constants/icons';
@ -16,6 +21,7 @@ import React from 'react';
import Spinner from 'component/spinner';
import Yrbl from 'component/yrbl';
import { getTipValues } from 'util/livestream';
import Slide from '@mui/material/Slide';
const VIEW_MODES = {
CHAT: 'chat',
@ -35,6 +41,7 @@ type Props = {
hideHeader?: boolean,
superchatsHidden?: boolean,
customViewMode?: string,
theme: string,
doCommentList: (string, string, number, number) => void,
doResolveUris: (Array<string>, boolean) => void,
doSuperChatList: (string) => void,
@ -52,12 +59,13 @@ export default function LivestreamChatLayout(props: Props) {
hideHeader,
superchatsHidden,
customViewMode,
theme,
doCommentList,
doResolveUris,
doSuperChatList,
} = props;
const isMobile = useIsMobile();
const isMobile = useIsMobile() && !isPopoutWindow;
const discussionElement = document.querySelector('.livestream__comments');
@ -225,6 +233,7 @@ export default function LivestreamChatLayout(props: Props) {
isPopoutWindow={isPopoutWindow}
hideChat={() => setChatHidden(true)}
setPopoutWindow={(v) => setPopoutWindow(v)}
isMobile={isMobile}
/>
</div>
@ -247,32 +256,60 @@ export default function LivestreamChatLayout(props: Props) {
)}
<div ref={commentsRef} className="livestreamComments__wrapper">
<div className="livestream-comments__top-actions">
{viewMode === VIEW_MODES.CHAT && superChatsByAmount && !superchatsHidden && (
<LivestreamSuperchats superChats={superChatsByAmount} toggleSuperChat={toggleSuperChat} />
<div
className={classnames('livestream-comments__top-actions', {
'livestream-comments__top-actions--mobile': isMobile,
})}
>
{isMobile && ((pinnedComment && showPinned) || (superChatsByAmount && !superchatsHidden)) && (
<MobileDrawerTopGradient theme={theme} />
)}
{pinnedComment && showPinned && viewMode === VIEW_MODES.CHAT && (
<div className="livestreamPinned__wrapper">
<LivestreamComment
comment={pinnedComment}
key={pinnedComment.comment_id}
uri={uri}
pushMention={setMention}
handleDismissPin={() => setShowPinned(false)}
/>
{!isMobile && (
<Button
title={__('Dismiss pinned comment')}
button="inverse"
className="close-button"
onClick={() => setShowPinned(false)}
icon={ICONS.REMOVE}
/>
)}
</div>
{viewMode === VIEW_MODES.CHAT && superChatsByAmount && (
<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
comment={pinnedComment}
key={pinnedComment.comment_id}
uri={uri}
pushMention={setMention}
handleDismissPin={() => setShowPinned(false)}
/>
<Button
title={__('Dismiss pinned comment')}
button="inverse"
className="close-button"
onClick={() => setShowPinned(false)}
icon={ICONS.REMOVE}
/>
</div>
)
))}
</div>
{viewMode === VIEW_MODES.SUPERCHAT && resolvingSuperChats ? (
@ -280,7 +317,12 @@ export default function LivestreamChatLayout(props: Props) {
<Spinner />
</div>
) : (
<LivestreamComments uri={uri} commentsToDisplay={commentsToDisplay} pushMention={setMention} />
<LivestreamComments
uri={uri}
commentsToDisplay={commentsToDisplay}
pushMention={setMention}
isMobile={isMobile}
/>
)}
{scrollPos < 0 && (
@ -308,3 +350,28 @@ export default function LivestreamChatLayout(props: Props) {
</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" />
</>
);
};

View file

@ -26,11 +26,12 @@ type Props = {
claim: StreamClaim,
myChannelIds: ?Array<string>,
stakedLevel: number,
isMobile?: boolean,
handleDismissPin?: () => void,
};
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 {
channel_url: authorUri,
@ -65,6 +66,7 @@ export default function LivestreamComment(props: Props) {
'livestream__comment--superchat': supportAmount > 0,
'livestream__comment--sticker': isSticker,
'livestream__comment--mentioned': hasUserMention,
'livestream__comment--mobile': isMobile,
})}
>
{supportAmount > 0 && (

View file

@ -11,10 +11,11 @@ type Props = {
commentsToDisplay: Array<Comment>,
fetchingComments: boolean,
uri: string,
isMobile?: boolean,
};
export default function LivestreamComments(props: Props) {
const { commentsToDisplay, fetchingComments, uri } = props;
const { commentsToDisplay, fetchingComments, uri, isMobile } = props;
const [forceUpdate, setForceUpdate] = React.useState(0);
@ -49,7 +50,13 @@ export default function LivestreamComments(props: Props) {
.slice(0)
.reverse()
.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>
);

View file

@ -1,4 +1,6 @@
// @flow
import 'scss/component/_swipeable-drawer.scss';
import { lazyImport } from 'util/lazyImport';
import { useIsMobile } from 'effects/use-screensize';
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 FileRenderInitiator from 'component/fileRenderInitiator';
import LivestreamIframeRender from './iframe-render';
import Button from 'component/button';
import * as ICONS from 'constants/icons';
import SwipeableDrawer from 'component/swipeableDrawer';
import { DrawerExpandButton } from 'component/swipeableDrawer/view';
import LivestreamMenu from 'component/livestreamChatLayout/livestream-menu';
import Icon from 'component/common/icon';
import CreditAmount from 'component/common/credit-amount';
@ -57,31 +59,6 @@ export default function LivestreamLayout(props: Props) {
if (!claim || !claim.signing_channel) return null;
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 (
<>
@ -132,12 +109,19 @@ export default function LivestreamLayout(props: Props) {
<SwipeableDrawer
open={Boolean(showChat)}
toggleDrawer={() => setShowChat(!showChat)}
title={<ChatModeSelector />}
title={
<ChatModeSelector
superChats={superChats}
chatViewMode={chatViewMode}
setChatViewMode={(mode) => setChatViewMode(mode)}
/>
}
actions={
<LivestreamMenu
noSuperchats={!superChats || superChats.length === 0}
superchatsHidden={superchatsHidden}
toggleSuperchats={() => setSuperchatsHidden(!superchatsHidden)}
isMobile
/>
}
>
@ -148,17 +132,9 @@ export default function LivestreamLayout(props: Props) {
customViewMode={chatViewMode}
/>
</SwipeableDrawer>
</React.Suspense>
)}
{isMobile && (
<Button
className="swipeable-drawer__expand-button"
label="Open Live Chat"
button="primary"
icon={ICONS.CHAT}
onClick={() => setShowChat(!showChat)}
/>
<DrawerExpandButton label={__('Open Live Chat')} toggleDrawer={() => setShowChat(!showChat)} />
</React.Suspense>
)}
<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>
);
};

View file

@ -1,4 +1,6 @@
// @flow
import 'scss/component/_swipeable-drawer.scss';
// $FlowFixMe
import { Global } from '@emotion/react';
// $FlowFixMe
@ -14,7 +16,7 @@ const DRAWER_PULLER_HEIGHT = 42;
type Props = {
children: Node,
open: Boolean,
open: boolean,
theme: string,
mobilePlayerDimensions?: { height: number },
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 (
<>
<DrawerGlobalStyles />
@ -93,8 +79,8 @@ export default function SwipeableDrawer(props: Props) {
>
{open && (
<div className="swipeable-drawer__header" style={{ top: -DRAWER_PULLER_HEIGHT }}>
<Puller />
<HeaderContents />
<Puller theme={theme} />
<HeaderContents title={title} actions={actions} toggleDrawer={toggleDrawer} />
</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}
/>
);
};

View file

@ -16,7 +16,7 @@ import Button from 'component/button';
import I18nMessage from 'component/i18nMessage';
import Empty from 'component/common/empty';
import SwipeableDrawer from 'component/swipeableDrawer';
import * as ICONS from 'constants/icons';
import { DrawerExpandButton } from 'component/swipeableDrawer/view';
import { useIsMobile } from 'effects/use-screensize';
const CommentsList = lazyImport(() => import('component/commentsList' /* webpackChunkName: "comments" */));
@ -199,7 +199,7 @@ export default function FilePage(props: Props) {
{!isMarkdown && (
<div className="file-page__secondary-content">
<>
<section className="file-page__media-actions">
{claimIsMine && isLivestream && (
<div className="livestream__creator-message">
<h4>{__('Only visible to you')}</h4>
@ -215,28 +215,24 @@ export default function FilePage(props: Props) {
{RENDER_MODES.FLOATING_MODES.includes(renderMode) && <FileTitleSection uri={uri} />}
{isMobile ? (
<SwipeableDrawer
open={Boolean(showComments)}
toggleDrawer={() => setShowComments(!showComments)}
title={commentsListTitle}
>
{commentsListElement}
</SwipeableDrawer>
) : (
commentsListElement
)}
</>
<React.Suspense fallback={null}>
{isMobile ? (
<>
<SwipeableDrawer
open={Boolean(showComments)}
toggleDrawer={() => setShowComments(!showComments)}
title={commentsListTitle}
>
{commentsListElement}
</SwipeableDrawer>
{isMobile && (
<Button
className="swipeable-drawer__expand-button"
label={commentsListTitle}
button="primary"
icon={ICONS.CHAT}
onClick={() => setShowComments(!showComments)}
/>
)}
<DrawerExpandButton label={commentsListTitle} toggleDrawer={() => setShowComments(!showComments)} />
</>
) : (
commentsListElement
)}
</React.Suspense>
</section>
{!isMarkdown && videoTheaterMode && <RightSideContent {...rightSideProps} />}
</div>

View file

@ -68,5 +68,4 @@
@import 'component/stripe-card';
@import 'component/wallet-tip-send';
@import 'component/swipe-list';
@import 'component/swipeable-drawer';
@import 'component/utils';

View file

@ -293,11 +293,36 @@
padding-bottom: 0;
margin: 0;
.card__title-section {
padding: 0px;
}
h1 {
font-size: 1.2rem;
font-weight: var(--font-weight-bold);
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;
}
}
}
}
}
}

View file

@ -43,11 +43,11 @@ $recent-msg-button__height: 2rem;
height: 95vh !important;
}
.livestreamSuperchats__wrapper {
.livestream-superchats__wrapper {
width: 100%;
}
.livestreamPinned__wrapper {
.livestream-pinned__wrapper {
width: 100%;
}
}
@ -168,7 +168,7 @@ $recent-msg-button__height: 2rem;
}
}
.livestreamSuperchats__wrapper {
.livestream-superchats__wrapper {
flex-shrink: 0;
position: relative;
overflow-x: scroll;
@ -181,36 +181,54 @@ $recent-msg-button__height: 2rem;
padding: var(--spacing-xs);
width: var(--livestream-comments-width);
}
}
@media (max-width: $breakpoint-small) {
z-index: 1300;
.livestream-superchats__wrapper--mobile {
@extend .livestream-superchats__wrapper;
z-index: 1300;
width: 100%;
background-color: transparent;
padding: 0px;
border-bottom: none;
scrollbar-width: 0px;
&::-webkit-scrollbar {
width: 0px;
height: 0px;
}
}
.livestream-comments__top-actions--mobile {
width: 100%;
position: absolute;
display: grid;
padding: var(--spacing-xxs);
padding-right: var(--spacing-m);
> div:not(:first-child) {
margin-top: var(--spacing-xxs);
}
.livestream__top-gradient {
width: 100%;
background-color: transparent;
padding: 0px;
border-bottom: none;
scrollbar-width: 0px;
&::-webkit-scrollbar {
width: 0px;
height: 0px;
}
}
}
.livestream-comments__top-actions {
@media (max-width: $breakpoint-small) {
height: 100%;
position: absolute;
display: grid;
padding: var(--spacing-xxs);
padding-right: var(--spacing-m);
> div:not(:first-child) {
margin-top: var(--spacing-xxs);
&:after {
position: absolute;
bottom: 0;
opacity: 1;
content: '';
height: 100%;
left: 0;
right: 0;
width: 100%;
}
}
}
.livestreamPinned__wrapper {
.livestream-pinned__wrapper {
display: flex;
flex-shrink: 0;
position: relative;
@ -237,46 +255,48 @@ $recent-msg-button__height: 2rem;
padding: var(--spacing-xs);
width: var(--livestream-comments-width);
}
}
@media (max-width: $breakpoint-small) {
z-index: 1300;
max-width: 100%;
padding: 0;
padding-left: var(--spacing-xxs);
border-radius: var(--border-radius);
border: 1px solid var(--color-border);
.livestream-pinned__wrapper--mobile {
@extend .livestream-pinned__wrapper;
.livestream__comment {
overflow: unset;
z-index: 1300;
max-width: 100%;
padding: 0;
padding-left: var(--spacing-xxs);
border-radius: var(--border-radius);
border: 1px solid var(--color-border);
.livestreamComment__body {
margin: 0px;
width: 100%;
.livestream__comment {
overflow: unset;
.markdown-preview {
p,
.button__label {
white-space: nowrap !important;
overflow: hidden;
text-overflow: ellipsis;
word-break: break-all;
}
.livestreamComment__body {
margin: 0px;
width: 100%;
a {
pointer-events: none;
}
.markdown-preview {
p,
.button__label {
white-space: nowrap !important;
overflow: hidden;
text-overflow: ellipsis;
word-break: break-all;
}
a {
pointer-events: none;
}
}
}
}
span {
font-size: var(--font-xxsmall) !important;
}
span {
font-size: var(--font-xxsmall) !important;
}
.close-button {
padding: 0;
padding-left: var(--spacing-xxs);
}
.close-button {
padding: 0;
padding-left: var(--spacing-xxs);
}
}
@ -288,7 +308,7 @@ $recent-msg-button__height: 2rem;
}
}
.livestreamSuperchats__inner {
.livestream-superchats {
display: flex;
.close-button {
@ -296,7 +316,7 @@ $recent-msg-button__height: 2rem;
}
}
.livestream__superchat {
.livestream-superchat {
display: flex;
margin-right: var(--spacing-xs);
padding: var(--spacing-xxs);
@ -347,15 +367,17 @@ $recent-msg-button__height: 2rem;
.channel-name {
max-width: 5rem;
}
}
@media (max-width: $breakpoint-small) {
background-color: #fff;
padding: 5px;
padding-bottom: 2px;
.livestream-superchat--mobile {
@extend .livestream-superchat;
span {
font-size: var(--font-xxsmall);
}
background-color: #fff;
padding: 5px;
padding-bottom: 2px;
span {
font-size: var(--font-xxsmall);
}
}

View file

@ -30,21 +30,23 @@
.channel-name {
font-size: var(--font-xsmall);
}
}
@media (max-width: $breakpoint-small) {
display: flex;
justify-content: space-between;
.livestream__comment--mobile {
@extend .livestream__comment;
.livestreamComment__menu {
position: relative;
right: 0;
top: 0;
}
display: flex;
justify-content: space-between;
span,
p {
font-size: var(--font-xxsmall) !important;
}
.livestreamComment__menu {
position: relative;
right: 0;
top: 0;
}
span,
p {
font-size: var(--font-xxsmall) !important;
}
}

View file

@ -169,6 +169,12 @@
margin-left: 0;
margin-top: var(--spacing-l);
}
@media (max-width: $breakpoint-small) {
.card__header--between {
padding: var(--spacing-xxs);
}
}
}
.file-page__recommended-collection {

View file

@ -160,6 +160,10 @@
width: unset;
height: 2rem;
}
.icon--Plus {
top: -2px;
}
}
}

View file

@ -9,6 +9,10 @@
top: 2px !important;
right: 2px !important;
}
span {
color: var(--color-text);
}
}
.swipeable-drawer__puller {
@ -40,6 +44,10 @@
.swipeable-drawer__header-actions {
display: flex;
button {
padding: 0.3rem;
}
button:not(:last-child) {
margin-right: var(--spacing-xxs);
}
@ -48,7 +56,7 @@
.swipeable-drawer__expand-button {
width: 100%;
margin: var(--spacing-xxs) 0;
border-radius: 0;
border-radius: 0 !important;
}
.swipeable-drawer__expand {

View file

@ -24,6 +24,7 @@
.MuiOutlinedInput-root {
font-size: var(--font-xsmall) !important;
flex-wrap: nowrap !important;
color: var(--color-text) !important;
textarea {
border: none;
@ -38,6 +39,10 @@
height: unset;
}
}
span {
color: var(--color-text) !important;
}
}
}