Compare commits

...

4 Commits

Author SHA1 Message Date
adeel.tajamul
65a5fa2e37 fix: copy link not working in in-context discussion 2023-02-16 12:10:12 +05:00
Mehak Nasir
f8800de766 feat: added delay in post preview to avoid flashing of content 2023-02-15 17:06:48 +05:00
ayesha waris
f7740de54a fix: topic info is fixed from posts in incontext discussions (#433) 2023-02-14 18:17:53 +05:00
Mehak Nasir
4ca25c14d9 fix: restrict tiny mce from converting url 2023-02-14 17:35:37 +05:00
4 changed files with 35 additions and 9 deletions

View File

@@ -5,6 +5,8 @@ import DOMPurify from 'dompurify';
import { logError } from '@edx/frontend-platform/logging';
import { useDebounce } from '../discussions/data/hooks';
const defaultSanitizeOptions = {
USE_PROFILES: { html: true },
ADD_ATTR: ['columnalign'],
@@ -16,19 +18,21 @@ function HTMLLoader({
const sanitizedMath = DOMPurify.sanitize(htmlNode, { ...defaultSanitizeOptions });
const previewRef = useRef();
const debouncedPostContent = useDebounce(htmlNode, 500);
useEffect(() => {
let promise = Promise.resolve(); // Used to hold chain of typesetting calls
function typeset(code) {
promise = promise.then(() => window.MathJax?.typesetPromise(code()))
.catch((err) => logError(`Typeset failed: ${err.message}`));
return promise;
}
typeset(() => {
previewRef.current.innerHTML = sanitizedMath;
});
}, [htmlNode]);
if (debouncedPostContent) {
typeset(() => {
previewRef.current.innerHTML = sanitizedMath;
});
}
}, [debouncedPostContent]);
return (
<div ref={previewRef} className={cssClassName} id={componentId} data-testid={testId} />

View File

@@ -119,6 +119,7 @@ export default function TinyMCEEditor(props) {
content_css: false,
content_style: contentStyle,
body_class: 'm-2 text-editor',
convert_urls: false,
relative_urls: false,
default_link_target: '_blank',
target_list: false,

View File

@@ -224,3 +224,24 @@ export const useTourConfiguration = (intl) => {
}
));
};
export const useDebounce = (value, delay) => {
// State and setters for debounced value
const [debouncedValue, setDebouncedValue] = useState(value);
useEffect(
() => {
// Update debounced value after delay
const handler = setTimeout(() => {
setDebouncedValue(value);
}, delay);
// Cancel the timeout if value changes (also on delay change or unmount)
// This is how we prevent debounced value from updating if value is changed ...
// .. within the delay period. Timeout gets cleared and restarted.
return () => {
clearTimeout(handler);
};
},
[value, delay], // Only re-call effect if value or delay changes
);
return debouncedValue;
};

View File

@@ -33,7 +33,7 @@ function Post({
const history = useHistory();
const dispatch = useDispatch();
const { enableInContextSidebar } = useContext(DiscussionContext);
const { courseId } = useSelector((state) => state.courseTabs);
const courseId = useSelector((state) => state.config.id);
const topic = useSelector(selectTopic(post.topicId));
const getTopicSubsection = useSelector(selectorForUnitSubsection);
const topicContext = useSelector(selectTopicContext(post.topicId));
@@ -126,7 +126,7 @@ function Post({
<div className="d-flex mt-14px text-break font-style text-primary-500">
<HTMLLoader htmlNode={post.renderedBody} componentId="post" cssClassName="html-loader" testId={post.id} />
</div>
{topicContext && topic && (
{topicContext && (
<div
className={classNames('mt-14px mb-1 font-style font-size-12',
{ 'w-100': enableInContextSidebar })}
@@ -137,7 +137,7 @@ function Post({
destination={topicContext.unitLink}
target="_top"
>
{enableInContextSidebar
{(topicContext && !topic)
? (
<>
<span className="w-auto">{topicContext.chapterName}</span>