I wanted a single-page web app that turns an always-plugged-in Android phone (target: LG V30 on LineageOS 21, Android 14) into a bedside prayer-times clock. It is designed to run full-screen in a kiosk browser/WebView shell. Giant countdown to the next prayer, the five daily prayer times plus Sunrise, Gregorian + Hijri dates, and the athan plays at each prayer. To be fair, Mawaqit could work but I wanted by own spin on the theming.
Visual language: periwinkle glassmorphism on a near-black base, Ubuntu typeface, slow drifting gradients and soft cross-fades. A "night mode" collapses to true AMOLED-black between 23:00 and 05:00.
- HTML / CSS / vanilla browser JavaScript — no build step
adhan4.4.3 (vendored browser bundle atlib/adhan.js) for prayer time calculationIntl.DateTimeFormatwithislamic-umalquracalendar for the Hijri date- Ubuntu font (latin subset, woff2) vendored in
fonts/ - Intended to run in a fullscreen Android kiosk browser or WebView shell
- Open
index.htmlin Chrome to preview. - Copy the example config:
cp config.example.js config.local.js
- Edit
config.local.js:lat/lng— your exact decimal coordinatesmethod— prayer calculation method, e.g.'NorthAmerica'madhab—'Shafi'(earlier Asr) or'Hanafi'(later)timeFormat—'12h'or'24h'hijriAdjustmentDays—0,1, or-1to match local moonsightingdimAfterHour/dimUntilHour— night-mode schedule
- Confirm the two mp3 files exist in
audio/:audio/fajr.mp3— Fajr athan (has the extra "prayer is better than sleep" phrase)audio/standard.mp3— athan for Dhuhr, Asr, Maghrib, Isha
config.local.js and the audio files are ignored by Git. That keeps exact
coordinates and possibly copyrighted recordings out of public commits.
- Install Magisk: patch
boot.imgfrom the LineageOS build, flash via fastboot. - Install Advanced Charging Control (ACC) from F-Droid or
github.com/MatteCarra/AccA. - Set
shutdown capacity: 60,resume capacity: 40. Charging now cycles 40→60 indefinitely, which dramatically extends the battery's life while plugged in 24/7.
adb push . /sdcard/athan/Recommended free/open-source option: Webview Kiosk from F-Droid.
- Install Webview Kiosk from F-Droid.
- Set the start URL to:
file:///sdcard/athan/index.html - Enable fullscreen/immersive mode, keep screen on, launch on boot, and use as the default launcher if you want a locked-down bedside device.
- In Web Engine settings, disable Media playback requires user gesture. That setting is what allows the athan audio to play unattended.
- Set Android media volume, disable Do Not Disturb if needed, and lock orientation to portrait.
If WebView Kiosk shows net::ERR_ACCESS_DENIED for the file:///sdcard/...
URL, use the localhost method below instead.
Some Android WebView builds block direct file:///sdcard/... pages. The free
workaround is to run a tiny local web server on the phone with Termux.
- Install Termux from F-Droid.
- Open Termux and run:
pkg update pkg install python termux-setup-storage
- Allow the storage permission popup.
- Start the local server:
cd /sdcard/athan python -m http.server 8080 - In Webview Kiosk, use this start URL instead:
http://127.0.0.1:8080/index.html
Keep Termux running in the background. For a permanent nightstand setup, disable battery optimization for Termux so Android does not kill the local server.
Tap the screen once after setup. This primes the audio element in case your browser/WebView still requires a user gesture before audio playback.
This project is meant to run inside a kiosk browser, not plain Chrome. Normal mobile browsers are not ideal for unattended athan audio because they generally block audible autoplay until the user interacts with the page. The app includes a first-tap audio unlock, but that only helps the current browser session.
For reliable unattended playback after reboot, use one of these:
- A free/open-source WebView kiosk shell that exposes Android WebView's
mediaPlaybackRequiresUserGesturesetting, such as Webview Kiosk. - A small native Android wrapper app that loads this folder in WebView and sets media playback to not require a user gesture.
Fully Kiosk Browser can also do this, but it is not required and is intentionally not the recommended setup for this project.
- Near-black base
#0b0b1e, pure#000in night mode. - Aurora gradient drifts over 3 minutes — no region stays bright.
- Every 60s the whole stage translates ±2px on a 9-point pattern.
- Every 6h, countdown and prayer list swap vertical order.
- Night mode (23:00–05:00) dims all text to muted periwinkle.
index.html // layout
config.example.js // copy to config.local.js and edit locally
style.css // periwinkle tokens, glass, Ubuntu, animations, day/night
app.js // prayer calc, tick loop, athan trigger, burn-in shift
lib/adhan.js // vendored adhan-js 4.4.3 browser bundle
fonts/ // Ubuntu woff2 latin subset (300/400/500/700)
audio/ // drop fajr.mp3 and standard.mp3 here
| Want to change… | Edit |
|---|---|
| Location | config.local.js |
| Calculation method | config.local.js |
| Madhab / Asr timing | config.local.js |
| Hijri adjustment | config.local.js |
| Time format | config.local.js |
| Color palette | :root block in style.css |
| Glass blur strength | --glass-blur |
| Countdown / row font sizes | .countdown, .prayer-name, .prayer-time in style.css |
| Pixel-shift interval | config.local.js |
| Night-mode hours | config.local.js |
Glass blur is janky on the V30 — Snapdragon 835 struggles with backdrop-filter under some drivers. Drop --glass-blur from 12px → 8px in style.css. If still janky, remove backdrop-filter entirely and set --glass-bg: rgba(26, 26, 58, 0.55) (opaque fallback).
Athan doesn't play — check the audio files are at the exact paths
audio/fajr.mp3 and audio/standard.mp3, confirm Android media volume is up,
and disable Media playback requires user gesture in your WebView/kiosk app.
If using a normal browser, tap the screen once after launch.
To test audio immediately, open one of these URLs and tap once if playback does not start:
http://127.0.0.1:8080/index.html?testAudio=fajr
http://127.0.0.1:8080/index.html?testAudio=standard
Configuration required is showing — copy config.example.js to
config.local.js, then set numeric lat and lng values.
White bars show at the top or bottom — this is Android/Webview Kiosk system
UI, not the web page. In Webview Kiosk, set Appearance → Address Bar Mode to
Hidden, Appearance → Immersive Mode to Always On, and Appearance →
Window Insets to None.
Hijri date is off by a day — set hijriAdjustmentDays in config.local.js
to 1 or -1 to align with your local mosque's convention.
Countdown drifts — it recomputes from Date.now() each tick, so drift is impossible unless the system clock is wrong. Check Settings → System → Date & time → Automatic.
MIT for the app code. See THIRD_PARTY_NOTICES.md for vendored library/font
notices. Audio files are not included in the repository.