Skip to content

Feat/warsh audio prayer mode - #10

Open
Zizwar wants to merge 15 commits into
claude/fix-splash-pages-6djJkfrom
feat/warsh-audio-prayer-mode
Open

Feat/warsh audio prayer mode#10
Zizwar wants to merge 15 commits into
claude/fix-splash-pages-6djJkfrom
feat/warsh-audio-prayer-mode

Conversation

@Zizwar

@Zizwar Zizwar commented Mar 19, 2026

Copy link
Copy Markdown
Owner

No description provided.

Zizwar and others added 14 commits March 14, 2026 05:33
Pages 1 and 2 use a different image endpoint (ayat/safahat1) for better
quality cover rendering.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Registers expo-splash-screen as a config plugin with imageWidth and
cover resizeMode so the splash renders at full size on Android 12+ and iOS.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Dhikr screen: vibrate feedback on toggle, infinite target (∞),
  sura/aya picker for Quran verses, scrollable dhikr text with
  inline edit/delete buttons
- Downloads: verify file size after download, report failed pages,
  add failed_pages translation to all 9 locales
- Image cache: auto-cache remotely fetched pages in background,
  one-time hint to switch to text mode on image load failure
- Ayah modal: fix scroll not working on ayah text by separating
  overlay from card, increase max visible text height

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Amiri Quran: classic Naskh inspired by Cairo's Bulaq Press (OFL license)
- Noto Naskh Arabic: Google's polished Naskh typeface (OFL license)
- Register both fonts in App.tsx useFonts
- Add to font picker in MushafViewer and SettingsScreen
- Add font name translations to all 9 locales

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Remove hand-left icon from header toolbar
- Remove DonateModal, donors ticker, and donation section from About
- Replace with simple "Support" button linking to mushaf.ma/support
- Remove unused Linking import from MushafViewer
- Add sura name filter search input above sura list in SearchScreen
- Add search_sura_name translation to all 9 locales

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
… record new

RecordingsScreen.tsx reduced from 1743 to ~838 lines by extracting:
- recordings/types.ts - shared interfaces
- recordings/styles.ts - all StyleSheet definitions
- recordings/RecordingDetailModal.tsx - full detail view on card tap
- recordings/RecordNewModal.tsx - new recording with sura/aya picker + TAP/HOLD modes
- hooks/useRecordingsPlayer.ts - audio playback with overlap fix

Key improvements:
- Simplified cards: show ayah text + play button, tap opens detail modal
- Fix sound overlap: pause() before remove(), playIdRef race condition guard
- Record from this screen: sura picker → aya grid → record with TAP or HOLD mode
- HOLD mode: press to record, release auto-advances to next aya
- TAP mode: tap to start/stop recording
- Add i18n keys for new features in all 9 locales

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…ih sura picker

- Deep linking: mushafmauri:// scheme + mushaf.ma/#/a{aya}s{sura}q{quira}
- Register .mrec file type on iOS (UTI) and Android (intent filter)
- Import recordings from URL (http/https) in addition to local files
- Replace inline SuraAyaPicker in TasbihScreen with full modal bottom sheet
- Add landing page (docs/index.html) and .well-known verification files
- Add i18n keys for import_from_file, import_from_url across all 9 locales

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Each param (a/s/q) parsed independently — any can be missing
- Defaults: sura=1, aya=1, quira=current user preference
- Even on parse error, still opens the mushaf
- Landing page also handles partial URLs with same defaults
- Examples: mushaf.ma/#/s2 → sura 2 aya 1, mushaf.ma → opens app

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Extract all hardcoded Madina coordinate values into madinaConfig object
- Add CoordTunerPanel with +/- buttons and text input for each value
- Toggle via wrench icon on top-left of Quran page (Hafs only)
- Press "تطبيق" to recalculate all ayah overlays with new values
- Temporary tool: set __DEV_COORD_TUNER__ = false to disable

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- AyahOverlay now receives isMadina prop — overlayTopExtra/overlayLeftExtra
  only apply to Hafs, Warsh coordinates remain untouched
- Tuner panel: smaller (72% width), centered on screen
- Added reset button (إعادة) to restore default values
- Added copy button (نسخ) to copy all values to clipboard
- Changed values highlighted in green for easy spotting
- All madinaConfig vars read from config object, not hardcoded consts

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…ffset

Calibrated values: ImgW=451, TOP_OFFSET=-30, height=38, ofHeight=8, mgWidth=20
Pages 1&2 use TOP_OFFSET_P12=-20 (different layout from normal pages)
Warsh coordinates completely isolated — not affected by any madinaConfig changes

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Values are now hardcoded in madinaConfig. Panel, clipboard import,
ScrollView/TextInput imports, and _rev counter all removed.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add all 9 languages (ar, en, fr, amz, es, de, it, nl, he) as compact chips
- Auto-detect device language on first launch
- Add display mode step (image vs text) with offline/online explanations
- Add amiri-quran and noto-naskh to font options
- 5 steps: welcome → language → mushaf → mode → theme+font
- Restore normal welcome behavior (shows once only)
- All new keys translated in 9 locales

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@gemini-code-assist

Copy link
Copy Markdown

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request introduces significant new features and improvements across the application. It primarily focuses on enhancing user interaction with Quranic content through deep linking, a more robust and user-friendly recording management system, and flexible display options for Mushaf pages. Additionally, it refines existing functionalities like offline downloads and the Tasbih counter, making the app more versatile and resilient.

Highlights

  • Deep Linking & .mrec File Support: Implemented robust deep linking functionality, allowing the app to open directly to specific Quranic verses (sura/aya) via mushaf.ma URLs and to import recording profiles from .mrec files via various URIs (local files, content providers, or web links).
  • Refactored Recording Management: The recording screen has been significantly refactored, introducing a dedicated audio player hook, new modals for detailed recording actions, and a streamlined 'Record New' workflow. This improves the user experience for managing and interacting with personal Quranic recitations.
  • Mushaf Display Mode Selection: Added a new 'Display Mode' option during onboarding and in settings, enabling users to choose between image-based and text-based Quran page rendering. This provides flexibility, especially for offline use or when image loading fails.
  • New Quranic Fonts: Integrated 'Amiri Quran' and 'Noto Naskh' fonts, expanding the typographic options available for displaying Quranic text within the application.
  • Enhanced Offline Download Feedback: Improved the offline page download process to accurately track and display the number of failed page downloads, providing clearer feedback to the user.
  • Tasbih Counter Improvements: The Tasbih counter now supports an 'infinite' target option and features an updated UI for dhikr text display, including inline edit/delete actions and a new Sura/Ayah picker for linking dhikr to specific Quranic verses.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces significant new features, including deep linking for ayahs and .mrec files, and includes a major and very welcome refactoring of the Recordings screen. The code is now much more modular and maintainable, with logic extracted into custom hooks and separate components. The UI has also been improved across several screens.

My review has identified a couple of critical issues related to placeholder values in the deep linking configuration files that must be addressed before deployment. I've also included a couple of medium-severity suggestions for improving robustness and state management.

"apps": [],
"details": [
{
"appIDs": ["TODO_TEAM_ID.wino.ma.mushaf.mauri"],

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

critical

This file contains a placeholder TODO_TEAM_ID. This must be replaced with the actual Apple Developer Team ID for Universal Links to work correctly on iOS. Without it, deep linking from the website will fail.

"namespace": "android_app",
"package_name": "wino.ma.mushaf.mauri",
"sha256_cert_fingerprints": [
"TODO:REPLACE_WITH_YOUR_SIGNING_KEY_SHA256_FINGERPRINT"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

critical

This file contains a placeholder TODO:REPLACE_WITH_YOUR_SIGNING_KEY_SHA256_FINGERPRINT. This must be replaced with the SHA256 fingerprint of your app's signing key for App Links to work correctly on Android. Without it, deep linking from the website will fail.

Comment thread App.tsx
if (!url) return;
try {
// Handle .mrec file URIs
if (url.endsWith(".mrec") || url.includes("mrec")) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The condition url.includes("mrec") is a bit broad and could potentially match URLs that are not intended to be treated as .mrec files (e.g., if 'mrec' appears as part of a path segment). It would be more robust to use a regular expression to check for the .mrec extension at the end of the path, before any query parameters or hash.

Suggested change
if (url.endsWith(".mrec") || url.includes("mrec")) {
if (/\.mrec($|\?|#)/.test(url)) {



// Show the "switch to text mode" hint at most once per app session
let textModeHintShown = false;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Using a global mutable variable textModeHintShown can lead to unpredictable behavior, especially in React's concurrent mode, and makes the component harder to test. It's better to manage session-level state like this within your state management solution (e.g., Zustand). You could add a property to your store to track if the hint has been shown.

…sionCode 14

- Language cards back to original design (nativeLabel + label, no flags)
- Tamazight moved to 5th position (after Spanish)
- Welcome screen shows once only (removed debug override)
- Set android versionCode=14, slug=mushaf-mauri-v3

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant