Skip to main content

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: 'بسم الله الرحمن الرحيم'

Quran Metadata Utilities

getSurahNameByPage

Retrieves the surah name for a given page number.
function getSurahNameByPage(surahs: Surah[], page: number): string
surahs
Surah[]
required
Array of surah metadata
page
number
required
Page number (1-604)
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
surahs
Surah[]
required
Array of surah metadata
page
number
required
Page number (1-604)
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 }
thumns
Thumn[]
required
Array of thumn metadata
page
number
required
Page number (1-604)
return
object
thumnInJuz
number
Position within the Juz (1-16)
juzNumber
number
Juz number (1-30)
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 }
surahs
Surah[]
required
Array of surah metadata
thumns
Thumn[]
required
Array of thumn metadata
page
number
required
Page number (1-604)
return
object
title
string
Page title for SEO
description
string
Page description for SEO
keywords
string
Comma-separated keywords
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
value
Riwaya
required
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
index
number
required
Index: 0 or 1
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
previousPage
number
required
Starting page number
currentPage
number
required
Ending page number
hizbs
Hizb[]
required
Array of Hizb metadata
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
startPage
number
required
Starting page number
endPage
number
required
Ending page number
thumnData
Thumn[]
required
Array of Thumn metadata
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
defaultDimension
number
required
Default dimension value
customDimension
number
required
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
width
number
required
Screen width in pixels
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
width
number
required
Screen width in pixels
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
width
number
required
Screen width in pixels
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} />;
}

getPaginationRange

Determines the number of page buttons to show based on screen width.
function getPaginationRange(width: number): number
width
number
required
Screen width in pixels
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} />;
}

Platform Detection Utilities

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>
  );
}

Build docs developers (and LLMs) love