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 { 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>
|
||||
|
|
|
@ -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)}
|
||||
|
|
|
@ -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),
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
@ -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',
|
||||
},
|
||||
}}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -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,8 +32,13 @@ 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">
|
||||
<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);
|
||||
|
@ -38,7 +46,11 @@ export default function LivestreamSuperchats(props: Props) {
|
|||
|
||||
return (
|
||||
<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 />
|
||||
|
||||
<div
|
||||
|
@ -72,11 +84,30 @@ export default function LivestreamSuperchats(props: Props) {
|
|||
label={__('Show More')}
|
||||
button="inverse"
|
||||
className="close-button"
|
||||
onClick={toggleSuperChat}
|
||||
onClick={() => toggleSuperChat()}
|
||||
iconRight={ICONS.MORE}
|
||||
/>
|
||||
)}
|
||||
</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
|
||||
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,13 +256,42 @@ 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">
|
||||
{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}
|
||||
|
@ -262,7 +300,6 @@ export default function LivestreamChatLayout(props: Props) {
|
|||
handleDismissPin={() => setShowPinned(false)}
|
||||
/>
|
||||
|
||||
{!isMobile && (
|
||||
<Button
|
||||
title={__('Dismiss pinned comment')}
|
||||
button="inverse"
|
||||
|
@ -270,9 +307,9 @@ export default function LivestreamChatLayout(props: Props) {
|
|||
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" />
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -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 && (
|
||||
|
|
|
@ -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>
|
||||
);
|
||||
|
|
|
@ -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>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -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}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -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,7 +215,9 @@ export default function FilePage(props: Props) {
|
|||
|
||||
{RENDER_MODES.FLOATING_MODES.includes(renderMode) && <FileTitleSection uri={uri} />}
|
||||
|
||||
<React.Suspense fallback={null}>
|
||||
{isMobile ? (
|
||||
<>
|
||||
<SwipeableDrawer
|
||||
open={Boolean(showComments)}
|
||||
toggleDrawer={() => setShowComments(!showComments)}
|
||||
|
@ -223,20 +225,14 @@ export default function FilePage(props: Props) {
|
|||
>
|
||||
{commentsListElement}
|
||||
</SwipeableDrawer>
|
||||
|
||||
<DrawerExpandButton label={commentsListTitle} toggleDrawer={() => setShowComments(!showComments)} />
|
||||
</>
|
||||
) : (
|
||||
commentsListElement
|
||||
)}
|
||||
</>
|
||||
|
||||
{isMobile && (
|
||||
<Button
|
||||
className="swipeable-drawer__expand-button"
|
||||
label={commentsListTitle}
|
||||
button="primary"
|
||||
icon={ICONS.CHAT}
|
||||
onClick={() => setShowComments(!showComments)}
|
||||
/>
|
||||
)}
|
||||
</React.Suspense>
|
||||
</section>
|
||||
|
||||
{!isMarkdown && videoTheaterMode && <RightSideContent {...rightSideProps} />}
|
||||
</div>
|
||||
|
|
|
@ -68,5 +68,4 @@
|
|||
@import 'component/stripe-card';
|
||||
@import 'component/wallet-tip-send';
|
||||
@import 'component/swipe-list';
|
||||
@import 'component/swipeable-drawer';
|
||||
@import 'component/utils';
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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,8 +181,11 @@ $recent-msg-button__height: 2rem;
|
|||
padding: var(--spacing-xs);
|
||||
width: var(--livestream-comments-width);
|
||||
}
|
||||
}
|
||||
|
||||
.livestream-superchats__wrapper--mobile {
|
||||
@extend .livestream-superchats__wrapper;
|
||||
|
||||
@media (max-width: $breakpoint-small) {
|
||||
z-index: 1300;
|
||||
width: 100%;
|
||||
background-color: transparent;
|
||||
|
@ -195,10 +198,9 @@ $recent-msg-button__height: 2rem;
|
|||
height: 0px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.livestream-comments__top-actions {
|
||||
@media (max-width: $breakpoint-small) {
|
||||
.livestream-comments__top-actions--mobile {
|
||||
width: 100%;
|
||||
position: absolute;
|
||||
display: grid;
|
||||
padding: var(--spacing-xxs);
|
||||
|
@ -207,10 +209,26 @@ $recent-msg-button__height: 2rem;
|
|||
> div:not(:first-child) {
|
||||
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;
|
||||
flex-shrink: 0;
|
||||
position: relative;
|
||||
|
@ -237,8 +255,11 @@ $recent-msg-button__height: 2rem;
|
|||
padding: var(--spacing-xs);
|
||||
width: var(--livestream-comments-width);
|
||||
}
|
||||
}
|
||||
|
||||
.livestream-pinned__wrapper--mobile {
|
||||
@extend .livestream-pinned__wrapper;
|
||||
|
||||
@media (max-width: $breakpoint-small) {
|
||||
z-index: 1300;
|
||||
max-width: 100%;
|
||||
padding: 0;
|
||||
|
@ -278,7 +299,6 @@ $recent-msg-button__height: 2rem;
|
|||
padding-left: var(--spacing-xxs);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.livestreamSuperchat__amount--large {
|
||||
.credit-amount {
|
||||
|
@ -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,8 +367,11 @@ $recent-msg-button__height: 2rem;
|
|||
.channel-name {
|
||||
max-width: 5rem;
|
||||
}
|
||||
}
|
||||
|
||||
.livestream-superchat--mobile {
|
||||
@extend .livestream-superchat;
|
||||
|
||||
@media (max-width: $breakpoint-small) {
|
||||
background-color: #fff;
|
||||
padding: 5px;
|
||||
padding-bottom: 2px;
|
||||
|
@ -357,7 +380,6 @@ $recent-msg-button__height: 2rem;
|
|||
font-size: var(--font-xxsmall);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.livestreamSuperchat__info {
|
||||
display: flex;
|
||||
|
|
|
@ -30,8 +30,11 @@
|
|||
.channel-name {
|
||||
font-size: var(--font-xsmall);
|
||||
}
|
||||
}
|
||||
|
||||
.livestream__comment--mobile {
|
||||
@extend .livestream__comment;
|
||||
|
||||
@media (max-width: $breakpoint-small) {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
|
||||
|
@ -46,7 +49,6 @@
|
|||
font-size: var(--font-xxsmall) !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.livestream__comment--mentioned {
|
||||
background-color: var(--color-card-background-highlighted);
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -160,6 +160,10 @@
|
|||
width: unset;
|
||||
height: 2rem;
|
||||
}
|
||||
|
||||
.icon--Plus {
|
||||
top: -2px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue