Skip to content

Commit 0439881

Browse files
authored
added mushaf & supplication link in quran nav modal, added hash based routing, major code refactoring (#208)
1 parent da34431 commit 0439881

40 files changed

+1005
-1364
lines changed

src/app.html

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,14 +46,26 @@
4646

4747
<!-- set the website theme - we put this code here to avoid the white flash and making people go blind -->
4848
<script>
49+
// Declare the theme variable
4950
let theme;
5051

5152
try {
52-
theme = JSON.parse(localStorage.getItem('userSettings')).displaySettings.websiteTheme;
53+
// Try to retrieve the user settings from localStorage and parse the JSON string
54+
const userSettings = JSON.parse(localStorage.getItem('userSettings'));
55+
56+
// Check if displaySettings and websiteTheme exist in the parsed object
57+
if (userSettings && userSettings.displaySettings && userSettings.displaySettings.websiteTheme !== undefined) {
58+
theme = userSettings.displaySettings.websiteTheme;
59+
} else {
60+
// Default theme in case the properties don't exist
61+
theme = 1;
62+
}
5363
} catch (error) {
64+
// If there's an error during JSON parsing or any other issue, fallback to default theme
5465
theme = 1;
5566
}
5667

68+
// Apply the theme class to the document's root element
5769
document.documentElement.classList = `theme-${theme} ${window.bodyColors[theme]}`;
5870
</script>
5971
%sveltekit.head%

src/components/display/morphology/Table.svelte

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,14 @@
1414
const loadAll = params.get('load_all') === 'true';
1515
const totalAvailableWords = Object.keys(wordData).length;
1616
const maxResultsToLoad = 50;
17-
let lastWordToLoad = loadAll ? totalAvailableWords : totalAvailableWords > maxResultsToLoad ? maxResultsToLoad : totalAvailableWords;
17+
let lastWordToLoad = calculateInitialLastWordToLoad(loadAll, totalAvailableWords, maxResultsToLoad);
18+
19+
function calculateInitialLastWordToLoad(loadAll, totalAvailableWords, maxResultsToLoad) {
20+
return loadAll ? totalAvailableWords : Math.min(totalAvailableWords, maxResultsToLoad);
21+
}
1822
1923
function updateLastWordToLoad() {
20-
lastWordToLoad = lastWordToLoad + 50;
21-
if (lastWordToLoad > totalAvailableWords) {
22-
lastWordToLoad = totalAvailableWords;
23-
}
24+
lastWordToLoad = Math.min(lastWordToLoad + 50, totalAvailableWords);
2425
}
2526
</script>
2627

src/components/display/verses/VerseOptionButtons.svelte

Lines changed: 39 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -16,44 +16,60 @@
1616
import { term } from '$utils/terminologies';
1717
import { quranMetaData } from '$data/quranMeta';
1818
19-
const chapter = +key.split(':')[0];
20-
const verse = +key.split(':')[1];
19+
const chapter = parseInt(key.split(':')[0], 10);
20+
const verse = parseInt(key.split(':')[1], 10);
2121
const versesInChapter = quranMetaData[chapter].verses;
2222
const buttonClasses = 'inline-flex items-center justify-center w-10 h-10 transition-colors duration-150 rounded-3xl focus:shadow-outline hover:bg-lightGray print:hidden';
2323
24-
// for chapter page, just show the key, else show the complete chapter transliteration & key
24+
// For chapter page, just show the key, else show the complete chapter transliteration & key
2525
$: verseKeyClasses = `${buttonClasses} w-fit px-4 bg-lightGray font-medium`;
2626
27-
// update userBookmarks whenever the __userSettings changes
27+
// Update userBookmarks whenever the __userSettings changes
2828
$: userBookmarks = JSON.parse($__userSettings).userBookmarks;
2929
3030
function audioHandler(key) {
31-
// stop any audio if something is playing
32-
if ($__audioSettings.isPlaying) resetAudioSettings({ location: 'end' });
33-
// else continue with playing options
34-
else {
35-
// for chapter & mushaf page, respect the user select play button functionality
31+
// Stop any audio if something is playing
32+
if ($__audioSettings.isPlaying) {
33+
resetAudioSettings({ location: 'end' });
34+
} else {
35+
// For chapter & mushaf page, respect the user select play button functionality
3636
if (['chapter', 'mushaf'].includes($__currentPage)) {
37-
// 1. Play selected Ayah (default)
38-
if ($__playButtonsFunctionality.verse === 1) playVerseAudio({ key, language: 'arabic', timesToRepeat: 1 });
39-
// 2. Play from here
40-
else if ($__playButtonsFunctionality.verse === 2) {
41-
setVersesToPlay({ location: 'verseOptionsOrModal', chapter: chapter, startVerse: verse, endVerse: versesInChapter, audioRange: 'playFromHere' });
42-
playVerseAudio({ key: `${window.versesToPlayArray[0]}`, timesToRepeat: 1, language: 'arabic' });
43-
}
44-
45-
// 3. Open Advance Play modal
46-
else if ($__playButtonsFunctionality.verse === 3) showAudioModal(key);
37+
handleAudioPlayOptions(key);
38+
} else {
39+
playVerseAudio({ key, language: 'arabic', timesToRepeat: 1 });
4740
}
41+
}
42+
}
43+
44+
function handleAudioPlayOptions(key) {
45+
const { verse } = $__playButtonsFunctionality;
4846
49-
// for any other page, stick to default
50-
else playVerseAudio({ key, language: 'arabic', timesToRepeat: 1 });
47+
switch (verse) {
48+
case 1:
49+
playVerseAudio({ key, language: 'arabic', timesToRepeat: 1 });
50+
break;
51+
case 2:
52+
setVersesToPlay({
53+
location: 'verseOptionsOrModal',
54+
chapter,
55+
startVerse: verse,
56+
endVerse: versesInChapter,
57+
audioRange: 'playFromHere'
58+
});
59+
playVerseAudio({ key: `${window.versesToPlayArray[0]}`, timesToRepeat: 1, language: 'arabic' });
60+
break;
61+
case 3:
62+
showAudioModal(key);
63+
break;
64+
default:
65+
playVerseAudio({ key, language: 'arabic', timesToRepeat: 1 });
66+
break;
5167
}
5268
}
5369
54-
// function to toggle words block for display mode #7
70+
// Function to toggle words block for display mode #7
5571
function wordsBlockToggler(verse) {
56-
document.querySelectorAll(`#verse-${verse}-words`)[0].classList.toggle('hidden');
72+
document.querySelector(`#verse-${verse}-words`).classList.toggle('hidden');
5773
}
5874
</script>
5975

src/components/display/verses/VerseOptionsDropdown.svelte

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,26 +13,29 @@
1313
const dropdownItemClasses = 'font-normal rounded-3xl hover:bg-black/5';
1414
let dropdownOpen = false;
1515
16-
// we need to manually add and/or remove z-index from the verse options dropdown because it becomes transparent due to our themes which we achieve via CSS filters
17-
// we remove z-index from all button blocks, and add it to button block of verse for which the dropdown was opened
18-
$: {
16+
// We need to manually add and/or remove z-index from the verse options dropdown because it becomes transparent due to our themes which we achieve via CSS filters
17+
// We remove z-index from all button blocks, and add it to the button block of the verse for which the dropdown was opened
18+
$: updateZIndex($__verseKey);
19+
20+
function updateZIndex(verseKey) {
1921
try {
2022
if (dropdownOpen) {
2123
document.querySelectorAll('.verseButtons').forEach((element) => {
2224
element.classList.remove('z-10');
2325
});
24-
document.getElementById($__verseKey).firstChild.classList.add('z-10');
26+
document.getElementById(verseKey).firstChild.classList.add('z-10');
2527
}
26-
} catch (error) {}
28+
} catch (error) {
29+
// console.error('Error updating z-index:', error);
30+
}
2731
}
2832
29-
// update userBookmarks whenever the __userSettings changes
33+
// Update userBookmarks whenever the __userSettings changes
3034
$: userBookmarks = JSON.parse($__userSettings).userBookmarks;
3135
32-
// open share menu
36+
// Open share menu
3337
function shareVerse() {
34-
const chapter = +$__verseKey.split(':')[0];
35-
const verse = +$__verseKey.split(':')[1];
38+
const [chapter, verse] = $__verseKey.split(':').map(Number);
3639
3740
if (navigator.share) {
3841
navigator.share({

src/components/display/verses/WordsBlock.svelte

Lines changed: 28 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,4 @@
11
<script>
2-
export let key;
3-
export let value;
4-
export let line = null;
5-
export let exampleVerse = false;
6-
72
import VerseOptionsDropdown from '$display/verses/VerseOptionsDropdown.svelte';
83
import Word from '$display/verses/Word.svelte';
94
import Tooltip from '$ui/FlowbiteSvelte/tooltip/Tooltip.svelte';
@@ -15,48 +10,52 @@
1510
import { updateSettings } from '$utils/updateSettings';
1611
import { mushafWordFontLink, mushafFontVersion } from '$data/websiteSettings';
1712
18-
const fontSizes = JSON.parse($__userSettings).displaySettings.fontSizes;
13+
export let key;
14+
export let value;
15+
export let line = null;
16+
export let exampleVerse = false;
1917
18+
const fontSizes = JSON.parse($__userSettings).displaySettings.fontSizes;
2019
$: displayIsContinuous = selectableDisplays[$__displayType].continuous;
2120
22-
// if mushaf fonts are selected, then dynamically load the fonts
21+
// Dynamically load the fonts if mushaf fonts are selected
2322
if ([2, 3].includes($__fontType)) {
2423
loadFont(`p${value.meta.page}`, `${mushafWordFontLink}/QCF4${`00${value.meta.page}`.slice(-3)}_COLOR-Regular.woff?version=${mushafFontVersion}`).then(() => {
25-
// we can by default hide the v4 words and show when the font is loaded...
24+
// Hide the v4 words by default and show when the font is loaded...
2625
document.querySelectorAll(`.p${value.meta.page}`).forEach((element) => {
2726
element.classList.remove('invisible');
2827
});
2928
});
3029
}
3130
32-
// handle what happens when a word is clicked depending on page type
33-
// 1. if a word is clicked on the morphology page, show/goto that word's morphology
34-
// 2. if a word is clicked on other pages, play the word's audio
35-
// 3. if the end verse icon is clicked on any page, show the verse options dropdown
31+
// Handle word clicks based on page type
32+
// 1. On morphology page, navigate to word's morphology
33+
// 2. On other pages, play word's audio
34+
// 3. On any page, show verse options dropdown for end verse icon
3635
function wordClickHandler(props) {
37-
// only if its morphology page and a word is clicked
3836
if ($__currentPage === 'morphology' && props.type === 'word') {
3937
__morphologyKey.set(props.key);
4038
goto(`/morphology/${props.key}`, { replaceState: false });
41-
}
42-
43-
// for all other pages
44-
else {
39+
} else {
4540
__verseKey.set(props.key);
46-
47-
// word in verse
4841
if (props.type === 'word') {
49-
wordAudioController({ key: props.key, chapter: +props.key.split(':')[0], verse: +props.key.split(':')[1] });
50-
}
51-
52-
// end verse icon
53-
else if (props.type === 'end') {
54-
// for continuous modes, the verse options dropdown will open, but if its not a continuous mode then un/bookmark verse
55-
if (!displayIsContinuous) updateSettings({ type: 'userBookmarks', key: props.key, set: true });
42+
wordAudioController({
43+
key: props.key,
44+
chapter: +props.key.split(':')[0],
45+
verse: +props.key.split(':')[1]
46+
});
47+
} else if (props.type === 'end') {
48+
if (!displayIsContinuous)
49+
updateSettings({
50+
type: 'userBookmarks',
51+
key: props.key,
52+
set: true
53+
});
5654
}
5755
}
5856
}
5957
58+
// Common classes for words and end icons
6059
$: wordAndEndIconCommonClasses = `
6160
hover:cursor-pointer
6261
${selectableThemes[$__websiteTheme].palette === 1 ? 'hover:bg-white/20' : 'hover:bg-black/10'}
@@ -65,6 +64,7 @@
6564
${exampleVerse && '!p-0'}
6665
`;
6766
67+
// Classes for word spans
6868
$: wordSpanClasses = `
6969
arabicText leading-normal
7070
arabic-font-${$__fontType}
@@ -73,12 +73,14 @@
7373
${[1, 4].includes($__fontType) && 'text-black theme'}
7474
`;
7575
76+
// Classes for v4 hafs words
7677
$: v4hafsClasses = `
7778
invisible v4-words
7879
p${value.meta.page}
7980
${$__fontType === 3 ? 'theme-palette-tajweed' : 'theme-palette-normal'}
8081
`;
8182
83+
// Classes for end icons
8284
$: endIconClasses = `rounded-lg ${wordAndEndIconCommonClasses}`;
8385
</script>
8486

src/components/display/verses/modes/Chapter.svelte

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
import { __currentPage, __userSettings, __displayType, __chapterNumber, __chapterData, __chapterDataLoaded } from '$utils/stores';
1414
import { buttonOutlineClasses } from '$data/commonClasses';
1515
16-
// load button click options
16+
// Load button click options
1717
const loadButtonOptions = {
1818
rootMargin: '2000px',
1919
unobserveOnEnter: true
@@ -36,30 +36,28 @@
3636
let nextVersesStart;
3737
let nextVersesEnd;
3838
39-
// function to load the next set of verses
39+
// Function to load the next set of verses
4040
function loadNextVerses() {
4141
versesLoadType = 'next';
4242
43-
// importing the same component to be re-used when the "Load Next Verses" button is pressed
43+
// Importing the same component to be re-used when the "Load Next Verses" button is pressed
4444
import('./Chapter.svelte').then((res) => (Chapter = res.default));
4545
46-
// max verses to load when the next set is requested
46+
// Max verses to load when the next set is requested
4747
const versesToLoad = 5;
4848
49-
// get the last verse number from last prop value
49+
// Get the last verse number from last prop value
5050
const versesOnPage = document.getElementsByClassName('verse');
5151
const lastVerseOnPage = +versesOnPage[versesOnPage.length - 1].id.split(':')[1];
5252
53-
// remove the existing button
53+
// Remove the existing button
5454
document.getElementById('loadVersesButton').remove();
5555
56-
// define the new starting and ending range
57-
(nextVersesStart = lastVerseOnPage + 1), (nextVersesEnd = nextVersesStart + versesToLoad);
56+
// Define the new starting and ending range
57+
nextVersesStart = lastVerseOnPage + 1;
58+
nextVersesEnd = Math.min(nextVersesStart + versesToLoad, chapterTotalVerses);
5859
59-
// if the end verse set above is greater than total verses, then set it as total verses
60-
if (nextVersesEnd > chapterTotalVerses) nextVersesEnd = chapterTotalVerses;
61-
62-
// setting the nextVersesProps
60+
// Setting the nextVersesProps
6361
nextVersesProps = {
6462
startVerse: nextVersesStart,
6563
endVerse: nextVersesEnd

src/components/display/verses/modes/Individual.svelte

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,18 @@
77
import TranslationTransliteration from '$display/layouts/TranslationTransliteration.svelte';
88
import { __displayType } from '$utils/stores';
99
10+
const allowedDisplayTypes = [1, 2, 7];
11+
1012
const displayComponents = {
1113
1: { component: WordByWord },
1214
2: { component: Normal },
1315
7: { component: TranslationTransliteration }
1416
};
1517
16-
// only allow display type 1, 2 & 7, and don't save the layout in settings
17-
if (![1, 2, 7].includes($__displayType)) __displayType.set(1);
18+
// Only allow display type 1, 2, & 7, and don't save the layout in settings if not allowed
19+
if (!allowedDisplayTypes.includes($__displayType)) {
20+
__displayType.set(1);
21+
}
1822
</script>
1923

2024
<svelte:component this={displayComponents[$__displayType].component} {key} {value} />

0 commit comments

Comments
 (0)