No description
  • Dart 86.5%
  • Python 5%
  • C++ 2.6%
  • CMake 1.9%
  • Shell 1.6%
  • Other 2.4%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
2026-09-19 10:33:38 +02:00
android feat: add advertising id in the manifest for analytics 2026-08-27 15:34:01 +02:00
assets chore: fastlane Play upload pipeline + ignore generated screenshots 2026-08-17 20:39:30 +02:00
communication/2026/08/search-for-testers feat: improve long description for stores 2026-08-28 13:17:24 +02:00
docs docs: refresh expected container dex md5 for 1.0.6 2026-09-19 10:33:38 +02:00
fastlane release: 1.0.6+7 — version bump, release notes, store changelogs 2026-09-19 10:11:35 +02:00
fdroid/metadata feat: improve long description for stores 2026-08-28 13:17:24 +02:00
fonts feat: transfer project from monorepo (loss of history) 2026-08-16 16:38:35 +02:00
ios feat: transfer project from monorepo (loss of history) 2026-08-16 16:38:35 +02:00
lib fix: keep snooze usable through ring-window stalls and analytics contention 2026-09-19 09:50:11 +02:00
linux feat: transfer project from monorepo (loss of history) 2026-08-16 16:38:35 +02:00
macos feat: prepare for fdroid distribution 2026-08-18 13:36:58 +02:00
test fix: keep snooze usable through ring-window stalls and analytics contention 2026-09-19 09:50:11 +02:00
tool feat: add on device testing integration 2026-08-24 16:58:22 +02:00
web feat: transfer project from monorepo (loss of history) 2026-08-16 16:38:35 +02:00
windows feat: prepare for fdroid distribution 2026-08-18 13:36:58 +02:00
.gitignore fix: ignore the screenshot failures 2026-09-02 10:39:03 +02:00
.metadata feat: transfer project from monorepo (loss of history) 2026-08-16 16:38:35 +02:00
analysis_options.yaml fix: keep snooze usable through ring-window stalls and analytics contention 2026-09-19 09:50:11 +02:00
firebase.json feat: transfer project from monorepo (loss of history) 2026-08-16 16:38:35 +02:00
justfile fix: keep snooze usable through ring-window stalls and analytics contention 2026-09-19 09:50:11 +02:00
l10n.yaml feat: implement localisation 2026-08-16 20:58:50 +02:00
LICENSE feat: transfer project from monorepo (loss of history) 2026-08-16 16:38:35 +02:00
PRIVACY_POLICY.md feat: add advertising id in the manifest for analytics 2026-08-27 15:34:01 +02:00
pubspec.google.yaml release: 1.0.6+7 — version bump, release notes, store changelogs 2026-09-19 10:11:35 +02:00
pubspec.lock fix: pin pubspec.lock to the F-Droid container toolchain (Flutter 3.44.8) 2026-09-19 10:21:16 +02:00
pubspec.yaml release: 1.0.6+7 — version bump, release notes, store changelogs 2026-09-19 10:11:35 +02:00
README.md feat: create new release version 1.05 (6) 2026-08-27 14:34:18 +02:00
RELEASE_NOTES.md release: 1.0.6+7 — version bump, release notes, store changelogs 2026-09-19 10:11:35 +02:00
RELEASE_VERSION.md fix: build FOSS reference APK in the F-Droid buildserver container 2026-08-20 07:51:19 +02:00

SoftWakeup

A morning alarm for people who cannot wake up easily — gentle to wake to, impossible to sleep through.

Most alarms start the day with a small heart attack: a brutal ring, a rushed hand hunting the snooze button, guilt, repeat. SoftWakeup is built for heavy sleepers and serial snoozers, and takes another path: instead of dragging you out of sleep, it carries you out of it.

Screenshots

Home — your mornings at a glance Better alarm — the soft wake-up editor
Home screen Better alarm editor

The idea: a cocoon, not a siren

Well before the real alarm, SoftWakeup starts a soft wake-up: gentle audio — birdsong, breeze, soft chimes, or a sound of your own — played quietly, without repeating, requiring nothing from you. No button to press, no decision to make half-asleep. You hear it, you drift, you surface. Your body learns that morning is approaching, and when the firm alarm finally rings, you are already halfway awake.

And even your snooze is part of the plan instead of a defeat: the wake-up returns at a gentle cadence, a little firmer each time, until you are up.

A "Better alarm", at a glance

  • Wake-up time — the deadline. The firm alarm that always rings.
  • Soft wake-up — begins as many minutes before as you choose, with gentle audio that plays on its own. No user intervention needed.
  • Snooze cadence — the soft sequence repeats at that interval with a crescendo across iterations, up to the normal alarm.
  • Repeats — once, on chosen weekdays, or every day.

Everything is resolved when the alarm is armed, and the operating system itself owns every step of the morning — the sequence plays even if the app is not running.

Prefer it plain? A Simple alarm — one time, flat identical snoozes — is always available.

Your morning, your sounds

  • A bundled ringtone library for the firm alarm and the soft wake-up, with tap-to-preview.
  • Import your own audio: any sound on your device can become a wake-up voice, kept in the app's private library.
  • Per-alarm and per-step volume, gentle ramps, and a cross-iteration crescendo.
  • Labels, an on/off switch per alarm, and a "next ring" hint on every card.

Languages

SoftWakeup is fully localised and follows the device/system language. It currently ships in eight European languages:

Language Locale
English en
German de
French fr
Spanish es
Italian it
Portuguese pt
Dutch nl
Polish pl

If the device language is not among these, the app falls back to English. Translations live in lib/l10n/*.arb and are compiled with flutter gen-l10n (see l10n.yaml). Two gates keep the app fully translated: a CI check (just l10n-check) and a completeness test (test/l10n/completeness_test.dart) both fail the build if any string is missing a translation — so no untranslated text can ever ship.

Reliable by design

SoftWakeup has one rule that outranks all others: the alarm rings, always.

  • The OS schedules everything. On Android and iOS the wake-up chain is handed to the operating system's own scheduler — never to an in-app timer. Android rings with the app killed, the screen locked and under Doze, and re-arms after reboot.
  • The ring path needs nothing. Every sound, volume and step is resolved at arm time and travels with the alarm; there is nothing to look up — and therefore nothing to fail — at ring time.
  • Never silent. If an imported audio file is missing, the alarm falls back to a bundled tone. A missing file is never a silent morning.
  • Stopping is deliberate. Swiping the app away while it rings does not silence it; only a conscious action — the ring screen or the notification's Stop/Snooze — ends the ringing.
  • Self-healing. On start, SoftWakeup reconciles itself with the OS scheduler and re-arms anything the OS lost.

Platform honesty: iOS may refuse to ring a force-killed app — an OS constraint, not a bug. In that state SoftWakeup still rings with a bundled notification tone. Android has no such constraint.

Platforms

  • Android — the full experience; rings even when the app is not running.
  • iOS — Not yet tested, I do not have a mac. Full experience while the app is alive; best-effort bundled notification tone when force-killed (OS constraint).
  • Linux — a desktop companion for development; rings only while the app is open.

Under the hood

Built with Flutter and organised by domain-driven design: a pure-Dart domain (alarms, wake-up chains, repeat rules), one use case per file in the application layer, and platform adapters (OS scheduler, storage, audio) behind ports. The ring path is deliberately boring: everything an alarm needs is resolved at arm time, and the test suite doubles as the executable specification of the behaviour described above.

Localisation uses the standard Flutter stack — flutter_localizations + intl + ARB files compiled by flutter gen-l10n — with a context.l10n extension for ergonomic access and a completeness gate that keeps every locale in sync.

Build it yourself

SoftWakeup is a standard Flutter project (in soft_wakeup/):

cd soft_wakeup
flutter pub get
flutter run                # any connected device or desktop target

Release builds:

flutter build apk          # Android
flutter build ios          # iOS (requires macOS + Xcode)
flutter build linux        # Linux desktop companion

Prerequisites: the Flutter stable channel plus the usual toolchain for each target (Android SDK, Xcode, or a Linux desktop toolchain). The Linux target additionally needs the GStreamer development headers (libgstreamer1.0-dev, libgstreamer-plugins-base1.0-dev).

Quality gate: flutter test — the tests are the specification — and flutter analyze.

To run the Linux desktop companion in a specific language (for testing localisation):

just run-linux-lang fr_FR.UTF-8   # French
# also: de_DE, es_ES, it_IT, pt_PT, nl_NL, pl_PL

(The Flutter Linux embedder resolves the locale via GLib, which gives the LANGUAGE environment variable priority over LANG; the recipe sets both, so a leftover LANGUAGE=en_US cannot force English.)

Distribution

SoftWakeup ships in two builds from one codebase:

  • FOSS (F-Droid) — the default build. No Firebase, no analytics, no crash reporting: the analytics/crashlytics ports are wired to no-op implementations. This is what F-Droid builds directly from the source repo.
  • Play (Google Play) — the same app plus Firebase Analytics, Crashlytics, and Remote Config. Built by our CI, which swaps in pubspec.google.yaml and sets PLAY_BUILD=true.

The split is pinned by test/fdroid_flavor_test.dart so Firebase can never leak back into the FOSS build. Build either flavour with:

just apk-foss    # FOSS APK (F-Droid)
just apk-play    # Play APK (Firebase)
just aab-foss    # FOSS App Bundle
just aab-play    # Play App Bundle (Google Play)

F-Droid store metadata (icon, feature graphic, and phoneScreenshots/1.png … 6.png) lives in fastlane/metadata/android/en-US/ and is committed to the repo — F-Droid reads it from source. The screenshots are downscaled to 720 px wide to keep the repository small.

Contributing

This project is not currently set up for collaboration — it is a personal project, and external contributions are not being accepted at this time. This may change in the future; if and when it does, this section will be updated with the contribution guidelines.

License

GPL-3.0 — see LICENSE.