Fix keyboard & comment selectors open affecting scroll
This commit is contained in:
parent
e42090d3b6
commit
dae0f9c3d5
5 changed files with 57 additions and 10 deletions
|
@ -54,6 +54,7 @@ type Props = {
|
|||
supportDisabled: boolean,
|
||||
uri: string,
|
||||
disableInput?: boolean,
|
||||
onSlimInputClose?: () => void,
|
||||
setQuickReply: (any) => void,
|
||||
onCancelReplying?: () => void,
|
||||
onDoneReplying?: () => void,
|
||||
|
@ -89,6 +90,7 @@ export function CommentCreate(props: Props) {
|
|||
supportDisabled,
|
||||
uri,
|
||||
disableInput,
|
||||
onSlimInputClose,
|
||||
doCommentCreate,
|
||||
doFetchCreatorSettings,
|
||||
doToast,
|
||||
|
@ -177,6 +179,8 @@ export function CommentCreate(props: Props) {
|
|||
} else {
|
||||
setTipSelector(true);
|
||||
}
|
||||
|
||||
if (onSlimInputClose) onSlimInputClose();
|
||||
}
|
||||
|
||||
function handleStickerComment() {
|
||||
|
@ -198,6 +202,9 @@ export function CommentCreate(props: Props) {
|
|||
setTipAmount(sticker.price || 0);
|
||||
setShowSelectors({ tab: showSelectors.tab || undefined, open: false });
|
||||
|
||||
// added this here since selecting a sticker can cause scroll issues
|
||||
if (onSlimInputClose) onSlimInputClose();
|
||||
|
||||
if (sticker.price && sticker.price > 0) {
|
||||
setActiveTab(canReceiveFiatTip ? TAB_FIAT : TAB_LBC);
|
||||
setTipSelector(true);
|
||||
|
@ -207,6 +214,8 @@ export function CommentCreate(props: Props) {
|
|||
function handleCancelSticker() {
|
||||
setReviewingStickerComment(false);
|
||||
setSelectedSticker(null);
|
||||
|
||||
if (onSlimInputClose) onSlimInputClose();
|
||||
}
|
||||
|
||||
function handleCancelSupport() {
|
||||
|
@ -218,6 +227,8 @@ export function CommentCreate(props: Props) {
|
|||
setShowSelectors({ tab: showSelectors.tab || undefined, open: false });
|
||||
setSelectedSticker(null);
|
||||
}
|
||||
|
||||
if (onSlimInputClose) onSlimInputClose();
|
||||
}
|
||||
|
||||
function handleSupportComment() {
|
||||
|
@ -574,6 +585,7 @@ export function CommentCreate(props: Props) {
|
|||
handleSubmit={handleCreateComment}
|
||||
slimInput={isMobile && uri} // "uri": make sure it's on a file page
|
||||
slimInputButtonRef={slimInputButtonRef}
|
||||
onSlimInputClose={onSlimInputClose}
|
||||
commentSelectorsProps={commentSelectorsProps}
|
||||
submitButtonRef={buttonRef}
|
||||
setShowSelectors={setShowSelectors}
|
||||
|
@ -633,7 +645,10 @@ export function CommentCreate(props: Props) {
|
|||
disabled={disabled || tipSelectorError || !minAmountMet}
|
||||
icon={activeTab === TAB_LBC ? ICONS.LBC : ICONS.FINANCE}
|
||||
label={__('Review')}
|
||||
onClick={() => setReviewingSupportComment(true)}
|
||||
onClick={() => {
|
||||
setReviewingSupportComment(true);
|
||||
if (onSlimInputClose) onSlimInputClose();
|
||||
}}
|
||||
/>
|
||||
) : (
|
||||
(!isMobile || selectedSticker) &&
|
||||
|
|
|
@ -53,6 +53,7 @@ type Props = {
|
|||
submitButtonRef?: any,
|
||||
tipModalOpen?: boolean,
|
||||
noticeLabel?: any,
|
||||
onSlimInputClose?: () => void,
|
||||
onChange?: (any) => any,
|
||||
setShowSelectors?: ({ tab?: string, open: boolean }) => void,
|
||||
quickActionHandler?: (any) => any,
|
||||
|
@ -116,6 +117,7 @@ export class FormField extends React.PureComponent<Props, State> {
|
|||
submitButtonRef,
|
||||
tipModalOpen,
|
||||
noticeLabel,
|
||||
onSlimInputClose,
|
||||
quickActionHandler,
|
||||
setShowSelectors,
|
||||
render,
|
||||
|
@ -277,6 +279,7 @@ export class FormField extends React.PureComponent<Props, State> {
|
|||
showSelectors={Boolean(showSelectors && showSelectors.open)}
|
||||
slimInput={slimInput}
|
||||
slimInputButtonRef={slimInputButtonRef}
|
||||
onSlimInputClose={onSlimInputClose}
|
||||
tipModalOpen={tipModalOpen}
|
||||
>
|
||||
{(!slimInput || this.state.drawerOpen) && label && (
|
||||
|
|
|
@ -11,6 +11,7 @@ type TextareaWrapperProps = {
|
|||
showSelectors?: boolean,
|
||||
commentSelectorsProps?: any,
|
||||
tipModalOpen?: boolean,
|
||||
onSlimInputClose?: () => void,
|
||||
toggleDrawer: () => void,
|
||||
closeSelector?: () => void,
|
||||
};
|
||||
|
@ -24,6 +25,7 @@ export const TextareaWrapper = (wrapperProps: TextareaWrapperProps) => {
|
|||
commentSelectorsProps,
|
||||
showSelectors,
|
||||
tipModalOpen,
|
||||
onSlimInputClose,
|
||||
toggleDrawer,
|
||||
closeSelector,
|
||||
} = wrapperProps;
|
||||
|
@ -31,6 +33,7 @@ export const TextareaWrapper = (wrapperProps: TextareaWrapperProps) => {
|
|||
function handleCloseAll() {
|
||||
toggleDrawer();
|
||||
if (closeSelector) closeSelector();
|
||||
if (onSlimInputClose) onSlimInputClose();
|
||||
}
|
||||
|
||||
return slimInput ? (
|
||||
|
|
|
@ -82,6 +82,7 @@ export default function LivestreamChatLayout(props: Props) {
|
|||
const [chatHidden, setChatHidden] = React.useState(false);
|
||||
const [didInitialScroll, setDidInitialScroll] = React.useState(false);
|
||||
const [minScrollHeight, setMinScrollHeight] = React.useState(0);
|
||||
const [keyboardOpened, setKeyboardOpened] = React.useState(false);
|
||||
|
||||
const claimId = claim && claim.claim_id;
|
||||
const commentsToDisplay = viewMode === VIEW_MODES.CHAT ? commentsByChronologicalOrder : superChatsByAmount;
|
||||
|
@ -89,10 +90,7 @@ export default function LivestreamChatLayout(props: Props) {
|
|||
const pinnedComment = pinnedComments.length > 0 ? pinnedComments[0] : null;
|
||||
const { superChatsChannelUrls, superChatsFiatAmount, superChatsLBCAmount } = getTipValues(superChatsByAmount);
|
||||
const scrolledPastRecent = Boolean(
|
||||
(scrollPos || scrollPos === 0) &&
|
||||
(!isMobile || minScrollHeight) &&
|
||||
scrollPos < minScrollHeight &&
|
||||
viewMode === VIEW_MODES.CHAT
|
||||
viewMode === VIEW_MODES.CHAT && !isMobile ? scrollPos < 0 : scrollPos < minScrollHeight
|
||||
);
|
||||
|
||||
const restoreScrollPos = React.useCallback(() => {
|
||||
|
@ -149,7 +147,7 @@ export default function LivestreamChatLayout(props: Props) {
|
|||
if (discussionElement) {
|
||||
const scrollTop = discussionElement.scrollTop;
|
||||
|
||||
if (!scrollPos || scrollTop !== scrollPos) {
|
||||
if (scrollTop !== scrollPos) {
|
||||
setScrollPos(scrollTop);
|
||||
}
|
||||
}
|
||||
|
@ -171,7 +169,11 @@ export default function LivestreamChatLayout(props: Props) {
|
|||
// -ve scrollPos: user scrolled.
|
||||
const timer = setTimeout(() => {
|
||||
// Use a timer here to ensure we reset after the new comment has been rendered.
|
||||
if (!isMobile) {
|
||||
discussionElement.scrollTop = 0;
|
||||
} else {
|
||||
restoreScrollPos();
|
||||
}
|
||||
}, COMMENT_SCROLL_TIMEOUT);
|
||||
return () => clearTimeout(timer);
|
||||
}
|
||||
|
@ -179,6 +181,18 @@ export default function LivestreamChatLayout(props: Props) {
|
|||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [commentsLength]); // (Just respond to 'commentsLength' updates and nothing else)
|
||||
|
||||
// Restore Scroll Pos after mobile input opens keyboard and avoid scroll height conflicts
|
||||
React.useEffect(() => {
|
||||
if (keyboardOpened) {
|
||||
const timer = setTimeout(() => {
|
||||
restoreScrollPos();
|
||||
setKeyboardOpened(false);
|
||||
}, 300);
|
||||
|
||||
return () => clearTimeout(timer);
|
||||
}
|
||||
}, [keyboardOpened, restoreScrollPos]);
|
||||
|
||||
// Stop spinner for resolving superchats
|
||||
React.useEffect(() => {
|
||||
if (resolvingSuperChats) {
|
||||
|
@ -359,7 +373,14 @@ export default function LivestreamChatLayout(props: Props) {
|
|||
) : null}
|
||||
|
||||
<div className="livestream__comment-create">
|
||||
<CommentCreate isLivestream bottom embed={embed} uri={uri} onDoneReplying={restoreScrollPos} />
|
||||
<CommentCreate
|
||||
isLivestream
|
||||
bottom
|
||||
embed={embed}
|
||||
uri={uri}
|
||||
onDoneReplying={restoreScrollPos}
|
||||
onSlimInputClose={!scrolledPastRecent && isMobile ? () => setKeyboardOpened(true) : undefined}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -7,6 +7,7 @@ import LivestreamLayout from 'component/livestreamLayout';
|
|||
import moment from 'moment';
|
||||
import Page from 'component/page';
|
||||
import React from 'react';
|
||||
import { useIsMobile } from 'effects/use-screensize';
|
||||
|
||||
const LivestreamChatLayout = lazyImport(() => import('component/livestreamChatLayout' /* webpackChunkName: "chat" */));
|
||||
|
||||
|
@ -41,6 +42,8 @@ export default function LivestreamPage(props: Props) {
|
|||
doUserSetReferrer,
|
||||
} = props;
|
||||
|
||||
const isMobile = useIsMobile();
|
||||
|
||||
const [activeStreamUri, setActiveStreamUri] = React.useState(false);
|
||||
const [showLivestream, setShowLivestream] = React.useState(false);
|
||||
const [showScheduledInfo, setShowScheduledInfo] = React.useState(false);
|
||||
|
@ -145,8 +148,10 @@ export default function LivestreamPage(props: Props) {
|
|||
// This can be removed when we start using the app video player, not a LIVESTREAM iframe
|
||||
doSetPlayingUri({ uri: null });
|
||||
|
||||
return () => doSetPlayingUri({ uri: null });
|
||||
}, [doSetPlayingUri]);
|
||||
return () => {
|
||||
if (isMobile) doSetPlayingUri({ uri: null });
|
||||
};
|
||||
}, [doSetPlayingUri, isMobile]);
|
||||
|
||||
return (
|
||||
<Page
|
||||
|
|
Loading…
Reference in a new issue