fix: post content vertical scroll issue
This commit is contained in:
committed by
Mehak Nasir
parent
59740948c5
commit
de81833f9a
@@ -1,5 +1,7 @@
|
||||
/* eslint-disable import/prefer-default-export */
|
||||
import { useContext, useEffect, useRef } from 'react';
|
||||
import {
|
||||
useContext, useEffect, useRef, useState,
|
||||
} from 'react';
|
||||
|
||||
import { useDispatch, useSelector } from 'react-redux';
|
||||
import { useHistory, useLocation, useRouteMatch } from 'react-router';
|
||||
@@ -13,7 +15,7 @@ import { fetchCourseBlocks } from '../../data/thunks';
|
||||
import { clearRedirect } from '../posts/data';
|
||||
import { selectTopics } from '../topics/data/selectors';
|
||||
import { fetchCourseTopics } from '../topics/data/thunks';
|
||||
import { discussionsPath, postMessageToParent } from '../utils';
|
||||
import { discussionsPath } from '../utils';
|
||||
import {
|
||||
selectAreThreadsFiltered, selectLearnersTabEnabled,
|
||||
selectModerationSettings,
|
||||
@@ -99,58 +101,37 @@ export function useIsOnXLDesktop() {
|
||||
return windowSize.width >= breakpoints.extraLarge.minWidth;
|
||||
}
|
||||
|
||||
/**
|
||||
* Given an element this attempts to get the height of the entire UI.
|
||||
*
|
||||
* @param element
|
||||
* @returns {number}
|
||||
*/
|
||||
function getOuterHeight(element) {
|
||||
// This is the height of the entire document body.
|
||||
const bodyHeight = document.body.offsetHeight;
|
||||
// This is the height of the container that will scroll.
|
||||
const elementContainerHeight = element.parentNode.clientHeight;
|
||||
// The difference between the body height and the container height is the size of the header footer etc.
|
||||
// Add to that the element's own height and we get the size the UI should be to fit everything.
|
||||
return bodyHeight - elementContainerHeight + element.scrollHeight + 10;
|
||||
}
|
||||
|
||||
/**
|
||||
* This hook posts a resize message to the parent window if running in an iframe
|
||||
* @param refContainer reference to the component whose size is to be measured
|
||||
*/
|
||||
export function useContainerSizeForParent(refContainer) {
|
||||
function postResizeMessage(height) {
|
||||
postMessageToParent('plugin.resize', { height });
|
||||
}
|
||||
|
||||
const location = useLocation();
|
||||
const enabled = window.parent !== window;
|
||||
const [height, setHeight] = useState();
|
||||
|
||||
const resizeObserver = useRef(new ResizeObserver(() => {
|
||||
/* istanbul ignore if: ResizeObserver isn't available in the testing env */
|
||||
if (refContainer.current) {
|
||||
postResizeMessage(getOuterHeight(refContainer.current));
|
||||
setHeight(refContainer.current.clientHeight);
|
||||
}
|
||||
}));
|
||||
|
||||
useEffect(() => {
|
||||
const container = refContainer.current;
|
||||
const observer = resizeObserver.current;
|
||||
if (container && observer && enabled) {
|
||||
if (container && observer) {
|
||||
observer.observe(container);
|
||||
postResizeMessage(getOuterHeight(container));
|
||||
setHeight(container.clientHeight);
|
||||
}
|
||||
|
||||
return () => {
|
||||
if (container && observer && enabled) {
|
||||
if (container && observer) {
|
||||
observer.unobserve(container);
|
||||
// Send a message to reset the size so that navigating to another
|
||||
// page doesn't cause the size to be retained
|
||||
postResizeMessage(null);
|
||||
}
|
||||
};
|
||||
}, [refContainer, resizeObserver, location]);
|
||||
|
||||
return height;
|
||||
}
|
||||
|
||||
export const useAlertBannerVisible = (content) => {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import React, { useContext, useRef } from 'react';
|
||||
import React, { useContext } from 'react';
|
||||
|
||||
import { useSelector } from 'react-redux';
|
||||
import { Route, Switch } from 'react-router';
|
||||
@@ -11,7 +11,7 @@ import { ArrowBack } from '@edx/paragon/icons';
|
||||
import { PostsPages, Routes } from '../../data/constants';
|
||||
import { CommentsView } from '../comments';
|
||||
import { DiscussionContext } from '../common/context';
|
||||
import { useContainerSizeForParent, useIsOnDesktop } from '../data/hooks';
|
||||
import { useIsOnDesktop } from '../data/hooks';
|
||||
import messages from '../messages';
|
||||
import { PostEditor } from '../posts';
|
||||
import { discussionsPath } from '../utils';
|
||||
@@ -19,17 +19,15 @@ import { discussionsPath } from '../utils';
|
||||
function DiscussionContent({ intl }) {
|
||||
const location = useLocation();
|
||||
const history = useHistory();
|
||||
const refContainer = useRef(null);
|
||||
const postEditorVisible = useSelector((state) => state.threads.postEditorVisible);
|
||||
const isOnDesktop = useIsOnDesktop();
|
||||
const {
|
||||
courseId, learnerUsername, category, topicId, page,
|
||||
} = useContext(DiscussionContext);
|
||||
useContainerSizeForParent(refContainer);
|
||||
|
||||
return (
|
||||
<div className="d-flex bg-light-400 flex-column w-75 w-xs-100 w-xl-75 align-items-center h-100 overflow-auto">
|
||||
<div className="d-flex flex-column w-100" ref={refContainer}>
|
||||
<div className="d-flex bg-light-400 flex-column w-75 w-xs-100 w-xl-75 align-items-center">
|
||||
<div className="d-flex flex-column w-100">
|
||||
{!isOnDesktop && (
|
||||
<IconButton
|
||||
src={ArrowBack}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import React from 'react';
|
||||
import React, { useEffect, useRef } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import classNames from 'classnames';
|
||||
@@ -8,23 +8,39 @@ import {
|
||||
} from 'react-router';
|
||||
|
||||
import { RequestStatus, Routes } from '../../data/constants';
|
||||
import { useIsOnDesktop, useIsOnXLDesktop, useShowLearnersTab } from '../data/hooks';
|
||||
import {
|
||||
useContainerSizeForParent, useIsOnDesktop, useIsOnXLDesktop, useShowLearnersTab,
|
||||
} from '../data/hooks';
|
||||
import { selectconfigLoadingStatus } from '../data/selectors';
|
||||
import { LearnerPostsView, LearnersView } from '../learners';
|
||||
import { PostsView } from '../posts';
|
||||
import { TopicsView } from '../topics';
|
||||
|
||||
export default function DiscussionSidebar({ displaySidebar }) {
|
||||
export default function DiscussionSidebar({ displaySidebar, postActionBarRef }) {
|
||||
const location = useLocation();
|
||||
const isOnDesktop = useIsOnDesktop();
|
||||
const isOnXLDesktop = useIsOnXLDesktop();
|
||||
const configStatus = useSelector(selectconfigLoadingStatus);
|
||||
const redirectToLearnersTab = useShowLearnersTab();
|
||||
const sidebarRef = useRef(null);
|
||||
const postActionBarHeight = useContainerSizeForParent(postActionBarRef);
|
||||
|
||||
useEffect(() => {
|
||||
if (sidebarRef && postActionBarHeight) {
|
||||
if (isOnDesktop) {
|
||||
sidebarRef.current.style.maxHeight = `${document.body.offsetHeight - postActionBarHeight}px`;
|
||||
}
|
||||
sidebarRef.current.style.minHeight = `${document.body.offsetHeight - postActionBarHeight}px`;
|
||||
sidebarRef.current.style.top = `${postActionBarHeight}px`;
|
||||
}
|
||||
}, [sidebarRef, postActionBarHeight]);
|
||||
|
||||
return (
|
||||
<div
|
||||
className={classNames('flex-column', {
|
||||
ref={sidebarRef}
|
||||
className={classNames('flex-column min-content-height position-sticky', {
|
||||
'd-none': !displaySidebar,
|
||||
'd-flex h-100 overflow-auto': displaySidebar,
|
||||
'd-flex overflow-auto': displaySidebar,
|
||||
'w-100': !isOnDesktop,
|
||||
'sidebar-desktop-width': isOnDesktop && !isOnXLDesktop,
|
||||
'w-25 sidebar-XL-width': isOnXLDesktop,
|
||||
@@ -60,8 +76,13 @@ export default function DiscussionSidebar({ displaySidebar }) {
|
||||
|
||||
DiscussionSidebar.defaultProps = {
|
||||
displaySidebar: false,
|
||||
postActionBarRef: null,
|
||||
};
|
||||
|
||||
DiscussionSidebar.propTypes = {
|
||||
displaySidebar: PropTypes.bool,
|
||||
postActionBarRef: PropTypes.oneOfType([
|
||||
PropTypes.func,
|
||||
PropTypes.shape({ current: PropTypes.instanceOf(Element) }),
|
||||
]),
|
||||
};
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import React, { useEffect } from 'react';
|
||||
import React, { useEffect, useRef } from 'react';
|
||||
|
||||
import { useSelector } from 'react-redux';
|
||||
import {
|
||||
@@ -26,6 +26,7 @@ import InformationBanner from './InformationsBanner';
|
||||
|
||||
export default function DiscussionsHome() {
|
||||
const location = useLocation();
|
||||
const postActionBarRef = useRef(null);
|
||||
const postEditorVisible = useSelector(
|
||||
(state) => state.threads.postEditorVisible,
|
||||
);
|
||||
@@ -82,10 +83,10 @@ export default function DiscussionsHome() {
|
||||
}}
|
||||
>
|
||||
{!inIframe && <Header courseOrg={org} courseNumber={courseNumber} courseTitle={courseTitle} />}
|
||||
<main className="container-fluid d-flex flex-column p-0 h-100 w-100 overflow-hidden" id="main" tabIndex="-1">
|
||||
<main className="container-fluid d-flex flex-column p-0 w-100" id="main" tabIndex="-1">
|
||||
{!inIframe
|
||||
&& <CourseTabsNavigation activeTab="discussion" courseId={courseId} />}
|
||||
<div style={{ zIndex: 1, boxShadow: '0px 2px 4px rgb(0 0 0 / 15%), 0px 2px 8px rgb(0 0 0 / 15%)' }}>
|
||||
<div className="header-action-bar" ref={postActionBarRef}>
|
||||
<div
|
||||
className="d-flex flex-row justify-content-between navbar fixed-top"
|
||||
>
|
||||
@@ -100,8 +101,8 @@ export default function DiscussionsHome() {
|
||||
path={[Routes.POSTS.PATH, Routes.TOPICS.CATEGORY]}
|
||||
component={provider === DiscussionProvider.LEGACY ? LegacyBreadcrumbMenu : BreadcrumbMenu}
|
||||
/>
|
||||
<div className="d-flex flex-row overflow-hidden flex-grow-1 h-100">
|
||||
<DiscussionSidebar displaySidebar={displaySidebar} />
|
||||
<div className="d-flex flex-row">
|
||||
<DiscussionSidebar displaySidebar={displaySidebar} postActionBarRef={postActionBarRef} />
|
||||
{displayContentArea && <DiscussionContent />}
|
||||
{!displayContentArea && (
|
||||
<Switch>
|
||||
|
||||
@@ -15,7 +15,7 @@ function EmptyPage({
|
||||
fullWidth = false,
|
||||
}) {
|
||||
const containerClasses = classNames(
|
||||
'justify-content-center align-items-center d-flex w-100 flex-column pt-5',
|
||||
'min-content-height justify-content-center align-items-center d-flex w-100 flex-column pt-5',
|
||||
{ 'bg-light-400': !fullWidth },
|
||||
);
|
||||
|
||||
|
||||
@@ -220,3 +220,15 @@ header {
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
.min-content-height {
|
||||
min-height: 80vh;
|
||||
}
|
||||
|
||||
.header-action-bar {
|
||||
background-color: #fff;
|
||||
z-index: 1;
|
||||
box-shadow: 0px 2px 4px rgb(0 0 0 / 15%), 0px 2px 8px rgb(0 0 0 / 15%);
|
||||
position: sticky;
|
||||
top: 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user