Avoid re-render glitches

When changing between languages, the transition between pages can
cause UI glitches, where text could change font for a brief second.

The fix makes the main content invisible by default, and applies the
'invisible' class just before switching languages. After the main
content has rendered, the 'invisible' class is removed. These changes
effectively remove the UI glitches that were present when switching
languages.
This commit is contained in:
0x1eef 2023-10-23 14:46:09 -03:00
parent 764cf6709c
commit 11bd1105fb
4 changed files with 26 additions and 4 deletions

View file

@ -86,3 +86,7 @@ body .root .content.ar {
font-size: xx-large; font-size: xx-large;
} }
} }
.invisible {
display: none !important;
}

View file

@ -20,6 +20,8 @@ export function LanguageSelect({ locale, path = "" }: Props) {
return `${path}/`; return `${path}/`;
} }
})(); })();
const content = document.querySelector(".content.theme");
content.classList.add("invisible");
location.replace(`/${locale}/${newPath}`); location.replace(`/${locale}/${newPath}`);
}} }}
> >

View file

@ -1,4 +1,4 @@
import React from "react"; import React, { useRef, useEffect } from "react";
import ReactDOM from "react-dom/client"; import ReactDOM from "react-dom/client";
import classNames from "classnames"; import classNames from "classnames";
@ -16,9 +16,17 @@ interface Props {
function SurahIndex({ locale, surahs, t }: Props) { function SurahIndex({ locale, surahs, t }: Props) {
const [theme, setTheme] = useTheme(); const [theme, setTheme] = useTheme();
const ref = useRef<HTMLDivElement>();
useEffect(() => {
if (ref.current) {
const div = ref.current;
div.classList.remove("invisible");
}
}, []);
return ( return (
<div className={classNames("content", "theme", theme, locale)}> <div ref={ref} className={classNames("invisible", "content", "theme", theme, locale)}>
<a href={`/${locale}/`} className="row title"> <a href={`/${locale}/`} className="row title">
{t(locale, "TheNobleQuran")} {t(locale, "TheNobleQuran")}
</a> </a>

View file

@ -1,4 +1,4 @@
import React, { useState, useEffect } from "react"; import React, { useState, useEffect, useRef } from "react";
import ReactDOM from "react-dom/client"; import ReactDOM from "react-dom/client";
import classNames from "classnames"; import classNames from "classnames";
@ -40,6 +40,14 @@ function SurahStream({ node, recitations, locale, paused, t }: Props) {
const readyToRender = stream.length > 0; const readyToRender = stream.length > 0;
const ayah = stream[stream.length - 1]; const ayah = stream[stream.length - 1];
const hasCompactLayout = ["ar"].includes(locale); const hasCompactLayout = ["ar"].includes(locale);
const ref = useRef<HTMLDivElement>();
useEffect(() => {
if (ref.current) {
const div = ref.current;
div.classList.remove("invisible");
}
}, []);
useEffect(() => { useEffect(() => {
setEndOfStream(false); setEndOfStream(false);
@ -47,7 +55,7 @@ function SurahStream({ node, recitations, locale, paused, t }: Props) {
}, [stream.length === 0]); }, [stream.length === 0]);
return ( return (
<div className={classNames("content", "theme", theme, locale)}> <div ref={ref} className={classNames("invisible", "content", "theme", theme, locale)}>
{readyToRender && ( {readyToRender && (
<> <>
<a href={`/${locale}/`} className="row title"> <a href={`/${locale}/`} className="row title">