Files
jamshalat-diary/PRD.md
dwindown faadc1865d feat: Murattal player enhancements & prayer schedule auto-scroll
- Murattal: Spotify-style 5-button controls [Shuffle, Prev, Play, Next, Playlist]
- Murattal: Animated 7-bar equalizer visualization in player circle
- Murattal: Unsplash API background with frosted glass player overlay
- Murattal: Transparent AppBar with backdrop blur
- Murattal: Surah playlist bottom sheet with full 114 Surah list
- Murattal: Auto-play disabled on screen open, enabled on navigation
- Murattal: Shuffle mode for random Surah playback
- Murattal: Photographer attribution per Unsplash guidelines
- Dashboard: Auto-scroll prayer schedule to next active prayer
- Fix: setState lifecycle errors on Reading & Murattal screens
- Setup: flutter_dotenv, cached_network_image, url_launcher deps
2026-03-13 15:42:17 +07:00

885 lines
32 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Product Requirements Document
## Jamshalat Diary — Islamic Worship Companion App
**Version:** 1.0
**Date:** March 2026
**Platform:** Flutter (iOS + Android)
**Status:** Draft
---
## Table of Contents
1. [Overview](#1-overview)
2. [Target Users](#2-target-users)
3. [Design System](#3-design-system)
4. [App Architecture](#4-app-architecture)
5. [Navigation](#5-navigation)
6. [Feature Specifications](#6-feature-specifications)
- 6.1 Dashboard
- 6.2 Prayer Calendar (Imsakiyah)
- 6.3 Daily Checklist
- 6.4 Dzikir
- 6.5 Reports (Laporan)
- 6.6 Qibla Finder
- 6.7 Quran Reading
- 6.8 Quran Murattal
- 6.9 Settings
7. [Data Model](#7-data-model)
8. [Third-Party Dependencies](#8-third-party-dependencies)
9. [Non-Functional Requirements](#9-non-functional-requirements)
10. [Permissions](#10-permissions)
11. [Out of Scope (v1.0)](#11-out-of-scope-v10)
---
## 1. Overview
**Jamshalat Diary** is an offline-first Muslim daily worship companion app built in Flutter. It helps Muslim users track their daily prayers, worship habits, and spiritual growth with a clean, modern UI that supports both light and dark themes.
**Core value proposition:**
- Never miss a prayer — real-time prayer time countdowns with Adhan/Iqamah notifications
- Track daily worship completion — checklist for Sholat, Tilawah, Dzikir
- Build consistent habits — weekly/monthly progress reports
- All-in-one Islamic toolkit — Qibla compass, Quran reader, Murattal player, Dzikir counter
---
## 2. Target Users
**Primary:** Muslim adults (1845) who want to improve consistency in daily worship
**Secondary:** Parents tracking worship habits for the family
**User goals:**
- Know exact prayer times for their location, offline
- Get reminded for Adhan and Iqamah
- Log daily ibadah (worship) completion
- Read Quran and perform guided Dzikir
- Find Qibla direction while traveling
- Review worship quality over time
---
## 3. Design System
### 3.1 Color Tokens
| Token | Light Value | Dark Value | Usage |
|---|---|---|---|
| `primary` | `#70df20` | `#70df20` | Active states, CTAs, progress fills |
| `background` | `#f7f8f6` | `#182111` | App background |
| `surface` | `#ffffff` | `#1e2a14` | Cards, bottom nav |
| `sage` | `#728764` | `#728764` | Secondary text, section labels |
| `cream` | `#f2f4f0` | — | Dividers, borders (light mode) |
| `on-primary` | `#0a1a00` | `#0a1a00` | Text on primary bg |
| `text-primary` | `#1a2a0a` | `#f2f4f0` | Body text |
| `text-secondary` | `#64748b` | `#94a3b8` | Captions, labels |
| `error` | `#ef4444` | `#f87171` | Error states |
| `success` | `#22c55e` | `#4ade80` | Success/completed states |
### 3.2 Typography
| Style | Font | Weight | Size | Usage |
|---|---|---|---|---|
| `displayLarge` | Plus Jakarta Sans | 800 (ExtraBold) | 32sp | Hero numbers (next prayer) |
| `headlineMedium` | Plus Jakarta Sans | 700 (Bold) | 24sp | Screen titles, section headers |
| `titleMedium` | Plus Jakarta Sans | 600 (SemiBold) | 16sp | Card titles, nav labels |
| `bodyLarge` | Plus Jakarta Sans | 400 (Regular) | 16sp | Body text |
| `bodySmall` | Plus Jakarta Sans | 400 (Regular) | 12sp | Captions, timestamps |
| `labelSmall` | Plus Jakarta Sans | 700 (Bold) | 10sp | Uppercase tags, section labels |
| `arabicBody` | Amiri | 400 (Regular) | 24sp | Quran verses, Dzikir Arabic text |
| `arabicLarge` | Amiri | 700 (Bold) | 28sp | Surah headings in Arabic |
### 3.3 Spacing & Shape
| Token | Value | Flutter |
|---|---|---|
| `radiusSm` | 8dp | `BorderRadius.circular(8)` |
| `radiusMd` | 12dp | `BorderRadius.circular(12)` |
| `radiusLg` | 16dp | `BorderRadius.circular(16)` |
| `radiusXl` | 24dp | `BorderRadius.circular(24)` |
| `radiusFull` | 9999dp | `StadiumBorder()` |
| `spacingXs` | 4dp | — |
| `spacingSm` | 8dp | — |
| `spacingMd` | 16dp | — |
| `spacingLg` | 24dp | — |
| `spacingXl` | 32dp | — |
### 3.4 Iconography
- **Library:** Material Symbols Outlined (via `material_symbols_icons` Flutter package)
- **Filled variant:** Used for active bottom nav tab icons only
- **Size:** 24dp default, 20dp for compact rows, 32dp for feature section icons
### 3.5 Dark Mode
- Toggled via user preference in Settings (stored locally)
- Options: **Light**, **Dark**, **System (Auto)**
- Implemented via Flutter `ThemeMode``ThemeMode.light`, `ThemeMode.dark`, `ThemeMode.system`
- All color tokens have explicit light and dark values; no transparency hacks
---
## 4. App Architecture
### 4.1 Structure
```
lib/
├── main.dart
├── app/
│ ├── app.dart # MaterialApp.router + theme + locale
│ ├── router.dart # GoRouter — shell route for bottom nav
│ └── theme/
│ ├── app_theme.dart # ThemeData light + dark
│ ├── app_colors.dart # AppColors class with static consts
│ └── app_text_styles.dart # TextTheme definitions
├── core/
│ ├── widgets/
│ │ ├── bottom_nav_bar.dart
│ │ ├── prayer_time_card.dart
│ │ ├── section_header.dart
│ │ ├── ios_toggle.dart
│ │ ├── progress_bar.dart
│ │ └── circular_progress_indicator_custom.dart
│ ├── utils/
│ │ ├── date_utils.dart
│ │ ├── prayer_utils.dart # Hijri date conversion helpers
│ │ └── arabic_utils.dart # RTL text helpers
│ └── providers/
│ └── theme_provider.dart # ThemeMode state via Riverpod
├── features/
│ ├── dashboard/
│ │ ├── data/
│ │ ├── domain/
│ │ └── presentation/
│ │ ├── dashboard_screen.dart
│ │ └── widgets/
│ ├── imsakiyah/
│ ├── checklist/
│ ├── dzikir/
│ ├── laporan/
│ ├── qibla/
│ ├── quran/
│ │ ├── presentation/
│ │ │ ├── quran_screen.dart # Surah list
│ │ │ ├── quran_reading_screen.dart
│ │ │ └── quran_murattal_screen.dart
│ └── settings/
└── data/
├── local/
│ ├── hive_boxes.dart # Box names constants
│ └── adapters/ # Hive TypeAdapters
└── services/
├── prayer_service.dart # Adhan calculation
├── location_service.dart # GPS + last known
├── notification_service.dart
└── quran_service.dart # Local JSON asset
```
### 4.2 State Management
**Riverpod** (flutter_riverpod + riverpod_annotation + riverpod_generator)
- Every feature has its own `*_provider.dart`
- Async data via `AsyncNotifierProvider`
- UI state (loading, error, data) handled via `AsyncValue`
- Theme mode via `StateProvider<ThemeMode>`
### 4.3 Local Storage
**Hive** for offline-first persistence:
| Box | Key | Value type |
|---|---|---|
| `settings` | String key | dynamic |
| `checklist_items` | date string (yyyy-MM-dd) | `List<ChecklistItem>` |
| `worship_logs` | date string | `WorshipLog` |
| `dzikir_counters` | dzikir ID | int count |
| `cached_prayer_times` | `lat_lng_date` | `PrayerTimes` |
---
## 5. Navigation
### 5.1 Bottom Navigation Bar (5 tabs)
| Index | Label | Icon (inactive) | Icon (active) | Route |
|---|---|---|---|---|
| 0 | Home | `home_outlined` | `home` (filled) | `/` |
| 1 | Calendar | `calendar_today_outlined` | `calendar_today` | `/imsakiyah` |
| 2 | Checklist | `rule_outlined` | `rule` (filled) | `/checklist` |
| 3 | Reports | `bar_chart_outlined` | `bar_chart` | `/laporan` |
| 4 | Tools | `auto_fix_high_outlined` | `auto_fix_high` (filled) | `/tools` |
- Bottom nav is persistent across all 5 tabs (shell route via GoRouter)
- Safe area padding (bottom) applied to nav bar (`pb: 24dp`)
- Active tab: `primary` text + filled icon
- Inactive tab: `text-secondary` color
### 5.2 Full Route Map
```
/ → DashboardScreen
/qibla → QiblaScreen (push, no bottom nav)
/imsakiyah → ImsakiyahScreen
/checklist → ChecklistScreen
/laporan → LaporanScreen
/tools → ToolsScreen (hub for Dzikir, Quran, Qibla)
/tools/dzikir → DzikirScreen
/tools/quran → QuranListScreen
/tools/quran/:surahId → QuranReadingScreen
/tools/quran/:surahId/murattal → QuranMurattalScreen
/tools/qibla → QiblaScreen
/settings → SettingsScreen (push from Dashboard header)
```
---
## 6. Feature Specifications
---
### 6.1 Dashboard
**Route:** `/`
**Description:** App home screen showing next prayer, daily prayer schedule, checklist summary, and weekly progress.
#### UI Components
**Header (sticky)**
- Left: Circular user avatar (40dp, primary border 2dp) + greeting text ("Welcome back," / user name "Assalamu'alaikum, [Name]")
- Right: Notification bell `IconButton` → opens notification settings
**Next Prayer Hero Card**
- Full-width card, `bg-primary`, `borderRadius: 24dp`, `padding: 20dp`, `boxShadow: lg`
- Content:
- Label: "Next Prayer" with `schedule` icon
- Title: `"{PrayerName} at {HH:mm}"``displayLarge` weight 800
- Subtitle: `"Countdown: HH:mm:ss"` — live countdown timer updating every second
- Actions row:
- "View Qibla" button (`black bg`, `white text`, `explore icon`, `borderRadius: full`)
- Volume/mute toggle button (`white/30 backdrop-blur`, `rounded-full`)
- Decorative: white/20 blurred circle blob (top-right, size 120dp)
**Prayer Times Horizontal Scroll**
- Section title: "Daily Prayer Times" + "Today" chip (`primary/10 bg`, `primary text`)
- Horizontal `ListView.builder`, no scroll indicator, `padding: 16dp horizontal`
- Each card: `width: 112dp`, `borderRadius: 16dp`, `border: primary/10`
- Icon (Material Symbol): Fajr→`wb_twilight`, Dhuhr→`wb_sunny`, Asr→`filter_drama`, Maghrib→`wb_twilight`, Isha→`dark_mode`
- Prayer name (`sm font-bold`)
- Time string (`xs text-secondary`)
- **Active prayer card:** `bg-primary/10`, `border-2 border-primary`, primary text color
- **Adhan/Iqamah variant:** Active card shows notification badge (small bell icon, white circle, shadow, absolute top-right)
**Daily Checklist Summary Card**
- Title: "Today's Checklist" + subtitle "{n} dari {total} Ibadah selesai"
- Circular SVG progress indicator (48dp, `strokeWidth: 4`, `primary` stroke)
- Percentage text centered inside circle
- 2 preview items: "Sholat Fardhu (4 of 5)" and "Tilawah Quran (1 Juz)"
- Completed items: `check_circle` icon in `primary` color
- "View Full Checklist" CTA button → navigates to `/checklist`
**Weekly Progress Chart**
- Title: "Weekly Progress"
- `Container` with `bg-surface`, `borderRadius: 16dp`, `padding: 20dp`
- 7 vertical bars (MonSun): each bar is `Expanded`, `bg-primary/20`, with `primary` fill overlay proportional to completion %
- Day labels below each bar: `10sp`, `font-bold`, `text-secondary`
#### Behavior
- Countdown timer refreshes every 1 second via `Timer.periodic`
- Prayer times are calculated from device location via `adhan` package on app start
- If location unavailable, use last cached location; if none, prompt user
- Notification badge on prayer card: shown when Adhan has been called (within current window)
- Tapping the Next Prayer card → navigates to Imsakiyah screen
#### Acceptance Criteria
- [ ] Correct prayer times displayed for device's current GPS location
- [ ] Countdown shows real-time seconds tick
- [ ] Active prayer card highlighted with `primary` border and color
- [ ] Checklist summary reflects today's actual completion state from local storage
- [ ] Weekly chart bars reflect daily worship logs from past 7 days
- [ ] Works fully offline (cached prayer times used when no internet)
---
### 6.2 Prayer Calendar (Imsakiyah)
**Route:** `/imsakiyah`
**Description:** Full Hijri-calendar view of prayer times, organized by month, with location selection.
#### UI Components
**Header**
- Back arrow + "Prayer Calendar" (centered, `headlineMedium`) + `more_vert` menu button
**Month Selector**
- Horizontal scrolling chip row (no scrollbar)
- Selected: `bg-primary`, `text-slate-900`, `font-semibold`, `borderRadius: full`
- Unselected: `bg-surface`, `text-secondary`, `borderRadius: full`
- Months shown in Hijri format: "Ramadan 1445H", "Shawwal 1445H", etc.
**Location Card**
- `bg-surface`, `borderRadius: 16dp`, `border: 1dp`
- `location_on` icon (primary) + "Your Location" label + city name (e.g., "Jakarta, Indonesia")
- `expand_more` chevron — tapping opens city search/picker
**Prayer Times Table**
- 7-column grid: Day | Fajr | Sunrise | Dhuhr | Asr | Maghrib | Isha
- Header row: `bg-primary/10`, `10sp font-bold uppercase tracking-wider text-secondary`
- Data rows: alternating subtle bg for readability
- Today's row: highlighted with `primary/5` background, bold text
#### Behavior
- Loads prayer times for entire selected month using `adhan` package
- Location defaults to last GPS fix; editable via city search
- City search: local bundled list of major Indonesian cities (offline), Geocoding API optional
- Changing month or location recalculates and re-renders table
- Scroll position resets to today's row on initial load
#### Acceptance Criteria
- [ ] Displays complete monthly prayer timetable for selected Hijri month
- [ ] Today's row is visually highlighted
- [ ] Month chip scroll updates table data
- [ ] Location change triggers recalculation
- [ ] Works offline with bundled city coordinates
---
### 6.3 Daily Checklist
**Route:** `/checklist`
**Description:** Daily worship completion tracker with custom checklist items and progress visualization.
#### UI Components
**Header**
- "Daily Worship" (`headlineMedium`) + date string ("Tuesday, 24 Oct") + calendar icon button (date picker)
**Progress Card**
- `bg-slate-900 / bg-primary/10 (dark)`, `borderRadius: 16dp`, `padding: 20dp`
- Decorative `auto_awesome` icon (64sp, opacity 10%, top-right)
- "Today's Goal" label (`xs uppercase tracking-wider text-slate-400`)
- Percentage: "{n}% Complete" (`displayLarge font-bold white`)
- "{completed} / {total} Tasks" (`primary color xs`)
- Progress bar: `h-12dp`, `bg-white/10`, `primary fill`, `borderRadius: full`
- Motivational quote text below bar (`xs text-slate-300`)
**Task List**
Section header: "Religious Tasks" (`sm font-bold uppercase tracking-widest text-secondary`)
Each checklist item:
- `Container` with `bg-surface / bg-primary/5 (dark)`, `borderRadius: 12dp`, `border: 1dp`
- Custom checkbox: 24dp square, `border-2 border-primary/30`, `borderRadius: 6dp`
- Checked state: `bg-primary`, white checkmark SVG inside
- Task label: `bodyLarge font-medium`
- Optional: sub-label (e.g., target count for Tilawah)
**Default checklist items (seeded on first launch):**
| Item | Category | Default Target |
|---|---|---|
| Sholat Fajr | Sholat Fardhu | 1x |
| Sholat Dhuhr | Sholat Fardhu | 1x |
| Sholat Asr | Sholat Fardhu | 1x |
| Sholat Maghrib | Sholat Fardhu | 1x |
| Sholat Isha | Sholat Fardhu | 1x |
| Tilawah Quran | Tilawah | 1 Juz |
| Dzikir Pagi | Dzikir | 1 session |
| Dzikir Petang | Dzikir | 1 session |
| Sholat Sunnah Rawatib | Sunnah | 1x |
| Shodaqoh | Charity | 1x |
#### Behavior
- Checklist resets daily at midnight (new date key in Hive)
- Checking/unchecking an item updates Hive immediately (no "save" button)
- Progress card and percentage update reactively via Riverpod
- Motivational quotes rotate from a bundled list
- User can add/remove/reorder checklist items (edit mode)
- Completion data written to `worship_logs` for use by Reports feature
#### Acceptance Criteria
- [ ] Default 10 items seeded on first launch
- [ ] Checking item updates progress bar + percentage in real time
- [ ] Data persists across app restarts (Hive)
- [ ] New empty checklist created automatically on date change
- [ ] Historical completion accessible by Reports feature
---
### 6.4 Dzikir
**Route:** `/tools/dzikir`
**Description:** Guided morning and evening remembrance (Dzikir) with Arabic text, transliteration, translation, and tap counter.
#### UI Components
**Header (sticky)**
- `back arrow` + "Dzikir Pagi & Petang" (centered, `titleLarge font-bold`) + `info` icon button
- `bg-surface/80`, `backdropFilter: blur(12dp)`, `borderBottom: 1dp primary/10`
**Tab Bar**
- 2 tabs: "Pagi" (Morning) and "Petang" (Evening)
- Active tab: `border-bottom-2 border-primary`, `text-primary`, `font-semibold`
- Inactive tab: `text-secondary`
**Hero Banner**
- `text-center`, `padding: 32dp vertical`
- `bg-gradient(primary/5 → transparent, top → bottom)`
- Title: "Dzikir Pagi / Petang" (`headlineMedium font-bold`)
- Subtitle: context text in Indonesian (`bodySmall text-secondary max-width: 280dp`)
**Dzikir Cards (scrollable list)**
- Each card: `bg-surface`, `borderRadius: 16dp`, `border: 1dp primary/10`, `padding: 20dp`, `margin: 8dp bottom`
- **Arabic text** (`Amiri font`, `24sp`, `RTL direction`, `line-height: 2.0`, `text-right`)
- **Transliteration** (`bodySmall`, `italic`, `text-secondary`, `mt: 12dp`)
- **Translation (Indonesian)** (`bodyMedium`, `text-primary`, `mt: 8dp`)
- **Counter row:**
- "Dibaca: {count} / {target}x" label
- `+` tap button (`bg-primary/10`, `text-primary`, `borderRadius: full`, `size: 40dp`)
- Counter increments on tap; fills to target
- When target reached: button becomes `check_circle` (green), card shows completion glow
#### Behavior
- Default content: bundled local JSON with standard Dzikir Pagi (~20 items) and Dzikir Petang (~20 items)
- Counter state persisted per dzikir per session in Hive (`dzikir_counters` box)
- Counter resets daily (tied to date)
- "Pagi" tab auto-selected between Fajr and Dhuhr; "Petang" between Maghrib and Isha; user can override
- Info button → bottom sheet with brief explanation of dzikir practice
#### Acceptance Criteria
- [ ] Arabic text renders correctly with Amiri font, RTL direction
- [ ] Tap counter increments and persists within the day
- [ ] Counter resets the next day
- [ ] Tab switches between Pagi and Petang content
- [ ] Completion state shown when all counters reach target
---
### 6.5 Reports (Laporan)
**Route:** `/laporan`
**Description:** Visual analytics of worship completion across weekly, monthly, and yearly timeframes.
#### UI Components
**Header**
- Back arrow + "Worship Quality Report" (centered) + `share` icon button
**Tab Bar**
- 3 tabs: Weekly · Monthly · Yearly
- Active: `border-bottom-2 border-primary text-primary`
- Tab bar: `border-bottom: 1dp`
**Main Chart Card**
- `bg-surface`, `borderRadius: 16dp`, `border: 1dp`, `padding: 20dp`
- Header row:
- Left: `analytics` icon badge (`bg-primary/10`, `primary`, `borderRadius: 12dp`, `40dp size`)
- Center: "Daily Completion" label (`bodySmall text-secondary`) + percentage (`displayLarge font-bold`)
- Right: trend chip: `trending_up` icon + delta % (`text-emerald-500` if positive)
- **Bar Chart:**
- `height: 160dp`, flex row of 7 bars (weekly) or 30/12 bars
- Each bar: `Expanded`, `bg-primary/20` track, `bg-primary` fill overlay (proportional to % complete)
- `borderRadius: top only (full)`
- Day/date labels below (`10sp font-bold text-secondary uppercase`)
- Tapping a bar → shows tooltip with exact date + completion %
**Summary Stats Row (below chart)**
- 3 stat cards in a row:
- Best streak: "{n} days" + `local_fire_department` icon
- Average: "{n}%" + `percent` icon
- Total completed: "{n} tasks" + `check_circle` icon
#### Behavior
- Weekly: shows past 7 days (MonSun of current week)
- Monthly: shows all days of current month (30/31 bars, may need scroll)
- Yearly: shows 12 months as bars
- Data sourced from `worship_logs` Hive box (daily completion records)
- Share button: generates a shareable image/text summary of current period stats
#### Acceptance Criteria
- [ ] Correct bar heights proportional to actual daily completion %
- [ ] Tab switching updates chart data and labels
- [ ] Tooltip on bar tap shows date + details
- [ ] Summary stats calculated correctly from logs
- [ ] Empty state when no logs exist ("Start tracking to see your progress")
---
### 6.6 Qibla Finder
**Route:** `/tools/qibla` or `/qibla` (accessible from Dashboard hero card)
**Description:** Compass-based Qibla direction finder showing the direction of Mecca.
#### UI Components
**Header**
- Back arrow + "Qibla Finder" (centered) + `my_location` button (top-right, re-centers GPS)
**Main Content (centered)**
- Location display: `location_on` icon (primary) + city name + Qibla degree ("142.3° from North")
- **Compass widget:**
- Circular compass with N/S/E/W labels
- Rotating needle pointing to Qibla direction
- Mosque silhouette icon overlaid at compass center (fade-to-transparent mask top)
- Green pointer / arrow indicating Qibla direction
- Accuracy indicator: "High accuracy" / "Low accuracy" based on sensor confidence
#### Behavior
- Uses `flutter_qiblah` package for Qibla calculation + `flutter_compass` for device heading
- Rotates compass ring based on device orientation (sensor stream)
- Displays degree from North
- If location permission denied → prompt to enable, fallback to manual city entry
- Mosque silhouette uses a local SVG/image asset with `ShaderMask` fade
#### Acceptance Criteria
- [ ] Compass rotates smoothly with device orientation
- [ ] Qibla arrow points to correct direction based on GPS coordinates
- [ ] Works offline (no internet needed for calculation)
- [ ] Graceful fallback if compass sensor unavailable
---
### 6.7 Quran Reading
**Route:** `/tools/quran``/tools/quran/:surahId`
**Description:** Full Quran reader with Arabic text, Indonesian translation, and verse-by-verse display.
#### UI Components
**Surah List Screen (`/tools/quran`)**
- Search bar at top
- `ListView` of 114 Surahs: number badge + Arabic name + Latin name + verse count + Juz info
**Reading Screen (`/tools/quran/:surahId`)**
Header (sticky, `bg-surface/80 backdrop-blur`):
- Back arrow
- Center column: Surah name (Arabic, `Amiri`) + "Juz {n}" label + verse count
- `more_vert` menu (bookmarks, jump to verse, settings)
**Bismillah banner:** Centered, Arabic font, before verse 1 (except Surah 9)
**Verse Cards:**
- Each verse: `Container`, `bg-surface`, `borderRadius: 12dp`, `padding: 16dp`, `border: 1dp`
- Verse number badge: small circle, `bg-primary/10`, `primary text`, left-aligned
- **Arabic text:** `Amiri`, `28sp`, `RTL`, `line-height: 2.2`, right-aligned, full width
- **Transliteration** (optional, toggled in settings): `bodySmall italic text-secondary`
- **Indonesian translation:** `bodyMedium text-primary`, left-aligned, `mt: 8dp`
- Verse action row: `bookmark`, `share`, `play` (Murattal) icons
#### Behavior
- Quran data: bundled local JSON asset (`assets/quran/quran_id.json`) — 114 surahs, Arabic + Indonesian translation
- Reading position persisted per Surah (last verse read)
- Bookmarks stored in Hive
- "Play" icon on verse → navigates to Murattal screen for that Surah starting at that verse
- Font size adjustable via settings (stored preference)
#### Acceptance Criteria
- [ ] All 114 Surahs accessible
- [ ] Arabic text renders with Amiri font, correct RTL layout
- [ ] Indonesian translation displayed below each verse
- [ ] Reading position saved across app restarts
- [ ] Bookmarking a verse persists in Hive
- [ ] Works fully offline
---
### 6.8 Quran Murattal
**Route:** `/tools/quran/:surahId/murattal`
**Description:** Audio recitation player synchronized with Quran text display.
#### UI Components
**Header:** Same as Quran Reading (Surah name + Juz info)
**Quran Text:** Same as Reading screen — synchronized verse highlight follows audio playback
**Audio Player (bottom persistent panel)**
- Reciter name + surah name
- Progress slider (current position / total duration)
- `skip_previous` | `replay_10` | Play/Pause (`play_circle` / `pause_circle`, 56dp) | `forward_10` | `skip_next`
- Playback speed selector (0.75x, 1x, 1.25x, 1.5x)
- Sleep timer button
#### Behavior
- Audio source: Bundled MP3s for commonly used Surahs (short ones: Al-Fatihah, Juz Amma) — OR streamed from a free Quran audio API (e.g., mp3quran.net)
- Currently playing verse highlighted with `primary/10 bg` + left border accent
- Auto-scrolls to current verse during playback
- Background audio playback (continues when app backgrounded)
- Notification media controls shown in system tray during playback
#### Acceptance Criteria
- [ ] Audio plays and pauses correctly
- [ ] Current verse highlighted in sync with audio (best effort with timed segments)
- [ ] Background playback works (audio continues when screen off)
- [ ] System notification with media controls displayed during playback
- [ ] Playback speed adjustment works
---
### 6.9 Settings
**Route:** `/settings`
**Description:** User profile, notification preferences, display preferences, and app info.
#### UI Components
**Header (sticky)**
- Back arrow + "Settings" (`titleLarge font-bold`) + no right action
**Profile Section**
- Avatar: 64dp circle, `bg-primary/20`, `border-2 border-primary`, initials or photo
- Name: (`titleMedium font-bold`)
- Email: (`bodySmall text-secondary`)
- Edit button (`text-primary`, `edit` icon, top-right of card) → edit name/email inline
**Notification Settings Group**
Label: "NOTIFICATIONS" (`labelSmall uppercase tracking-wider sage color`)
Rows (separated by thin divider):
- **Adhan Notification** — per prayer toggle: Fajr, Dhuhr, Asr, Maghrib, Isha
- **Iqamah Reminder** — offset in minutes (default: 10 min, stepper or picker)
- **Daily Checklist Reminder** — time picker (default: 9:00 AM)
Each row: `leading icon (bg-primary/10, rounded-lg, 40dp)` + `label + subtitle` + **iOS-style toggle**
**iOS-style toggle spec:**
- Size: `51dp × 31dp`
- Track: `bg-cream (off)` / `bg-primary (on)`, `borderRadius: full`
- Thumb: `27dp` white circle, `shadow-md`, animates left↔right on toggle
- Implemented via `AnimatedContainer` + `GestureDetector`
**Display Settings Group**
Label: "DISPLAY"
Rows:
- **Dark Mode**: Light / Dark / Auto (3-way segmented control or cycle toggle)
- **Font Size**: Small / Medium / Large (affects Quran + Dzikir text)
- **Language**: Indonesian / English (UI language, not Quran translation)
**About Group**
Label: "ABOUT"
Rows:
- App Version: "Jamshalat Diary v1.0.0"
- Privacy Policy (launches in-app browser)
- Rate the App (links to store)
- Contact / Feedback
#### Behavior
- All settings persisted in Hive `settings` box immediately on change
- Dark mode change applies instantly (no restart needed) via ThemeMode Riverpod provider
- Notification toggles register/unregister `flutter_local_notifications` channels
- Iqamah offset: default 10 minutes, adjustable per prayer
- Profile name/email stored locally only (no backend account system in v1.0)
#### Acceptance Criteria
- [ ] All toggle states persisted and restored on restart
- [ ] Dark mode applies instantly with animation
- [ ] Adhan/Iqamah notifications schedule correctly based on calculated prayer times
- [ ] Notifications cancel when their toggle is turned off
- [ ] iOS-style toggle animation is smooth (no jank)
---
## 7. Data Model
### 7.1 Hive Boxes & Schemas
```dart
// Settings box (key-value)
class AppSettings {
String userName; // 'Alex Rivers'
String userEmail; // 'alex@example.com'
ThemeMode themeMode; // ThemeMode.system
double arabicFontSize; // 24.0
String uiLanguage; // 'id' | 'en'
Map<String, bool> adhanEnabled; // {'fajr': true, 'dhuhr': true, ...}
Map<String, int> iqamahOffset; // {'fajr': 15, 'dhuhr': 10, ...} in minutes
DateTime? checklistReminderTime;
double? lastLat;
double? lastLng;
String? lastCityName;
}
// Checklist box
@HiveType(typeId: 1)
class ChecklistItem {
String id; // UUID
String title; // 'Sholat Fajr'
String category; // 'sholat_fardhu'
String? subtitle; // '1 Juz'
int sortOrder;
bool isCustom; // false for default items
}
// Daily log box (keyed by 'yyyy-MM-dd')
@HiveType(typeId: 2)
class DailyWorshipLog {
String date; // '2026-03-06'
Map<String, bool> completedItems; // {'item_id': true}
int totalItems;
int completedCount;
double completionPercent;
}
// Dzikir counter box (keyed by 'dzikir_id:yyyy-MM-dd')
@HiveType(typeId: 3)
class DzikirCounter {
String dzikirId;
String date;
int count;
int target;
}
// Bookmarks box
@HiveType(typeId: 4)
class QuranBookmark {
int surahId;
int verseId;
String surahName;
String verseText; // Arabic snippet
DateTime savedAt;
}
// Cached prayer times box (keyed by 'lat_lng_yyyy-MM-dd')
@HiveType(typeId: 5)
class CachedPrayerTimes {
String key;
double lat;
double lng;
String date;
DateTime fajr;
DateTime sunrise;
DateTime dhuhr;
DateTime asr;
DateTime maghrib;
DateTime isha;
}
```
---
## 8. Third-Party Dependencies
| Package | Version | Purpose |
|---|---|---|
| `flutter_riverpod` | ^2.x | State management |
| `riverpod_annotation` | ^2.x | Code gen for providers |
| `go_router` | ^13.x | Declarative navigation |
| `hive_flutter` | ^1.x | Local key-value storage |
| `hive_generator` | ^2.x | Hive TypeAdapter codegen |
| `adhan` | ^1.x | Prayer time calculation (offline) |
| `geolocator` | ^11.x | GPS location |
| `geocoding` | ^3.x | Reverse geocoding (city name) |
| `flutter_qiblah` | ^2.x | Qibla direction calculation |
| `flutter_compass` | ^0.x | Device compass heading |
| `flutter_local_notifications` | ^17.x | Adhan + Iqamah notifications |
| `just_audio` | ^0.x | Quran Murattal audio playback |
| `audio_service` | ^0.x | Background audio + media controls |
| `google_fonts` | ^6.x | Plus Jakarta Sans |
| `material_symbols_icons` | ^4.x | Material Symbols icon set |
| `build_runner` | ^2.x | Code generation runner |
**Quran Data Sources:**
- Arabic text + Indonesian translation: bundled as `assets/quran/quran_id.json` (local, offline)
- Audio (Murattal): streamed from `https://server6.mp3quran.net/` (Mishari Al-Afasy) or bundled short Surahs
---
## 9. Non-Functional Requirements
### 9.1 Performance
- App cold start: < 2 seconds on mid-range devices (Snapdragon 700 series / Apple A14)
- Bottom nav tab switch: < 150ms
- Prayer time calculation: < 50ms (synchronous, offline)
- Quran verse list render: use `ListView.builder` (lazy loading), never `ListView` with all children
### 9.2 Offline-First
- Core features work with no internet: Dashboard, Checklist, Dzikir, Reports, Qibla, Quran Reading, Settings
- Quran Murattal: short Surahs bundled; longer Surahs require connectivity (graceful fallback shown)
- Prayer times: cached per location+date in Hive; recalculated on location change
### 9.3 Accessibility
- Minimum touch target: 48×48dp for all interactive elements
- All icons have semantic labels (`Semantics(label: ...)`)
- Arabic text has `textDirection: TextDirection.rtl` explicitly set
- Sufficient contrast ratios for both light and dark themes (WCAG AA)
### 9.4 Dark Mode
- All screens must look correct in both light and dark mode
- No hardcoded `Colors.white` or `Colors.black` — use `AppColors` tokens only
- Theme transitions are animated (Material 3 `AnimatedTheme`)
### 9.5 Localization
- v1.0: Indonesian (id) as primary language, English (en) as secondary
- Use `flutter_localizations` + `intl` package for date/number formatting
- All UI strings in `AppLocalizations` (ARB files); no hardcoded Indonesian strings in widgets
---
## 10. Permissions
| Permission | Reason | Timing |
|---|---|---|
| `ACCESS_FINE_LOCATION` (Android) / `NSLocationWhenInUseUsageDescription` (iOS) | Prayer time calculation, Qibla direction | On first Dashboard load |
| `POST_NOTIFICATIONS` (Android 13+) | Adhan and Iqamah notifications | On Settings → Notifications first toggle |
| `SCHEDULE_EXACT_ALARM` (Android 12+) | Exact Adhan notification timing | When notification enabled |
| Background audio (iOS: `audio` background mode) | Murattal background playback | On Murattal first play |
**Permission UX:**
- Never request permission without explaining why first (show rationale bottom sheet)
- Graceful degradation: if location denied → manual city picker; if notifications denied → remind once, then respect
---
## 11. Out of Scope (v1.0)
The following features are **explicitly excluded** from v1.0 to keep scope focused:
- User accounts / cloud sync (no backend, local-only)
- Social features (sharing worship progress to social media, leaderboards)
- Full Quran audio library (only short Surahs bundled/streamed)
- Quran memorization (Hafalan) mode
- Hijri calendar widget beyond Imsakiyah
- Community / forum features
- Multi-user / family tracking
- Wear OS / watchOS companion
- Widgets (home screen app widget)
- Apple Watch prayer time complication
- In-app purchases or subscriptions
- Push notifications from a server (only local scheduled notifications)
---
*PRD v1.0 — Jamshalat Diary — March 2026*