diff --git a/src/components/GlobalScrollListener.tsx b/src/components/GlobalScrollListener.tsx
index 869d759785..1463606ebf 100644
--- a/src/components/GlobalScrollListener.tsx
+++ b/src/components/GlobalScrollListener.tsx
@@ -4,7 +4,10 @@ import { useDispatch } from 'react-redux';
import useScrollDirection, { ScrollDirection } from '@/hooks/useScrollDirection';
import { setIsVisible } from '@/redux/slices/navbar';
-import { setIsExpanded } from '@/redux/slices/QuranReader/contextMenu';
+import {
+ setIsExpanded,
+ setShowReadingPreferenceSwitcher,
+} from '@/redux/slices/QuranReader/contextMenu';
const GlobalScrollListener = () => {
const dispatch = useDispatch();
@@ -23,6 +26,11 @@ const GlobalScrollListener = () => {
dispatch({ type: setIsExpanded.type, payload: true });
dispatch({ type: setIsVisible.type, payload: true });
}
+ if (newYPosition > 150 && direction === ScrollDirection.Down) {
+ dispatch({ type: setShowReadingPreferenceSwitcher.type, payload: true });
+ } else if (newYPosition <= 150 && direction === ScrollDirection.Up) {
+ dispatch({ type: setShowReadingPreferenceSwitcher.type, payload: false });
+ }
},
[dispatch],
);
diff --git a/src/components/QuranReader/ContextMenu.module.scss b/src/components/QuranReader/ContextMenu.module.scss
index 9d38a34c33..22b4e122dd 100644
--- a/src/components/QuranReader/ContextMenu.module.scss
+++ b/src/components/QuranReader/ContextMenu.module.scss
@@ -75,10 +75,15 @@
}
}
+.halfSection {
+ width: 50%; // when reading preference toggle is hidden
+}
+
.section {
- width: 50%;
- display: flex;
- align-items: center;
+ width: calc(100% / 3);
+ @include breakpoints.smallerThanTablet {
+ width: 50%;
+ }
}
.alignStart {
diff --git a/src/components/QuranReader/ContextMenu.tsx b/src/components/QuranReader/ContextMenu.tsx
index 2dc4ac5252..dd87170728 100644
--- a/src/components/QuranReader/ContextMenu.tsx
+++ b/src/components/QuranReader/ContextMenu.tsx
@@ -7,7 +7,11 @@ import useTranslation from 'next-translate/useTranslation';
import { shallowEqual, useDispatch, useSelector } from 'react-redux';
import styles from './ContextMenu.module.scss';
+import ReadingPreferenceSwitcher, {
+ ReadingPreferenceSwitcherType,
+} from './ReadingPreferenceSwitcher';
+import { SwitchSize } from '@/dls/Switch/Switch';
import ChevronDownIcon from '@/icons/chevron-down.svg';
import { selectNavbar } from '@/redux/slices/navbar';
import { selectContextMenu } from '@/redux/slices/QuranReader/contextMenu';
@@ -31,7 +35,10 @@ const ContextMenu = () => {
const isSidebarNavigationVisible = useSelector(selectIsSidebarNavigationVisible);
const { t, lang } = useTranslation('common');
const isSideBarVisible = useSelector(selectNotes, shallowEqual).isVisible;
- const { isExpanded } = useSelector(selectContextMenu, shallowEqual);
+ const { isExpanded, showReadingPreferenceSwitcher } = useSelector(
+ selectContextMenu,
+ shallowEqual,
+ );
const isNavbarVisible = useSelector(selectNavbar, shallowEqual).isVisible;
const { verseKey, chapterId, page, hizb } = useSelector(selectLastReadVerseKey, shallowEqual);
const chapterData = useMemo(() => {
@@ -66,7 +73,7 @@ const ContextMenu = () => {
style={{ '--progress': `${progress}%` }} // this is to pass the value to css so it can be used to show the progress bar.
>
-
+
-
+ {showReadingPreferenceSwitcher && (
+
+
+
+ )}
+
svg {
+ width: 15px;
+ display: block;
+ margin: auto;
+ }
+
+ @include breakpoints.smallerThanTablet {
+ & > svg {
+ -webkit-margin-end: 0;
+ margin-inline-end: 0;
+ }
+ }
+}
diff --git a/src/components/QuranReader/ReadingPreferenceSwitcher/ReadingPreferenceOption.tsx b/src/components/QuranReader/ReadingPreferenceSwitcher/ReadingPreferenceOption.tsx
index db537cb44c..bca037014c 100644
--- a/src/components/QuranReader/ReadingPreferenceSwitcher/ReadingPreferenceOption.tsx
+++ b/src/components/QuranReader/ReadingPreferenceSwitcher/ReadingPreferenceOption.tsx
@@ -1,20 +1,30 @@
import React from 'react';
+import classNames from 'classnames';
import useTranslation from 'next-translate/useTranslation';
import styles from '@/components/QuranReader/ReadingPreferenceSwitcher/ReadingPreference.module.scss';
import Spinner from '@/dls/Spinner/Spinner';
+import BookIcon from '@/icons/book.svg';
+import ReaderIcon from '@/icons/reader.svg';
import { ReadingPreference } from 'types/QuranReader';
type Props = {
readingPreference: ReadingPreference;
selectedReadingPreference: ReadingPreference;
+ isIconsOnly?: boolean;
isLoading: boolean;
};
+export const readingPreferenceIcons = {
+ [ReadingPreference.Reading]: ,
+ [ReadingPreference.Translation]: ,
+};
+
const LoadingSwitcher: React.FC = ({
readingPreference,
selectedReadingPreference,
+ isIconsOnly = false,
isLoading,
}) => {
const { t } = useTranslation('common');
@@ -23,10 +33,23 @@ const LoadingSwitcher: React.FC = ({
- {t(`reading-preference.${readingPreference}`)}
+ {!isIconsOnly && (
+
+ {t(`reading-preference.${selectedReadingPreference}`)}
+
+ )}
) : (
- t(`reading-preference.${selectedReadingPreference}`)
+
+
+ {readingPreferenceIcons[selectedReadingPreference]}
+
+ {!isIconsOnly && (
+
+ {t(`reading-preference.${selectedReadingPreference}`)}
+
+ )}
+
);
};
diff --git a/src/components/QuranReader/ReadingPreferenceSwitcher/ReadingPreferenceSwitcher.module.scss b/src/components/QuranReader/ReadingPreferenceSwitcher/ReadingPreferenceSwitcher.module.scss
index 42e4f8c902..eacb816d13 100644
--- a/src/components/QuranReader/ReadingPreferenceSwitcher/ReadingPreferenceSwitcher.module.scss
+++ b/src/components/QuranReader/ReadingPreferenceSwitcher/ReadingPreferenceSwitcher.module.scss
@@ -1,8 +1,7 @@
$readingPreferenceMaxWidth: calc(20 * var(--spacing-large));
+$contextMenuReadingPreferenceMaxWidth: calc(10 * var(--spacing-large));
.container {
max-width: $readingPreferenceMaxWidth;
- margin-block-start: var(--spacing-small);
- margin-block-end: var(--spacing-xxsmall);
margin-inline-start: auto;
margin-inline-end: auto;
padding-block-start: 0;
@@ -10,3 +9,12 @@ $readingPreferenceMaxWidth: calc(20 * var(--spacing-large));
padding-inline-start: var(--spacing-small);
padding-inline-end: var(--spacing-small);
}
+
+.surahHeaderContainer {
+ margin-block-start: var(--spacing-small);
+ margin-block-end: var(--spacing-xxsmall);
+}
+
+.contextMenuContainer {
+ max-width: $contextMenuReadingPreferenceMaxWidth;
+}
diff --git a/src/components/QuranReader/ReadingPreferenceSwitcher/index.tsx b/src/components/QuranReader/ReadingPreferenceSwitcher/index.tsx
index 86289f2ec1..80797a6f85 100644
--- a/src/components/QuranReader/ReadingPreferenceSwitcher/index.tsx
+++ b/src/components/QuranReader/ReadingPreferenceSwitcher/index.tsx
@@ -1,21 +1,40 @@
+import classNames from 'classnames';
import { useRouter } from 'next/router';
import { useSelector } from 'react-redux';
import LoadingSwitcher from './ReadingPreferenceOption';
import styles from './ReadingPreferenceSwitcher.module.scss';
-import Switch from '@/dls/Switch/Switch';
+import Switch, { SwitchSize } from '@/dls/Switch/Switch';
import usePersistPreferenceGroup from '@/hooks/auth/usePersistPreferenceGroup';
import {
selectReadingPreferences,
setReadingPreference,
} from '@/redux/slices/QuranReader/readingPreferences';
+import { selectLastReadVerseKey } from '@/redux/slices/QuranReader/readingTracker';
import { logValueChange } from '@/utils/eventLogger';
import PreferenceGroup from 'types/auth/PreferenceGroup';
import { ReadingPreference } from 'types/QuranReader';
-const ReadingPreferenceSwitcher = () => {
+export enum ReadingPreferenceSwitcherType {
+ SurahHeader = 'surah_header',
+ ContextMenu = 'context_menu',
+}
+
+interface Props {
+ size?: SwitchSize;
+ isIconsOnly?: boolean;
+ type?: ReadingPreferenceSwitcherType;
+}
+
+const ReadingPreferenceSwitcher: React.FC
= ({
+ size,
+ isIconsOnly = false,
+ type = ReadingPreferenceSwitcherType.SurahHeader,
+}) => {
const readingPreferences = useSelector(selectReadingPreferences);
+ const lastReadVerseKey = useSelector(selectLastReadVerseKey);
+ const lastReadVerse = lastReadVerseKey.verseKey?.split(':')[1];
const { readingPreference } = readingPreferences;
const {
actions: { onSettingsChange },
@@ -30,6 +49,7 @@ const ReadingPreferenceSwitcher = () => {
readingPreference={readingPreference}
selectedReadingPreference={ReadingPreference.Translation}
isLoading={isLoading}
+ isIconsOnly={isIconsOnly}
/>
),
value: ReadingPreference.Translation,
@@ -40,6 +60,7 @@ const ReadingPreferenceSwitcher = () => {
readingPreference={readingPreference}
selectedReadingPreference={ReadingPreference.Reading}
isLoading={isLoading}
+ isIconsOnly={isIconsOnly}
/>
),
value: ReadingPreference.Reading,
@@ -47,11 +68,20 @@ const ReadingPreferenceSwitcher = () => {
];
const onViewSwitched = (view: ReadingPreference) => {
- logValueChange('reading_preference', readingPreference, view);
+ logValueChange(`${type}_reading_preference`, readingPreference, view);
- // drop `startingVerse` from query params
const newQueryParams = { ...router.query };
- delete newQueryParams.startingVerse;
+
+ // Track `startingVerse` once we're past the start of the page so we can
+ // continue from the same ayah when switching views. Without the > 1 check,
+ // switching views at the start of the page causes unnecessary scrolls
+
+ if (type === ReadingPreferenceSwitcherType.SurahHeader) {
+ delete newQueryParams.startingVerse;
+ } else if (parseInt(lastReadVerse, 10) > 1) {
+ newQueryParams.startingVerse = lastReadVerse;
+ }
+
const newUrlObject = {
pathname: router.pathname,
query: newQueryParams,
@@ -69,11 +99,17 @@ const ReadingPreferenceSwitcher = () => {
};
return (
-
+
);
diff --git a/src/components/dls/Switch/Switch.module.scss b/src/components/dls/Switch/Switch.module.scss
index 6744cd6364..38255e6f3f 100644
--- a/src/components/dls/Switch/Switch.module.scss
+++ b/src/components/dls/Switch/Switch.module.scss
@@ -17,6 +17,13 @@ $separatorOpacity: 0.2;
); // use grid to prevent layout shift when `font-family: bold` on item selected https://css-tricks.com/bold-on-hover-without-the-layout-shift/
}
+.xSmallContainer {
+ padding-block-start: 0;
+ padding-block-end: 0;
+ padding-inline-start: 0;
+ padding-inline-end: 0;
+}
+
.item {
cursor: pointer;
color: var(--color-text-default);
@@ -94,3 +101,10 @@ $background-container: calc(0.8 * var(--spacing-xxsmall));
padding-inline-start: var(--spacing-small);
padding-inline-end: var(--spacing-small);
}
+
+.itemXSmall {
+ padding-block-start: var(--spacing-micro);
+ padding-block-end: var(--spacing-micro);
+ padding-inline-start: var(--spacing-micro);
+ padding-inline-end: var(--spacing-micro);
+}
diff --git a/src/components/dls/Switch/Switch.tsx b/src/components/dls/Switch/Switch.tsx
index ee3df858f9..230352abfd 100644
--- a/src/components/dls/Switch/Switch.tsx
+++ b/src/components/dls/Switch/Switch.tsx
@@ -14,6 +14,7 @@ type Item = {
disabled?: boolean;
};
export enum SwitchSize {
+ XSmall = 'xsmall',
Small = 'small',
Normal = 'normal',
Large = 'large',
@@ -29,7 +30,11 @@ const Switch = ({ items, onSelect, selected, size = SwitchSize.Normal }: SwitchP
const selectedIndex = items.findIndex((item) => item.value === selected);
const { locale } = useRouter();
return (
-
+
{items.map((item) => (