diff --git a/src/js/components/TheSurahPage/LanguageSelect.tsx b/src/js/components/TheSurahPage/LanguageSelect.tsx index aa1bccebf..1fd1a366c 100644 --- a/src/js/components/TheSurahPage/LanguageSelect.tsx +++ b/src/js/components/TheSurahPage/LanguageSelect.tsx @@ -1,12 +1,12 @@ import React from 'react'; import { Select, SelectOption } from 'components/Select'; -import { Surah, Ayat } from 'lib/Quran'; +import * as Quran from 'lib/Quran'; import { Slice } from 'lib/Quran/Slice'; interface Props { locale: string - surah: Surah - stream: Ayat + surah: Quran.Surah + stream: Quran.Ayat isPaused: boolean slice: Slice } diff --git a/src/js/components/TheSurahPage/Stream.tsx b/src/js/components/TheSurahPage/Stream.tsx index a71a6b49f..d6d43a6f7 100644 --- a/src/js/components/TheSurahPage/Stream.tsx +++ b/src/js/components/TheSurahPage/Stream.tsx @@ -1,13 +1,13 @@ -import { Surah, Ayat, Ayah, Locale } from 'lib/Quran'; +import * as Quran from 'lib/Quran'; import React, { useEffect } from 'react'; import { numbers, strings } from 'lib/i18n'; import { Slice } from 'lib/Quran/Slice'; import classNames from 'classnames'; interface Props { - surah: Surah - stream: Ayat - locale: Locale + surah: Quran.Surah + stream: Quran.Ayat + locale: Quran.Locale slice: Slice endOfStream: boolean isPaused: boolean @@ -17,7 +17,7 @@ export function Stream({ surah, stream, locale, slice, endOfStream, isPaused }: const n = numbers(locale); const s = strings(locale); const className = classNames('stream', { 'scroll-y': endOfStream || isPaused }); - const ayat = stream.map((ayah: Ayah) => { + const ayat = stream.map((ayah: Quran.Ayah) => { return (
  • diff --git a/src/js/components/TheSurahPage/Timer.tsx b/src/js/components/TheSurahPage/Timer.tsx index e312ba056..10ff6bf04 100644 --- a/src/js/components/TheSurahPage/Timer.tsx +++ b/src/js/components/TheSurahPage/Timer.tsx @@ -1,12 +1,12 @@ import React, { useEffect, useState } from 'react'; -import { Surah, Ayat, Locale } from 'lib/Quran'; +import * as Quran from 'lib/Quran'; import { numberToDecimal } from 'lib/i18n'; interface Props { - surah: Surah - locale: Locale - stream: Ayat - setStream: (stream: Ayat) => void + surah: Quran.Surah + locale: Quran.Locale + stream: Quran.Ayat + setStream: (stream: Quran.Ayat) => void isPaused: boolean } diff --git a/src/js/lib/Quran.ts b/src/js/lib/Quran.ts index a69999236..acdfd16ba 100644 --- a/src/js/lib/Quran.ts +++ b/src/js/lib/Quran.ts @@ -1,4 +1,8 @@ -import { Surah, Ayah, Ayat } from './Quran/Surah'; -const Quran = { Surah }; +import * as JSON from "lib/Quran/JSON"; +import { Surah, IDObject } from "lib/Quran/Surah"; + type Locale = 'ar' | 'en'; -export { Quran, Surah, Ayah, Ayat, Locale }; +type Ayah = {id: IDObject, text: string, readTimeMs: number }; +type Ayat = Ayah[]; + +export { Surah, Ayah, Ayat, Locale, JSON }; diff --git a/src/js/lib/Quran/JSON.ts b/src/js/lib/Quran/JSON.ts new file mode 100644 index 000000000..48b30c93c --- /dev/null +++ b/src/js/lib/Quran/JSON.ts @@ -0,0 +1,12 @@ +type Surah = { + id: string + place_of_revelation: string + transliterated_name: string + translated_name: string + verse_count: number + slug: string + codepoints: number[] +} +type Ayah = [number, string]; +type Ayat = Ayah[]; +export { Surah, Ayah, Ayat }; diff --git a/src/js/lib/Quran/Surah.ts b/src/js/lib/Quran/Surah.ts index ef72a5b14..d960b57ba 100644 --- a/src/js/lib/Quran/Surah.ts +++ b/src/js/lib/Quran/Surah.ts @@ -1,41 +1,23 @@ -import { Locale } from 'lib/Quran'; +import * as Quran from 'lib/Quran'; import { DelayBaseLine, DelayPerWord } from 'lib/i18n'; -export type Ayat = Ayah[]; - -interface SurahDetails { - id: string - place_of_revelation: string - transliterated_name: string - translated_name: string - verse_count: number - slug: string - codepoints: number[] -} - -export interface Ayah { - id: IDObject - text: string - readTimeMs: number -} - -interface IDObject { +export interface IDObject { number: number localeKey: string[] } export class Surah { - #details: SurahDetails; - ayat: Ayat; + #surah: Quran.JSON.Surah; + ayat: Quran.Ayat; - static fromDOMNode(locale: Locale, node: HTMLScriptElement) { + static fromDOMNode(locale: Quran.Locale, node: HTMLScriptElement) { const json = JSON.parse(node.innerText); return Surah.fromJSON(locale, json.shift(), json); } - static fromJSON(locale: Locale, details: SurahDetails, ayat: Array<[number, string]>): Surah { + static fromJSON(locale: Quran.Locale, surah: Quran.JSON.Surah, ayat: Quran.JSON.Ayat) { return new Surah( - details, + surah, ayat.map(([id, text]) => { return { id: { number: id, localeKey: String(id).split('') }, @@ -46,39 +28,39 @@ export class Surah { ); } - constructor(details: SurahDetails, ayat: Ayat) { - this.#details = details; + constructor(surah: Quran.JSON.Surah, ayat: Quran.Ayat) { + this.#surah = surah; this.ayat = ayat; } get id(): IDObject { return { - number: Number(this.#details.id), - localeKey: this.#details.id.split('') + number: Number(this.#surah.id), + localeKey: this.#surah.id.split('') }; } get name() { - return String.fromCodePoint(...this.#details.codepoints); + return String.fromCodePoint(...this.#surah.codepoints); } get transliteratedName() { - return this.#details.transliterated_name; + return this.#surah.transliterated_name; } get translatedName() { - return this.#details.translated_name; + return this.#surah.translated_name; } get placeOfRevelation() { - return this.#details.place_of_revelation; + return this.#surah.place_of_revelation; } get numberOfAyah() { - return this.#details.verse_count; + return this.#surah.verse_count; } get slug() { - return this.#details.slug; + return this.#surah.slug; } } diff --git a/src/js/pages/TheSurahPage.tsx b/src/js/pages/TheSurahPage.tsx index 3b7abaf5f..f22a12712 100644 --- a/src/js/pages/TheSurahPage.tsx +++ b/src/js/pages/TheSurahPage.tsx @@ -7,11 +7,11 @@ import { Stream } from 'components/TheSurahPage/Stream'; import { ThemeSelect } from 'components/TheSurahPage/ThemeSelect'; import { LanguageSelect } from 'components/TheSurahPage/LanguageSelect'; import { PlayShape, PauseShape } from 'components/TheSurahPage/Shape'; -import { Locale, Surah } from 'lib/Quran'; +import * as Quran from 'lib/Quran'; import { Slice } from 'lib/Quran/Slice'; interface Props { - locale: Locale + locale: Quran.Locale surahId: number slice: Slice paused: boolean @@ -23,7 +23,7 @@ function TheSurahPage({ locale, surahId, slice, paused }: Props) { const [stream, setStream] = useState([]); const [isPaused, setIsPaused] = useState(paused); const [theme, setTheme] = useState(getCookie('theme') || 'moon'); - const [surah] = useState(Surah.fromDOMNode(locale, node)); + const [surah] = useState(Quran.Surah.fromDOMNode(locale, node)); const readyToRender = stream.length > 0; const surahName = locale === 'ar' ? surah.name : surah.translatedName; const endOfStream = (function() { @@ -102,7 +102,7 @@ function TheSurahPage({ locale, surahId, slice, paused }: Props) { (function() { const toBoolean = (str: string | null): boolean => ['1', 't', 'true', 'yes'].includes(str); const root: HTMLElement = document.querySelector('.root'); - const locale = root.getAttribute('data-locale') as Locale; + const locale = root.getAttribute('data-locale') as Quran.Locale; const surahId = parseInt(root.getAttribute('data-surah-id')); const params = new URLSearchParams(location.search); const slice = Slice.fromParam(params.get('ayah'));