fix(reply modal): get mobile scroll position from hook before render

This commit is contained in:
plebeius.eth
2024-04-30 11:08:01 +02:00
parent d797dbd0bd
commit 1e91119687
4 changed files with 17 additions and 9 deletions
+3 -3
View File
@@ -13,9 +13,10 @@ import _ from 'lodash';
interface ReplyModalProps { interface ReplyModalProps {
closeModal: () => void; closeModal: () => void;
parentCid: string; parentCid: string;
scrollY: number;
} }
const ReplyModal = ({ closeModal, parentCid }: ReplyModalProps) => { const ReplyModal = ({ closeModal, parentCid, scrollY }: ReplyModalProps) => {
const { t } = useTranslation(); const { t } = useTranslation();
const { subplebbitAddress } = useParams() as { subplebbitAddress: string }; const { subplebbitAddress } = useParams() as { subplebbitAddress: string };
const { setContent, resetContent, replyIndex, publishReply } = useReply({ cid: parentCid, subplebbitAddress }); const { setContent, resetContent, replyIndex, publishReply } = useReply({ cid: parentCid, subplebbitAddress });
@@ -56,12 +57,11 @@ const ReplyModal = ({ closeModal, parentCid }: ReplyModalProps) => {
useEffect(() => { useEffect(() => {
if (nodeRef.current && isMobile) { if (nodeRef.current && isMobile) {
const viewportHeight = window.innerHeight; const viewportHeight = window.innerHeight;
const scrollY = window.scrollY;
const modalHeight = 150; const modalHeight = 150;
const centeredPosition = scrollY + viewportHeight / 2 - modalHeight / 2; const centeredPosition = scrollY + viewportHeight / 2 - modalHeight / 2;
nodeRef.current.style.top = `${centeredPosition}px`; nodeRef.current.style.top = `${centeredPosition}px`;
} }
}, [isMobile]); }, [isMobile, scrollY]);
const modalContent = ( const modalContent = (
<div className={styles.container} ref={nodeRef}> <div className={styles.container} ref={nodeRef}>
+10 -2
View File
@@ -1,9 +1,14 @@
import { useState, useCallback } from 'react'; import { useState, useCallback } from 'react';
import useWindowWidth from './use-window-width';
const useReplyModal = () => { const useReplyModal = () => {
const [showReplyModal, setShowReplyModal] = useState(false); const [showReplyModal, setShowReplyModal] = useState(false);
const [activeCid, setActiveCid] = useState<string | null>(null); const [activeCid, setActiveCid] = useState<string | null>(null);
// on mobile, the position is absolute instead of fixed, so we need to calculate the top position
const isMobile = useWindowWidth() < 640;
const [scrollY, setScrollY] = useState<number>(0);
const closeModal = useCallback(() => { const closeModal = useCallback(() => {
setActiveCid(null); setActiveCid(null);
setShowReplyModal(false); setShowReplyModal(false);
@@ -11,6 +16,9 @@ const useReplyModal = () => {
const openReplyModal = useCallback( const openReplyModal = useCallback(
(cid: string) => { (cid: string) => {
if (isMobile) {
setScrollY(window.scrollY);
}
if (activeCid && activeCid !== cid) { if (activeCid && activeCid !== cid) {
closeModal(); closeModal();
setTimeout(() => { setTimeout(() => {
@@ -22,10 +30,10 @@ const useReplyModal = () => {
setShowReplyModal(true); setShowReplyModal(true);
} }
}, },
[activeCid, closeModal], [activeCid, closeModal, isMobile],
); );
return { showReplyModal, activeCid, openReplyModal, closeModal }; return { activeCid, closeModal, openReplyModal, scrollY, showReplyModal };
}; };
export default useReplyModal; export default useReplyModal;
+2 -2
View File
@@ -24,7 +24,7 @@ const Board = () => {
const subplebbit = useSubplebbit({ subplebbitAddress }); const subplebbit = useSubplebbit({ subplebbitAddress });
const { createdAt, description, rules, shortAddress, state, suggested, title } = subplebbit || {}; const { createdAt, description, rules, shortAddress, state, suggested, title } = subplebbit || {};
const { showReplyModal, activeCid, openReplyModal, closeModal } = useReplyModal(); const { activeCid, closeModal, openReplyModal, showReplyModal, scrollY } = useReplyModal();
const loadingStateString = useFeedStateString(subplebbitAddresses) || t('loading'); const loadingStateString = useFeedStateString(subplebbitAddresses) || t('loading');
const loadingString = <div className={styles.stateString}>{state === 'failed' ? state : <LoadingEllipsis string={loadingStateString} />}</div>; const loadingString = <div className={styles.stateString}>{state === 'failed' ? state : <LoadingEllipsis string={loadingStateString} />}</div>;
@@ -62,7 +62,7 @@ const Board = () => {
return ( return (
<div className={styles.content}> <div className={styles.content}>
{showReplyModal && activeCid && <ReplyModal closeModal={closeModal} parentCid={activeCid} />} {showReplyModal && activeCid && <ReplyModal closeModal={closeModal} parentCid={activeCid} scrollY={scrollY} />}
{feed.length > 0 && ( {feed.length > 0 && (
<> <>
{rules && rules.length > 0 && <SubplebbitRules subplebbitAddress={subplebbitAddress} createdAt={createdAt} rules={rules} />} {rules && rules.length > 0 && <SubplebbitRules subplebbitAddress={subplebbitAddress} createdAt={createdAt} rules={rules} />}
+2 -2
View File
@@ -22,7 +22,7 @@ const PostPage = () => {
const isInDescriptionView = isDescriptionView(location.pathname, params); const isInDescriptionView = isDescriptionView(location.pathname, params);
const isInRulesView = isRulesView(location.pathname, params); const isInRulesView = isRulesView(location.pathname, params);
const { showReplyModal, activeCid, openReplyModal, closeModal } = useReplyModal(); const { activeCid, closeModal, openReplyModal, showReplyModal, scrollY } = useReplyModal();
const post = useComment({ commentCid }); const post = useComment({ commentCid });
const { deleted, locked, removed } = post || {}; const { deleted, locked, removed } = post || {};
@@ -34,7 +34,7 @@ const PostPage = () => {
return ( return (
<div className={styles.content}> <div className={styles.content}>
{showReplyModal && activeCid && <ReplyModal closeModal={closeModal} parentCid={activeCid} />} {showReplyModal && activeCid && <ReplyModal closeModal={closeModal} parentCid={activeCid} scrollY={scrollY} />}
{isInDescriptionView ? ( {isInDescriptionView ? (
<SubplebbitDescription <SubplebbitDescription
avatarUrl={suggested?.avatarUrl} avatarUrl={suggested?.avatarUrl}