# sayedmdsafwan/salattime architecture

> Architecture diagram of the GitHub repository sayedmdsafwan/salattime, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-09-27). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/sayedmdsafwan/salattime
- Repository: https://github.com/sayedmdsafwan/salattime

## Overview

Salat Time is an offline Android prayer-time and Qibla app whose WebView-hosted HTML/JS is the on-screen product, with native Kotlin services extending it for a persistent home-screen widget and compass. The main flow is location and settings in the web app, recipe sync through the bridge, then native time computation and widget scheduling. The README documents city/manual location, bilingual settings, and background GPS refresh; those capabilities are represented at their documented source locations. Sampled excerpts establish key bridge, scheduler, computation, widget, and compass links; unsampled web-app internals are shown only where README supports them.

Main entry points: [`app/src/main/java/com/safwan/prayertime/AlarmScheduler.kt`](https://github.com/sayedmdsafwan/salattime/blob/main/app/src/main/java/com/safwan/prayertime/AlarmScheduler.kt) (Schedule recompute), [`app/src/main/assets/index.html`](https://github.com/sayedmdsafwan/salattime/blob/main/app/src/main/assets/index.html) (Prayer UI & logic), [`app/src/main/java/com/safwan/prayertime/MainActivity.kt`](https://github.com/sayedmdsafwan/salattime/blob/main/app/src/main/java/com/safwan/prayertime/MainActivity.kt) (WebView host), [`app/src/main/java/com/safwan/prayertime/LocationRefreshReceiver.kt`](https://github.com/sayedmdsafwan/salattime/blob/main/app/src/main/java/com/safwan/prayertime/LocationRefreshReceiver.kt) (GPS refresh receiver)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_web["Web App"]
  node_webapp["Prayer UI &amp; logic<br/>[index.html]"]
  node_location["Location inputs<br/>[index.html]"]
  node_citydb[("Offline city database<br/>[index.html]")]
  node_settings["Settings &amp; language<br/>[index.html]"]
  node_webastro["Web prayer math<br/>[index.html]"]
end

subgraph group_native["Android Native"]
  node_main["WebView host<br/>[MainActivity.kt]"]
  node_bridge["JavaScript bridge<br/>[NativeBridge.kt]"]
  node_recipe["Prayer recipe<br/>[PrayerRecipe.kt]"]
  node_tz["Timezone resolver<br/>[TzResolver.kt]"]
  node_astro["Native prayer math<br/>[Astro.kt]"]
end

subgraph group_widget["Widget Runtime"]
  node_alarms["Schedule recompute<br/>[AlarmScheduler.kt]"]
  node_prefs[("Prayer state<br/>[AlarmScheduler.kt]")]
  node_provider["Widget lifecycle"]
  node_updater["Widget rendering<br/>[WidgetUpdater.kt]"]
  node_tick["Prayer tick"]
  node_daily["Daily recompute"]
  node_timechange["Clock changes"]
  node_boot["Boot recovery<br/>[BootReceiver.kt]"]
  node_gpssched["GPS refresh schedule"]
  node_gpsrecv["GPS refresh receiver"]
end

subgraph group_compass["Qibla Compass"]
  node_sensor["Compass sensors"]
  node_dial["Compass overlay"]
end

node_user(("App user"))
node_androidloc(("Android location"))
node_androidos(("Android OS"))
node_sensors(("Device sensors"))

node_user -->|"uses"| node_webapp
node_webapp -->|"selects location"| node_location
node_location -->|"searches cities"| node_citydb
node_webapp -->|"configures"| node_settings
node_webapp -->|"computes times"| node_webastro
node_main -->|"loads"| node_webapp
node_webapp -->|"syncs recipe"| node_bridge
node_bridge -->|"builds"| node_recipe
node_bridge -->|"syncs schedule"| node_alarms
node_alarms -->|"reads"| node_recipe
node_alarms -->|"resolves offset"| node_tz
node_alarms -->|"computes days"| node_astro
node_alarms -->|"writes times"| node_prefs
node_alarms -->|"maintains"| node_gpssched
node_tz -->|"reads"| node_recipe
node_provider -->|"refreshes schedule"| node_alarms
node_provider -->|"renders widget"| node_updater
node_updater -->|"reads times"| node_prefs
node_tick -->|"recomputes"| node_alarms
node_tick -->|"refreshes widget"| node_updater
node_daily -->|"recomputes"| node_alarms
node_timechange -->|"recomputes"| node_alarms
node_boot -->|"rearms"| node_alarms
node_gpssched -->|"schedules"| node_gpsrecv
node_gpsrecv -->|"requests fix"| node_androidloc
node_gpsrecv -->|"updates recipe"| node_alarms
node_androidos -->|"drives lifecycle"| node_provider
node_androidos -->|"fires alarm"| node_tick
node_androidos -->|"fires alarm"| node_daily
node_androidos -->|"broadcasts changes"| node_timechange
node_androidos -->|"broadcasts boot"| node_boot
node_androidos -->|"fires alarm"| node_gpsrecv
node_webapp -->|"requests compass"| node_main
node_main -->|"starts and locates"| node_sensor
node_sensor -->|"reads heading"| node_sensors
node_sensor -->|"sends heading"| node_dial
node_main -->|"controls overlay"| node_dial
node_dial -->|"shows bearing"| node_user

click node_webapp "https://github.com/sayedmdsafwan/salattime/blob/main/app/src/main/assets/index.html"
click node_location "https://github.com/sayedmdsafwan/salattime/blob/main/app/src/main/assets/index.html"
click node_citydb "https://github.com/sayedmdsafwan/salattime/blob/main/app/src/main/assets/index.html"
click node_settings "https://github.com/sayedmdsafwan/salattime/blob/main/app/src/main/assets/index.html"
click node_webastro "https://github.com/sayedmdsafwan/salattime/blob/main/app/src/main/assets/index.html"
click node_main "https://github.com/sayedmdsafwan/salattime/blob/main/app/src/main/java/com/safwan/prayertime/MainActivity.kt"
click node_bridge "https://github.com/sayedmdsafwan/salattime/blob/main/app/src/main/java/com/safwan/prayertime/NativeBridge.kt"
click node_recipe "https://github.com/sayedmdsafwan/salattime/blob/main/app/src/main/java/com/safwan/prayertime/PrayerRecipe.kt"
click node_tz "https://github.com/sayedmdsafwan/salattime/blob/main/app/src/main/java/com/safwan/prayertime/TzResolver.kt"
click node_astro "https://github.com/sayedmdsafwan/salattime/blob/main/app/src/main/java/com/safwan/prayertime/Astro.kt"
click node_alarms "https://github.com/sayedmdsafwan/salattime/blob/main/app/src/main/java/com/safwan/prayertime/AlarmScheduler.kt"
click node_prefs "https://github.com/sayedmdsafwan/salattime/blob/main/app/src/main/java/com/safwan/prayertime/AlarmScheduler.kt"
click node_provider "https://github.com/sayedmdsafwan/salattime/blob/main/app/src/main/java/com/safwan/prayertime/PrayerWidgetProvider.kt"
click node_updater "https://github.com/sayedmdsafwan/salattime/blob/main/app/src/main/java/com/safwan/prayertime/WidgetUpdater.kt"
click node_tick "https://github.com/sayedmdsafwan/salattime/blob/main/app/src/main/java/com/safwan/prayertime/WidgetTickReceiver.kt"
click node_daily "https://github.com/sayedmdsafwan/salattime/blob/main/app/src/main/java/com/safwan/prayertime/DailyRecomputeReceiver.kt"
click node_timechange "https://github.com/sayedmdsafwan/salattime/blob/main/app/src/main/java/com/safwan/prayertime/TimeChangeReceiver.kt"
click node_boot "https://github.com/sayedmdsafwan/salattime/blob/main/app/src/main/java/com/safwan/prayertime/BootReceiver.kt"
click node_gpssched "https://github.com/sayedmdsafwan/salattime/blob/main/app/src/main/java/com/safwan/prayertime/LocationRefreshScheduler.kt"
click node_gpsrecv "https://github.com/sayedmdsafwan/salattime/blob/main/app/src/main/java/com/safwan/prayertime/LocationRefreshReceiver.kt"
click node_sensor "https://github.com/sayedmdsafwan/salattime/blob/main/app/src/main/java/com/safwan/prayertime/QiblaSensorController.kt"
click node_dial "https://github.com/sayedmdsafwan/salattime/blob/main/app/src/main/java/com/safwan/prayertime/QiblaCompassView.kt"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_webapp,node_location,node_citydb,node_settings,node_webastro,node_user toneBlue
class node_main,node_bridge,node_recipe,node_tz,node_astro toneAmber
class node_alarms,node_prefs,node_provider,node_updater,node_tick,node_daily,node_timechange,node_boot,node_gpssched,node_gpsrecv toneMint
class node_sensor,node_dial toneRose
class node_androidloc,node_androidos,node_sensors toneIndigo
```

## Components

### Web App

- [Prayer UI & logic](https://github.com/sayedmdsafwan/salattime/blob/main/app/src/main/assets/index.html): `app/src/main/assets/index.html`
- [Location inputs](https://github.com/sayedmdsafwan/salattime/blob/main/app/src/main/assets/index.html): `app/src/main/assets/index.html`
- [Offline city database](https://github.com/sayedmdsafwan/salattime/blob/main/app/src/main/assets/index.html): `app/src/main/assets/index.html`
- [Settings & language](https://github.com/sayedmdsafwan/salattime/blob/main/app/src/main/assets/index.html): `app/src/main/assets/index.html`
- [Web prayer math](https://github.com/sayedmdsafwan/salattime/blob/main/app/src/main/assets/index.html): `app/src/main/assets/index.html`

### Android Native

- [WebView host](https://github.com/sayedmdsafwan/salattime/blob/main/app/src/main/java/com/safwan/prayertime/MainActivity.kt): `app/src/main/java/com/safwan/prayertime/MainActivity.kt`
- [JavaScript bridge](https://github.com/sayedmdsafwan/salattime/blob/main/app/src/main/java/com/safwan/prayertime/NativeBridge.kt): `app/src/main/java/com/safwan/prayertime/NativeBridge.kt`
- [Prayer recipe](https://github.com/sayedmdsafwan/salattime/blob/main/app/src/main/java/com/safwan/prayertime/PrayerRecipe.kt): `app/src/main/java/com/safwan/prayertime/PrayerRecipe.kt`
- [Timezone resolver](https://github.com/sayedmdsafwan/salattime/blob/main/app/src/main/java/com/safwan/prayertime/TzResolver.kt): `app/src/main/java/com/safwan/prayertime/TzResolver.kt`
- [Native prayer math](https://github.com/sayedmdsafwan/salattime/blob/main/app/src/main/java/com/safwan/prayertime/Astro.kt): `app/src/main/java/com/safwan/prayertime/Astro.kt`

### Widget Runtime

- [Schedule recompute](https://github.com/sayedmdsafwan/salattime/blob/main/app/src/main/java/com/safwan/prayertime/AlarmScheduler.kt): `app/src/main/java/com/safwan/prayertime/AlarmScheduler.kt`
- [Prayer state](https://github.com/sayedmdsafwan/salattime/blob/main/app/src/main/java/com/safwan/prayertime/AlarmScheduler.kt): `app/src/main/java/com/safwan/prayertime/AlarmScheduler.kt`
- [Widget lifecycle](https://github.com/sayedmdsafwan/salattime/blob/main/app/src/main/java/com/safwan/prayertime/PrayerWidgetProvider.kt): `app/src/main/java/com/safwan/prayertime/PrayerWidgetProvider.kt`
- [Widget rendering](https://github.com/sayedmdsafwan/salattime/blob/main/app/src/main/java/com/safwan/prayertime/WidgetUpdater.kt): `app/src/main/java/com/safwan/prayertime/WidgetUpdater.kt`
- [Prayer tick](https://github.com/sayedmdsafwan/salattime/blob/main/app/src/main/java/com/safwan/prayertime/WidgetTickReceiver.kt): `app/src/main/java/com/safwan/prayertime/WidgetTickReceiver.kt`
- [Daily recompute](https://github.com/sayedmdsafwan/salattime/blob/main/app/src/main/java/com/safwan/prayertime/DailyRecomputeReceiver.kt): `app/src/main/java/com/safwan/prayertime/DailyRecomputeReceiver.kt`
- [Clock changes](https://github.com/sayedmdsafwan/salattime/blob/main/app/src/main/java/com/safwan/prayertime/TimeChangeReceiver.kt): `app/src/main/java/com/safwan/prayertime/TimeChangeReceiver.kt`
- [Boot recovery](https://github.com/sayedmdsafwan/salattime/blob/main/app/src/main/java/com/safwan/prayertime/BootReceiver.kt): `app/src/main/java/com/safwan/prayertime/BootReceiver.kt`
- [GPS refresh schedule](https://github.com/sayedmdsafwan/salattime/blob/main/app/src/main/java/com/safwan/prayertime/LocationRefreshScheduler.kt): `app/src/main/java/com/safwan/prayertime/LocationRefreshScheduler.kt`
- [GPS refresh receiver](https://github.com/sayedmdsafwan/salattime/blob/main/app/src/main/java/com/safwan/prayertime/LocationRefreshReceiver.kt): `app/src/main/java/com/safwan/prayertime/LocationRefreshReceiver.kt`

### Qibla Compass

- [Compass sensors](https://github.com/sayedmdsafwan/salattime/blob/main/app/src/main/java/com/safwan/prayertime/QiblaSensorController.kt): `app/src/main/java/com/safwan/prayertime/QiblaSensorController.kt`
- [Compass overlay](https://github.com/sayedmdsafwan/salattime/blob/main/app/src/main/java/com/safwan/prayertime/QiblaCompassView.kt): `app/src/main/java/com/safwan/prayertime/QiblaCompassView.kt`

### Other components

- **App user**
- **Android location**
- **Android OS**
- **Device sensors**

## Connections

- App user → Prayer UI & logic: uses
- Prayer UI & logic → Location inputs: selects location
- Location inputs → Offline city database: searches cities
- Prayer UI & logic → Settings & language: configures
- Prayer UI & logic → Web prayer math: computes times
- WebView host → Prayer UI & logic: loads
- Prayer UI & logic → JavaScript bridge: syncs recipe
- JavaScript bridge → Prayer recipe: builds
- JavaScript bridge → Schedule recompute: syncs schedule
- Schedule recompute → Prayer recipe: reads
- Schedule recompute → Timezone resolver: resolves offset
- Schedule recompute → Native prayer math: computes days
- Schedule recompute → Prayer state: writes times
- Schedule recompute → GPS refresh schedule: maintains
- Timezone resolver → Prayer recipe: reads
- Widget lifecycle → Schedule recompute: refreshes schedule
- Widget lifecycle → Widget rendering: renders widget
- Widget rendering → Prayer state: reads times
- Prayer tick → Schedule recompute: recomputes
- Prayer tick → Widget rendering: refreshes widget
- Daily recompute → Schedule recompute: recomputes
- Clock changes → Schedule recompute: recomputes
- Boot recovery → Schedule recompute: rearms
- GPS refresh schedule → GPS refresh receiver: schedules
- GPS refresh receiver → Android location: requests fix
- GPS refresh receiver → Schedule recompute: updates recipe
- Android OS → Widget lifecycle: drives lifecycle
- Android OS → Prayer tick: fires alarm
- Android OS → Daily recompute: fires alarm
- Android OS → Clock changes: broadcasts changes
- Android OS → Boot recovery: broadcasts boot
- Android OS → GPS refresh receiver: fires alarm
- Prayer UI & logic → WebView host: requests compass
- WebView host → Compass sensors: starts and locates
- Compass sensors → Device sensors: reads heading
- Compass sensors → Compass overlay: sends heading
- WebView host → Compass overlay: controls overlay
- Compass overlay → App user: shows bearing
