Overview
Open Mushaf Native provides utility functions for common tasks including Quran metadata operations, dimension calculations, platform detection, and progress tracking.
Search Utilities
normalizeArabic
Normalizes Arabic text for consistent search and comparison.
import { normalizeArabic } from '@/utils/searchUtils';
Re-exported from quran-search-engine package.
Usage Example:
import { normalizeArabic } from '@/utils/searchUtils';
const normalized = normalizeArabic('الرَّحْمَـٰنِ');
// Normalizes hamza, alef variants, etc.
removeTashkeel
Removes Arabic diacritical marks (tashkeel) from text.
import { removeTashkeel } from '@/utils/searchUtils';
Re-exported from quran-search-engine package.
Usage Example:
import { removeTashkeel } from '@/utils/searchUtils';
const plain = removeTashkeel('بِسْمِ اللَّهِ الرَّحْمَـٰنِ الرَّحِيمِ');
// Returns: 'بسم الله الرحمن الرحيم'
getSurahNameByPage
Retrieves the surah name for a given page number.
function getSurahNameByPage(surahs: Surah[], page: number): string
Returns: Surah name in Arabic, or empty string if not found.
Usage Example:
import { getSurahNameByPage } from '@/utils/quranMetadataUtils';
import useQuranMetadata from '@/hooks/useQuranMetadata';
function PageHeader({ page }) {
const { surahData } = useQuranMetadata();
const surahName = getSurahNameByPage(surahData, page);
return <Text>{surahName}</Text>;
}
getSurahNumberByPage
Retrieves the surah number for a given page.
function getSurahNumberByPage(surahs: Surah[], page: number): string
Returns: Surah number as a string, or 1 if not found.
Usage Example:
import { getSurahNumberByPage } from '@/utils/quranMetadataUtils';
function PageInfo({ page, surahs }) {
const surahNumber = getSurahNumberByPage(surahs, page);
return <Text>Surah {surahNumber}</Text>;
}
getJuzPositionByPage
Calculates the juz number and thumn position for a given page.
function getJuzPositionByPage(
thumns: Thumn[],
page: number
): { thumnInJuz: number; juzNumber: number }
Position within the Juz (1-16)
Usage Example:
import { getJuzPositionByPage } from '@/utils/quranMetadataUtils';
function JuzIndicator({ page, thumns }) {
const { juzNumber, thumnInJuz } = getJuzPositionByPage(thumns, page);
return (
<View>
<Text>Juz {juzNumber}</Text>
<Text>Thumn {thumnInJuz}/16</Text>
</View>
);
}
getSEOMetadataByPage
Generates SEO-friendly metadata for a specific Quran page.
function getSEOMetadataByPage(
surahs: Surah[],
thumns: Thumn[],
page: number
): { title: string; description: string; keywords: string }
Usage Example:
import { getSEOMetadataByPage } from '@/utils/quranMetadataUtils';
import Head from 'next/head';
function PageMeta({ page, surahs, thumns }) {
const { title, description, keywords } = getSEOMetadataByPage(
surahs,
thumns,
page
);
return (
<Head>
<title>{title}</title>
<meta name="description" content={description} />
<meta name="keywords" content={keywords} />
</Head>
);
}
Riwaya Utilities
RiwayaByIndice
Converts a riwaya value to its index.
function RiwayaByIndice(value: Riwaya): number
Riwaya value: 'hafs' or 'warsh'
Returns: Index number: 0 for Hafs, 1 for Warsh.
Usage Example:
import { RiwayaByIndice } from '@/utils/riwaya';
const index = RiwayaByIndice('hafs'); // Returns 0
const warshIndex = RiwayaByIndice('warsh'); // Returns 1
RiwayaByValue
Converts an index to its riwaya value.
function RiwayaByValue(index: number): Riwaya
Returns: Riwaya value: 'hafs' or 'warsh'.
Throws: Error if index is invalid.
Usage Example:
import { RiwayaByValue } from '@/utils/riwaya';
const riwaya = RiwayaByValue(0); // Returns 'hafs'
const warsh = RiwayaByValue(1); // Returns 'warsh'
Progress Tracking Utilities
calculateHizbsBetweenPages
Calculates the number of Hizbs between two pages.
function calculateHizbsBetweenPages(
previousPage: number,
currentPage: number,
hizbs: Hizb[]
): number
Returns: Number of Hizbs completed between the two pages.
Usage Example:
import { calculateHizbsBetweenPages } from '@/utils/hizbProgress';
import { useAtomValue } from 'jotai';
import { yesterdayPage, currentSavedPage } from '@/jotai/atoms';
function DailyProgress() {
const yesterday = useAtomValue(yesterdayPage);
const current = useAtomValue(currentSavedPage);
const { hizbData } = useQuranMetadata();
const hizbsCompleted = calculateHizbsBetweenPages(
yesterday.value,
current,
hizbData
);
return <Text>{hizbsCompleted} Hizbs completed today</Text>;
}
calculateThumnsBetweenPages
Calculates the number of Thumns (eighths of a Hizb) between two pages.
function calculateThumnsBetweenPages(
startPage: number,
endPage: number,
thumnData: Thumn[]
): number
Returns: Number of Thumns between the pages (0 if invalid input).
Usage Example:
import { calculateThumnsBetweenPages } from '@/utils/hizbProgress';
function DetailedProgress({ startPage, endPage, thumns }) {
const thumnsRead = calculateThumnsBetweenPages(startPage, endPage, thumns);
const percentage = (thumnsRead / 240) * 100; // 240 thumns in Quran
return <Text>{percentage.toFixed(1)}% of Quran</Text>;
}
Dimension Utilities
getDimensionCoeff
Calculates the scaling coefficient for responsive dimensions.
function getDimensionCoeff({
defaultDimension,
customDimension
}): number
Custom/target dimension value
Returns: Scaling coefficient (customDimension / defaultDimension).
Usage Example:
import { getDimensionCoeff } from '@/utils/getDimensionCoeff';
function ScalableComponent({ defaultWidth, customWidth }) {
const coefficient = getDimensionCoeff({
defaultDimension: defaultWidth,
customDimension: customWidth
});
const scaledFontSize = 16 * coefficient;
return <Text style={{ fontSize: scaledFontSize }}>Scaled Text</Text>;
}
BREAKPOINTS
Screen size breakpoint constants.
export const BREAKPOINTS = {
COMPACT: 370, // Very small screens (small phones)
MOBILE: 640, // Mobile screens
TABLET: 1024, // Tablet screens
};
Usage Example:
import { BREAKPOINTS } from '@/utils/dimensionsUtils';
import { useWindowDimensions } from 'react-native';
function ResponsiveLayout() {
const { width } = useWindowDimensions();
const isMobile = width < BREAKPOINTS.MOBILE;
return isMobile ? <MobileView /> : <DesktopView />;
}
isCompactView
Checks if the screen width is in compact mode.
function isCompactView(width: number): boolean
Returns: true if width is less than 370px.
Usage Example:
import { isCompactView } from '@/utils/dimensionsUtils';
import { useWindowDimensions } from 'react-native';
function AdaptiveButton() {
const { width } = useWindowDimensions();
const compact = isCompactView(width);
return (
<Button size={compact ? 'small' : 'medium'}>
{compact ? 'OK' : 'Continue'}
</Button>
);
}
isMobileView
Checks if the screen width is in mobile mode.
function isMobileView(width: number): boolean
Returns: true if width is less than 640px.
Usage Example:
import { isMobileView } from '@/utils/dimensionsUtils';
function Navigation({ width }) {
return isMobileView(width) ? <MobileNav /> : <DesktopNav />;
}
isTabletView
Checks if the screen width is in tablet mode.
function isTabletView(width: number): boolean
Returns: true if width is less than 1024px.
Usage Example:
import { isTabletView } from '@/utils/dimensionsUtils';
function Layout({ width }) {
const isTablet = isTabletView(width);
return <View columns={isTablet ? 2 : 3} />;
}
Determines the number of page buttons to show based on screen width.
function getPaginationRange(width: number): number
Returns:
1 for screens < 640px (mobile)
3 for screens 640-1024px (tablet)
5 for screens > 1024px (desktop)
Usage Example:
import { getPaginationRange } from '@/utils/dimensionsUtils';
import { useWindowDimensions } from 'react-native';
function Pagination({ currentPage, totalPages }) {
const { width } = useWindowDimensions();
const range = getPaginationRange(width);
// Show 'range' number of page buttons
return <PageButtons current={currentPage} range={range} />;
}
isWeb
Boolean indicating if the app is running on web.
export const isWeb: boolean;
Usage Example:
import { isWeb } from '@/utils/isWeb';
function PlatformSpecificComponent() {
return isWeb ? <WebView /> : <NativeView />;
}
isRTL
Boolean indicating if the app is in RTL (right-to-left) mode.
export const isRTL: boolean;
Usage Example:
import { isRTL } from '@/utils/isRTL';
function DirectionalLayout() {
return (
<View style={{ flexDirection: isRTL ? 'row-reverse' : 'row' }}>
<Content />
</View>
);
}
debug
Boolean indicating if debug mode is enabled.
export const debug: boolean;
Based on EXPO_PUBLIC_DEBUG environment variable.
Usage Example:
import { debug } from '@/utils/isDEBUG';
function App() {
if (debug) {
console.log('Debug mode enabled');
}
return <MainApp />;
}
Version Utilities
getAppVersion
Retrieves the current app version.
function getAppVersion(): string
Returns: Version string (e.g., '1.2.3'), or '0.0.0' if unavailable.
Behavior:
- In development: Returns version from Expo config
- In production: Returns native application version
Usage Example:
import { getAppVersion } from '@/utils/getVersion';
function AboutScreen() {
const version = getAppVersion();
return <Text>Version {version}</Text>;
}
getBuildVersion
Retrieves the current build version.
function getBuildVersion(): string
Returns: Build version string (e.g., '123'), or '000' if unavailable.
Usage Example:
import { getAppVersion, getBuildVersion } from '@/utils/getVersion';
function VersionInfo() {
return (
<Text>
{getAppVersion()} (Build {getBuildVersion()})
</Text>
);
}