Synchronize ?ayah=x parameter on language change

When given - for example, `?ayah=5` and then the language is
changed at ayah 7, the "ayah" parameter should be updated to 7.

Fix #85
This commit is contained in:
0x1eef 2023-03-13 20:20:35 -03:00
parent 9f9e861922
commit ae2f4f23c5
2 changed files with 26 additions and 20 deletions

View file

@ -1,36 +1,35 @@
export interface Slice { export interface Slice {
begin: number begin: number
end: number end: number | null
length: number
coversOneAyah: boolean coversOneAyah: boolean
coversOneSurah: boolean coversOneSurah: boolean
coversSubsetOfSurah: boolean coversSubsetOfSurah: boolean
subsetLength: number
toParam: () => string | null toParam: () => string | null
} }
export function Slice(begin: number, end: number): Slice { export function Slice(begin: number, end: number | null): Slice {
const self: Slice = Object.create(null); const self: Slice = Object.create(null);
self.begin = begin; self.begin = begin;
self.end = end; self.end = end;
self.coversOneAyah = begin === end; self.coversOneAyah = end === null;
self.coversOneSurah = begin === 1 && end === 286; self.coversOneSurah = begin === 1 && end === 286;
self.coversSubsetOfSurah = begin >= 1 && end < 286; self.coversSubsetOfSurah = end !== null && begin >= 1 && end < 286;
self.length = end - (begin - 1); self.subsetLength = getSubsetLength(self);
self.toParam = () => {
if (self.coversOneAyah) {
return `${self.begin}`;
} else if(self.coversSubsetOfSurah) {
return `${self.begin}..${self.end}`;
} else {
return null;
}
};
return self; return self;
} }
const getSubsetLength = (slice: Slice) => {
const { begin, end } = slice;
if (end) {
return end - (begin - 1);
} else {
return 0;
}
};
const digitsRange = /^(\d{1,3})\.\.(\d{1,3})$/; const digitsRange = /^(\d{1,3})\.\.(\d{1,3})$/;
const digits = /^\d{1,3}$/; const digits = /^\d{1,3}$/;
Slice.fromParam = function(param: string | null): Slice { Slice.fromParam = function(param: string | null): Slice {
@ -42,7 +41,7 @@ Slice.fromParam = function(param: string | null): Slice {
const [, begin, end] = match; const [, begin, end] = match;
return Slice(parseInt(begin), parseInt(end)); return Slice(parseInt(begin), parseInt(end));
} else if (digits.test(param)) { } else if (digits.test(param)) {
return Slice(parseInt(param), parseInt(param)); return Slice(parseInt(param), null);
} else { } else {
return Slice(1, 286); return Slice(1, 286);
} }

View file

@ -26,10 +26,17 @@ function SurahStream({ node, locale, slice, paused, t }: Props) {
const [theme, setTheme] = useState(getCookie('theme') || 'moon'); const [theme, setTheme] = useState(getCookie('theme') || 'moon');
const [surah] = useState<Quran.Surah>(Quran.Surah.fromDOMNode(locale, node)); const [surah] = useState<Quran.Surah>(Quran.Surah.fromDOMNode(locale, node));
const readyToRender = stream.length > 0; const readyToRender = stream.length > 0;
const getAyahParam = (slice: Slice, stream: Quran.Ayat) => {
if(slice.coversSubsetOfSurah) {
return `${slice.begin}..${slice.end}`;
} else {
return stream.length;
}
};
const onLanguageChange = (o: SelectOption) => { const onLanguageChange = (o: SelectOption) => {
const locale = o.value; const locale = o.value;
const params = [ const params = [
['ayah', slice.toParam() || stream.length], ['ayah', getAyahParam(slice, stream)],
['paused', isPaused ? 't' : null] ['paused', isPaused ? 't' : null]
]; ];
const query = params.filter(([, v]) => v).flatMap(([k,v]) => `${k}=${v}`).join('&'); const query = params.filter(([, v]) => v).flatMap(([k,v]) => `${k}=${v}`).join('&');
@ -39,7 +46,7 @@ function SurahStream({ node, locale, slice, paused, t }: Props) {
if (slice.coversOneAyah || slice.coversOneSurah) { if (slice.coversOneAyah || slice.coversOneSurah) {
return stream.length === surah.ayat.length; return stream.length === surah.ayat.length;
} else if (slice.coversSubsetOfSurah) { } else if (slice.coversSubsetOfSurah) {
return stream.length === slice.length; return stream.length === slice.subsetLength;
} else { } else {
return false; return false;
} }
@ -47,7 +54,7 @@ function SurahStream({ node, locale, slice, paused, t }: Props) {
useEffect(() => { useEffect(() => {
if (slice.coversOneAyah) { if (slice.coversOneAyah) {
setStream([...surah.ayat.slice(0, slice.end)]); setStream([...surah.ayat.slice(0, slice.begin)]);
} else { } else {
setStream([surah.ayat[slice.begin - 1]]); setStream([surah.ayat[slice.begin - 1]]);
} }