src/js: add TheSurahPage.tsx
This commit is contained in:
parent
9b53401092
commit
8728c9df32
3 changed files with 104 additions and 0 deletions
31
src/js/components/TheQuran/Stream.tsx
Normal file
31
src/js/components/TheQuran/Stream.tsx
Normal file
|
@ -0,0 +1,31 @@
|
|||
import { Surah, Ayat, Ayah } from "lib/Quran"
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import classNames from "classnames";
|
||||
|
||||
type StreamProps = {
|
||||
surah: Surah,
|
||||
stream: Ayat
|
||||
}
|
||||
|
||||
export function Stream({surah, stream}: StreamProps) {
|
||||
const endOfStream = stream.length === surah.ayat.length;
|
||||
const ayat = stream.map((ayah: Ayah) => {
|
||||
return (
|
||||
<li key={ayah.num} className="ayah fade">
|
||||
<span>Surah 1, Ayah {ayah.num}</span>
|
||||
<p>{ayah.text}</p>
|
||||
</li>
|
||||
);
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
const el: HTMLElement = document.querySelector("ul.stream");
|
||||
el.scroll({top: el.offsetHeight, behavior: "smooth"});
|
||||
}, [stream]);
|
||||
|
||||
return (
|
||||
<ul className={classNames("stream", {"scroll-y": endOfStream})}>
|
||||
{ayat}
|
||||
</ul>
|
||||
);
|
||||
}
|
28
src/js/components/TheQuran/Timer.tsx
Normal file
28
src/js/components/TheQuran/Timer.tsx
Normal file
|
@ -0,0 +1,28 @@
|
|||
import React, { useEffect, useState } from "react";
|
||||
import { Quran, Surah, Ayah, Ayat } from "lib/Quran";
|
||||
|
||||
type TimerProps = {
|
||||
surah: Surah,
|
||||
ayah: Ayah,
|
||||
stream: Ayat,
|
||||
setStream: (stream: Ayat) => void
|
||||
};
|
||||
|
||||
export function Timer({surah, ayah, stream, setStream}: TimerProps) {
|
||||
const [ms, setMs] = useState(ayah.readingTime);
|
||||
useEffect(() => setMs(ayah.readingTime), [ayah]);
|
||||
useEffect(() => {
|
||||
if (stream.length === surah.ayat.length) {
|
||||
return;
|
||||
} else if (ms <= 0) {
|
||||
setStream([...stream, surah.ayat[ayah.num]]);
|
||||
} else {
|
||||
setTimeout(() => setMs(ms - 100), 100);
|
||||
}
|
||||
}, [ms]);
|
||||
return (
|
||||
<span className="timer">
|
||||
{(ms / 1000).toFixed(1)}
|
||||
</span>
|
||||
);
|
||||
}
|
45
src/js/pages/TheSurahPage.tsx
Normal file
45
src/js/pages/TheSurahPage.tsx
Normal file
|
@ -0,0 +1,45 @@
|
|||
import React, { useState, useEffect } from 'react';
|
||||
import ReactDOM from 'react-dom/client';
|
||||
import useSurah from "hooks/useSurah";
|
||||
import { Timer } from "components/TheQuran/Timer";
|
||||
import { Stream } from "components/TheQuran/Stream";
|
||||
import classNames from "classnames";
|
||||
|
||||
function TheSurahPage() {
|
||||
const [loading, surah] = useSurah("en", 1);
|
||||
const [stream, setStream] = useState([]);
|
||||
const [theme , setTheme] = useState("moon");
|
||||
|
||||
useEffect(() => {
|
||||
if (surah) {
|
||||
setStream([surah.ayat[stream.length]])
|
||||
}
|
||||
}, [surah]);
|
||||
|
||||
return (
|
||||
<div className={classNames(theme, "theme")}>
|
||||
<div className="flex-image">
|
||||
<div className="image"></div>
|
||||
</div>
|
||||
{stream.length &&
|
||||
<div className="flex-row">
|
||||
<span></span>
|
||||
<select name="theme" value={theme} onChange={(e) => setTheme(e.target.value)}>
|
||||
<option value="moon">The Moon 🌛</option>
|
||||
<option value="leaf">The Leaf 🌿</option>
|
||||
</select>
|
||||
<Timer
|
||||
surah={surah}
|
||||
ayah={surah.ayat[stream.length - 1]}
|
||||
setStream={setStream}
|
||||
stream={stream}
|
||||
/>
|
||||
</div>
|
||||
}
|
||||
{stream.length && <Stream surah={surah} stream={stream}/>}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
const root = ReactDOM.createRoot(document.querySelector(".surah"));
|
||||
root.render(<TheSurahPage/>);
|
Loading…
Reference in a new issue