Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -11,20 +11,19 @@ import StudyModeRelatedVerseSkeleton from './StudyModeRelatedVerseSkeleton';

import { fetcher } from '@/api';
import Button, { ButtonSize, ButtonVariant } from '@/dls/Button/Button';
import Collapsible from '@/dls/Collapsible/Collapsible';
import Separator from '@/dls/Separator/Separator';
import useQcfFont from '@/hooks/useQcfFont';
import ChevronDownIcon from '@/icons/chevron-down.svg';
import { selectWordByWordLocale } from '@/redux/slices/QuranReader/readingPreferences';
import { selectQuranReaderStyles } from '@/redux/slices/QuranReader/styles';
import { selectSelectedTranslations } from '@/redux/slices/QuranReader/translations';
import { getDefaultWordFields, getMushafId } from '@/utils/api';
import { makeByVerseKeyUrl } from '@/utils/apiPaths';
import { makeByRangeVersesUrl } from '@/utils/apiPaths';
import { logButtonClick } from '@/utils/eventLogger';
import { toLocalizedNumber, toLocalizedVerseKeyAuto } from '@/utils/locale';
import { VersesResponse } from 'types/ApiResponses';
import RelatedVerse from 'types/RelatedVerse';
import Verse from 'types/Verse';

interface VerseResponse {
verse: Verse;
}

const NOOP = (): void => {};

Expand All @@ -39,21 +38,24 @@ const StudyModeRelatedVerseContent: React.FC<StudyModeRelatedVerseContentProps>
currentVerseKey,
onGoToVerse,
}) => {
const { t } = useTranslation('common');
const { t, lang } = useTranslation('common');
const quranReaderStyles = useSelector(selectQuranReaderStyles, shallowEqual);
const selectedTranslations = useSelector(selectSelectedTranslations, shallowEqual);
const wordByWordLocale = useSelector(selectWordByWordLocale);

const [chapterId, verseNumber] = relatedVerse.verseKey.split(':');
const [chapterId, verseNumber] = relatedVerse.verseKeyFrom.split(':');

const handleGoToVerse = useCallback(() => {
logButtonClick('study_mode_goto_verse', { verseKey: relatedVerse.verseKey });
logButtonClick('study_mode_goto_verse', { verseKey: relatedVerse.verseKeyFrom });
onGoToVerse?.(chapterId, verseNumber, currentVerseKey);
}, [chapterId, verseNumber, onGoToVerse, relatedVerse.verseKey, currentVerseKey]);
}, [chapterId, verseNumber, onGoToVerse, relatedVerse.verseKeyFrom, currentVerseKey]);

// Fetch verse data when collapsible is opened
const queryKey = makeByVerseKeyUrl(relatedVerse.verseKey, {
// Fetch verse data for the range
const queryKey = makeByRangeVersesUrl(lang, {
from: relatedVerse.verseKeyFrom,
to: relatedVerse.verseKeyTo,
words: true,
perPage: 'all',
translationFields: 'resource_name,language_id',
translations: selectedTranslations.join(','),
...getDefaultWordFields(quranReaderStyles.quranFont),
Expand All @@ -62,44 +64,85 @@ const StudyModeRelatedVerseContent: React.FC<StudyModeRelatedVerseContentProps>
wordTransliteration: 'true',
});

const { data, isValidating } = useSWR<VerseResponse>(queryKey, fetcher, {
const { data, isValidating } = useSWR<VersesResponse>(queryKey, fetcher, {
revalidateOnFocus: false,
revalidateOnReconnect: false,
dedupingInterval: 2000,
});
Comment thread
afifvdin marked this conversation as resolved.

const verse = data?.verse;
const verses = data?.verses;

const title = useMemo(() => {
const verseKeyFrom = toLocalizedVerseKeyAuto(relatedVerse.verseKeyFrom, lang);

// Single verse: "Al-Fatihah 1:1"
if (relatedVerse.verseIdFrom === relatedVerse.verseIdTo) {
return `${relatedVerse.chapterNameFrom} ${verseKeyFrom}`;
}

const surahFrom = relatedVerse.verseKeyFrom.split(':')[0];
const surahTo = relatedVerse.verseKeyTo.split(':')[0];

// Cross-surah range: "Al-Fatihah 1:4 - Al-Baqarah 2:3"
if (surahFrom !== surahTo) {
const verseKeyTo = toLocalizedVerseKeyAuto(relatedVerse.verseKeyTo, lang);
return `${relatedVerse.chapterNameFrom} ${verseKeyFrom} - ${relatedVerse.chapterNameTo} ${verseKeyTo}`;
}

// Same surah range: "Al-Fatihah 1:1-4"
const verseNumberTo = toLocalizedNumber(Number(relatedVerse.verseKeyTo.split(':')[1]), lang);
return `${relatedVerse.chapterNameFrom} ${verseKeyFrom}-${verseNumberTo}`;
}, [relatedVerse, lang]);

const versesForFont = useMemo(() => (verse ? [verse] : []), [verse]);
const versesForFont = useMemo(() => verses || [], [verses]);
useQcfFont(quranReaderStyles.quranFont, versesForFont);

if (isValidating || !verse) {
if (isValidating || !verses || verses.length === 0) {
return <StudyModeRelatedVerseSkeleton />;
}

return (
<>
<div className={styles.relatedVerse}>
<StudyModeBodyContent
verse={verse}
showWordBox={false}
onWordClick={NOOP}
onWordBoxClose={NOOP}
onNavigatePreviousWord={NOOP}
onNavigateNextWord={NOOP}
canNavigateWordPrev={false}
canNavigateWordNext={false}
/>
<div className={styles.relatedVerseCta}>
<Button
className={styles.goToVerseButton}
size={ButtonSize.Small}
variant={ButtonVariant.Compact}
onClick={handleGoToVerse}
>
{t('go-to-verse')}
</Button>
</div>
<Collapsible
title={<p className={styles.title}>{title}</p>}
suffix={<ChevronDownIcon />}
Comment thread
afifvdin marked this conversation as resolved.
shouldRotateSuffixOnToggle
headerLeftClassName={styles.collapsibleHeader}
>
{({ isOpen }) => {
if (!isOpen) return null;

return (
<div className={styles.relatedVerseContent}>
{verses.map((verse) => (
<>
<StudyModeBodyContent
verse={verse}
showWordBox={false}
onWordClick={NOOP}
onWordBoxClose={NOOP}
onNavigatePreviousWord={NOOP}
onNavigateNextWord={NOOP}
canNavigateWordPrev={false}
canNavigateWordNext={false}
/>
<div className={styles.relatedVerseCta}>
<Button
className={styles.goToVerseButton}
size={ButtonSize.Small}
variant={ButtonVariant.Compact}
onClick={handleGoToVerse}
Comment thread
afifvdin marked this conversation as resolved.
>
{t('go-to-verse')}
</Button>
</div>
</>
))}
Comment thread
afifvdin marked this conversation as resolved.
</div>
);
}}
</Collapsible>
</div>
<div className={styles.relatedVerseSeparatorContainer}>
<Separator />
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
@use 'src/styles/breakpoints';
@use 'src/styles/utility';

.relatedVerse {
padding-block: var(--spacing-medium2-px);
.relatedVerseContent {
padding-block-end: var(--spacing-medium2-px);
}

.relatedVerseSeparatorContainer {
Expand Down Expand Up @@ -30,3 +30,18 @@
.relatedVerseCta {
@include utility.edgeHorizontalPadding;
}

.collapsibleHeader {
@include utility.edgeHorizontalPadding;
display: flex;
align-items: center;
justify-content: space-between;
inline-size: 100%;
padding-block: var(--spacing-medium2-px);
cursor: pointer;
transition: background-color 0.2s ease;

&:hover {
background-color: var(--color-background-alternative-medium);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,6 @@ const BottomActionsTabs: React.FC<BottomActionsTabsProps> = ({
containerClassName={styles.tabContainerWrapper}
className={classNames(styles.tabsContainer, className, {
[styles.center]: !isTranslationView,
[styles.tabsContainerRTL]: isRTL && isTranslationView,
})}
eventName={EventName.QURAN_READER_BOTTOM_ACTION_SCROLLABLE}
>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -187,11 +187,6 @@
}
}

.tabsContainerRTL {
justify-content: flex-start;
flex-direction: row-reverse;
}

.center {
justify-content: center;
}
Expand Down
18 changes: 18 additions & 0 deletions src/styles/_utility.scss
Original file line number Diff line number Diff line change
Expand Up @@ -1002,6 +1002,24 @@ $page-container-max-width: 80rem;
padding-block: var(--spacing-edge-vertical-px);
}

@mixin edgeMargin {
margin-inline: var(--spacing-edge-horizontal-px);
margin-block: var(--spacing-edge-vertical-px);
}

@mixin edgeMarginEven {
margin-inline: var(--spacing-edge-horizontal-px);
margin-block: var(--spacing-edge-vertical-even-px);
}

@mixin edgeHorizontalMargin {
margin-inline: var(--spacing-edge-horizontal-px);
}

@mixin edgeVerticalMargin {
margin-block: var(--spacing-edge-vertical-px);
}

@mixin scrollbarNone {
-webkit-overflow-scrolling: touch;
scroll-behavior: smooth;
Expand Down
9 changes: 6 additions & 3 deletions types/RelatedVerse.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
interface RelatedVerse {
id: number;
verseId: number;
verseKey: string;
verseIdFrom: number;
verseIdTo: number;
verseKeyFrom: string;
verseKeyTo: string;
relation: string;
chapterName: string;
chapterNameFrom: string;
chapterNameTo: string;
}

export default RelatedVerse;