Skip to content
Merged
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
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
5 changes: 5 additions & 0 deletions .gemini/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"general": {
"previewFeatures": true
}
}
12 changes: 11 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,13 @@
## 0.0.2

* Added RTL support for `MushafReader` and `MushafTwoPageReader`.
* Optimized `PageAyahWidget` rendering to reduce GC churn.
* Improved performance of `JuzWidget`, `SurahNameWidget`, and `SurahHeaderWidget` by caching async operations.
* Refactored `MushafReaderController` for better testability.
* Added comprehensive unit and widget tests.
* Updated documentation and examples.

## 0.0.1

* TODO: Describe initial release.
* Initial release.

126 changes: 68 additions & 58 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,14 @@ Renders Quran text exactly as it appears in the printed Medina Mushaf using 605
- **604 page fonts** (QCF4_001 to QCF4_604): Each page has its own font with pre-positioned glyphs
- **1 shared font** (QCF4_BSML): Contains Bismillah, Surah names, and Juz markers

The package includes a pre-populated SQLite database with all Quran data, page layouts, and glyph mappings.
The package includes pre-populated Hive boxes with all Quran data, page layouts, and glyph mappings.

## Requirements

- Flutter SDK ≥3.8.1
- Dart SDK ≥3.8.1
- The 605 QCF4 OTF font files in `assets/otf_fonts/`
- The pre-populated `quran.db` SQLite database in `assets/`
- The pre-populated Hive boxes in `assets/hive/`

## Installation

Expand All @@ -29,36 +29,71 @@ dependencies:

## Setup

### 1. Initialize the Controller
### 1. Initialize the Library

Call once at app startup (e.g., in `main()` before `runApp`):
Call once at app startup in `main()` before `runApp`:

```dart
import 'package:flutter/material.dart';
import 'package:mushaf_reader/mushaf_reader.dart';

void main() async {
WidgetsFlutterBinding.ensureInitialized();
await MushafController.init();
await MushafReaderLibrary.ensureInitialized();
runApp(MyApp());
}
```

### 2. Display a Page
### 2. Use the Reader Widget

```dart
class QuranScreen extends StatefulWidget {
@override
State<QuranScreen> createState() => _QuranScreenState();
}

class _QuranScreenState extends State<QuranScreen> {
late final MushafReaderController _controller;

@override
void initState() {
super.initState();
_controller = MushafReaderController();
}

@override
void dispose() {
_controller.dispose();
super.dispose();
}

@override
Widget build(BuildContext context) {
return MushafReader(
controller: _controller,
onAyahTap: (info) => print('Tapped ${info.reference}'),
);
}
}
```

### 3. Display a Single Page

```dart
MushafPage(
pageNumber: 1, // 1-604
width: 400,
onAyahTap: (int ayahId) {
page: 1, // 1-604
onTapAyah: (int ayahId) {
print('Tapped ayah $ayahId');
},
)
```

### 3. Fetch Individual Ayahs
### 4. Fetch Individual Ayahs

```dart
final ayah = await MushafController.instance.getAyah(ayahId);
final controller = MushafReaderController();

final ayah = await controller.getAyah(ayahId);
print('Surah ${ayah.surah}, Ayah ${ayah.numberInSurah}');
print('Text: ${ayah.text}');
```
Expand All @@ -70,51 +105,47 @@ lib/src/
├── core/
│ ├── fonts.dart # MushafFonts - font family helpers
│ ├── extensions.dart # Model conversions, Hindu-Arabic numerals
│ └── db_init*.dart # Platform-specific DB initialization
├── data/
│ ├── database/ # Drift SQLite database
│ ├── hive/ # Hive storage implementation
│ ├── models/ # Immutable data models (Freezed)
│ └── repository/ # Data access layer with LRU caching
├── logic/
│ └── mushaf_controller.dart # Singleton API
│ └── mushaf_reader_controller.dart # Unified controller
└── presentation/
├── controllers/ # MushafPageController (selection state)
├── screens/ # MushafPage widget
├── screens/ # MushafPage, MushafReader widgets
└── widgets/ # Ayah, Basmalah, Juz, SurahHeader, etc.
```

## Database Schema

The `quran.db` contains:
The Hive boxes contain:

| Table | Description |
|-------|-------------|
| `surahs` | 114 rows: id, name, revelation type, ayah count |
| `ayahs` | 6236 rows: id, surah, number_in_surah, text, page, juz |
| `page_layouts` | Glyph positions: page, ayah_id, line_start, line_end |
| `juzs` | 30 rows: number, glyph (QCF4_BSML character) |
| `metadata` | Key-value pairs (db version, etc.) |
- `surahs`: 114 entries (id, name, glyph, etc.)
- `ayahs`: 6236 entries (id, surah, number, text, page, juz)
- `juzs`: 30 entries (number, glyph)
- `pageLayouts`: Glyph positioning data per page
- `metadata`: Key-value pairs

## Key Classes

### MushafController
Singleton entry point. Provides:
- `init()` - Initialize database (call once)
- `getPage(int)` - Returns `QuranPageModel` with all page data
- `getAyah(int)` - Returns `AyahModel` for a specific ayah
### MushafReaderController
Unified controller for navigation, state, and data access. Provides:
- `jumpToPage(int)`, `nextPage()`, `previousPage()`
- `jumpToSurah(int)`, `jumpToJuz(int)`
- `selectAyah(int)` - Highlight specific ayah
- `getPageInfo(int)` - Returns `MushafPageInfo`

### QuranPageModel
Contains everything needed to render a page:
- `pageNumber`, `glyphText` (the full page glyph string)
- `surahBlocks` - List of Surahs on this page with their Ayah fragments
- `juz` - Juz info if a new Juz starts on this page
- `hasBasmalah` - Whether to show Bismillah
- `surahs` - List of Surah blocks on this page
- `lines` - Line layout information
- `juzNumber` - Juz info

### MushafPage
The main rendering widget. Handles:
- Responsive scaling based on `width`
- Per-ayah tap detection
- Ayah highlighting
- Responsive scaling
- Per-ayah tap detection and highlighting
- Surah headers, Juz markers, Basmalah

### MushafFonts
Expand All @@ -130,7 +161,7 @@ MushafFonts.basmalahStyle // TextStyle for headers
| Platform | Database Loading |
|----------|------------------|
| iOS, Android, macOS, Windows, Linux | Copies from assets to documents directory |
| Web | Drift WASM with IndexedDB storage |
| Web | Supported via Hive |

## Customization

Expand Down Expand Up @@ -187,30 +218,9 @@ MushafPage(
)
```

### Selection State

Use `MushafPageController` with `ChangeNotifierProvider` for ayah selection:

```dart
ChangeNotifierProvider(
create: (_) => MushafPageController(),
child: Consumer<MushafPageController>(
builder: (context, controller, _) {
return MushafPage(
page: 1,
pageController: controller,
onTapAyah: (ayahId) {
// Handle tap
},
);
},
),
)
```

## Dependencies

- `drift` + `sqlite3_flutter_libs` - SQLite database
- `hive_ce` + `hive_ce_flutter` - Data storage
- `freezed_annotation` - Immutable models
- `flutter_svg` - Surah header banners
- `path_provider` - Native file paths
Expand Down
Binary file modified assets/hive/ayahs.hive
Binary file not shown.
Binary file modified assets/hive/juzs.hive
Binary file not shown.
Binary file modified assets/hive/pagelayouts.hive
Binary file not shown.
Binary file modified assets/hive/surahs.hive
Binary file not shown.
Binary file added assets/images/mainframe.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed assets/jsons/quran.db
Binary file not shown.
Loading
Loading