Skip to content

darkmoonight/Rain

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 

History

471 Commits
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

๐ŸŒฆ๏ธ Rain

A beautiful, feature-rich weather application built with Flutter

English โ€ข ะ ัƒััะบะธะน

Stars Forks Downloads Play Store Installs GitHub release License

Tired of unpredictable weather? Rain keeps you prepared with accurate forecasts, interactive maps, and beautiful design. ๐ŸŒฆ๏ธ๐Ÿ“ฑ๐Ÿ—บ๏ธ

๐ŸŒ Available in 38 languages โ€ข ๐ŸŽจ Material You & AMOLED โ€ข ๐Ÿ’จ Air quality (EU/US AQI) โ€ข ๐Ÿ—บ๏ธ Interactive weather map โ€ข ๐Ÿ“ฑ Home screen widgets


โœจ Features

๐ŸŒก๏ธ Comprehensive Weather Data

  • Real-time conditions with feels-like temperature โ€ข Hourly forecasts (12 days) โ€ข 12-day daily outlooks
  • Location-aware time: forecast slots use each place's Open-Meteo timezone and UTC offset; HTTP Date skew corrects a wrong device clock
  • Detailed metrics: UV index, humidity, wind speed/direction, precipitation, visibility, pressure, dew point
  • Day/night-aware weather icons โ€ข Sunrise/sunset times โ€ข Expandable hourly variable details

๐Ÿ’จ Air Quality

  • Hourly air quality from Open-Meteo Air Quality API (7-day forecast, aligned to weather timestamps)
  • Summary card on the main weather screen: AQI value, severity badge, colored scale, health advice
  • Pollutant breakdown with progress bars: PM2.5, PM10, Oโ‚ƒ, NOโ‚‚, SOโ‚‚, CO (ฮผg/mยณ)
  • Choose European AQI or US AQI in Settings โ€ข Cached offline with weather data

๐Ÿ—บ๏ธ Interactive Weather Map

  • OpenStreetMap-based interactive map โ€ข Weather markers for all saved cities
  • Tap markers for quick weather preview โ€ข Long-press to add new locations
  • Visual city selection with GPS support โ€ข Map tile caching (30 days) โ€ข Dark mode styling

๐Ÿ™๏ธ Multi-City Management

  • Save unlimited cities to your watchlist โ€ข Drag-to-reorder โ€ข Pull-to-refresh all
  • Live local wall clock on each city card โ€ข Correct offsets between cities even when the device clock is off
  • City search with autocomplete โ€ข Manual coordinate entry โ€ข GPS auto-detection
  • Edit or remove saved cities โ€ข Timezone from the weather API for each location

๐Ÿ”” Smart Notifications

  • Scheduled weather forecasts (1-5 hour intervals) โ€ข Custom time window (start/end)
  • Weather-condition-specific icons โ€ข Silent notifications (no sound/vibration)
  • Automatic cancellation when disabled โ€ข Background scheduling

๐Ÿ“ฑ Home Screen Widgets (Android)

  • Three Material You widgets โ€” pin any from Settings โ†’ Widget (home screen and lock screen):
    • Compact (1ร—1) โ€” weather icon and temperature, fixed size
    • Current (2ร—2) โ€” resizable card with temperature on top and weather icon at bottom-left
    • Clock (4ร—1 bar) โ€” live clock and date, weather icon, city name and temperature; horizontally resizable
  • Respects app Celsius/Fahrenheit, rounded temperature, and 12h/24h time format (Clock widget)
  • Background refresh (Workmanager, ~15 min minimum): fetches stale main weather when online, then pushes widget data โ€ข Custom background and text colors (HSV picker)
  • Updates when the app loads cached weather, after fresh fetches, and from the periodic background task

๐ŸŽจ Beautiful Design

  • Material You dynamic theming (wallpaper colors) โ€ข Pure AMOLED black theme
  • Light/Dark/System modes โ€ข Large element mode toggle โ€ข Edge-to-edge display
  • Google Fonts (Ubuntu) โ€ข Smooth animations โ€ข Shimmer loading states

๐ŸŒ Extensive Localization

  • 38 languages including: English, ะ ัƒััะบะธะน, ไธญๆ–‡, ุงู„ุนุฑุจูŠุฉ, เคนเคฟเคจเฅเคฆเฅ€, Espaรฑol, Franรงais, Deutsch, Portuguรชs, ํ•œ๊ตญ์–ด, ๆ—ฅๆœฌ่ชž, Tรผrkรงe, and many more
  • Regional preferences โ€ข 12h/24h time format support

๐Ÿงฎ Customization Options

  • Temperature: Celsius/Fahrenheit โ€ข Measurement system: Metric/Imperial
  • Wind speed: kph/m/s โ€ข Pressure: hPa/mmHg โ€ข Rounded temperatures (app + widget)
  • Air quality standard: European AQI / US AQI
  • 12h/24h time format (app, pickers, notifications, and Clock widget)
  • Widget color customization with HSV color picker

๐Ÿ“ธ Screenshots


๐Ÿ“ฅ Download

Android

Play Store IzzyOnDroid

Other Platforms

Get the latest APK or builds for other platforms from the Releases Section.


๐Ÿ› ๏ธ Building from Source

Prerequisites

  • Flutter SDK 3.44 or higher (see pubspec.yaml)
  • Dart SDK 3.12 or higher
  • Android Studio / Xcode for platform-specific builds

Steps

# Clone the repository
git clone https://github.com/darkmoonight/Rain.git
cd Rain

# Install dependencies
flutter pub get

# Generate code (Isar, Freezed, JSON, translations)
dart run slang
dart run build_runner build --delete-conflicting-outputs

# Run the app (Android uses flavor gms by default; see pubspec `default-flavor`)
flutter run
# floss on device/emulator: flutter run --flavor floss

# Build for production
flutter build appbundle --release  # Android App Bundle (Play Store)
flutter build ios --release        # iOS

Android APK

Gradle flavors gms (default, Play Store deps) and floss (no Play Services, IzzyOnDroid). Output names match GitHub Releases.

Variant Files
gms rain-release-gms.apk, rain-arm64-v8a-release-gms.apk, rain-armeabi-v7a-release-gms.apk, rain-x86_64-release-gms.apk
floss rain-release-floss.apk, rain-arm64-v8a-release-floss.apk, rain-armeabi-v7a-release-floss.apk, rain-x86_64-release-floss.apk

All APKs land in build/app/outputs/flutter-apk/ after ./scripts/rename_apk_outputs.sh.

Single APK (one ABI)

chmod +x scripts/*.sh

./scripts/build_apk.sh gms --target-platform android-arm64
./scripts/build_apk.sh floss --target-platform android-arm64

Full release set (8 APKs, both variants)

Per variant: first split APKs (--split-per-abi), then universal (no extra flags). Four builds total:

./scripts/build_release_apks.sh

Runs four builds and then ./scripts/restore_pub_default.sh (FOSS overrides must not stay in pubspec.lock for normal dev).

Same steps manually:

./scripts/build_apk.sh gms --split-per-abi
./scripts/build_apk.sh gms

./scripts/build_apk.sh floss --split-per-abi
./scripts/build_apk.sh floss

./scripts/restore_pub_default.sh

Manual FOSS build (e.g. reproducible / IzzyOnDroid)

pubspec_overrides.yaml must exist before flutter pub get. After pub get, patch the jni package so libdartjni.so is reproducible (same step as IzzyOnDroid RB):

cp tool/pubspec_overrides.floss.yaml pubspec_overrides.yaml
flutter pub get
./scripts/patch_jni_reproducible_build.sh
dart run slang && dart run build_runner build --delete-conflicting-outputs
flutter build apk --release --flavor floss --target-platform android-arm64
./scripts/rename_apk_outputs.sh floss

Equivalent one-liner for the jni patch (idempotent; set PUB_CACHE in CI):

sed -i -E 's|target_link_options\(jni PRIVATE "-Wl,[^"]*max-page-size=16384"\)|target_link_options(jni PRIVATE "-Wl,--build-id=none,-z,max-page-size=16384")|' \
  "${PUB_CACHE:-$HOME/.pub-cache}"/hosted/*/jni-*/src/CMakeLists.txt

pubspec_overrides.yaml is gitignored; pubspec.lock in the repo targets gms.

Testing

The project has 338 unit and widget tests (93 *_test.dart files) with an Isar test bootstrap and fake platform services (geocoding, home widget, path provider).

flutter test
flutter analyze

If widget tests hang, run flutter test --concurrency=1.

Optional coverage report (output in coverage/, gitignored):

flutter test --coverage

Well covered: data/domain (repos, mappers, validators), core services/utils (notifications, connectivity, location parsing, HTTP date parsing), bootstrap (AppInitializer), router redirect/cache sync, settings provider updates, cities notifier (CRUD, loadError, delete edge cases), confirmation/selection dialogs, weather widgets and notifiers, location wall clock (TimeIndexHelper, clock skew persistence), air quality (AqiHelper, AirQualityMapper, graceful AQ API fallback).

Notification regression tests: stable notification IDs (notificationIdFor), one slot per hour when duplicate daily rows exist, and MainWeatherNotifier._init not calling cancelAll() while notifications stay enabled.

Widget/screen gaps (intentionally skipped): cold-start main.dart, WorkManager, OSM tile network/cache, onboarding โ†’ home E2E, geolocation submit โ†’ full navigation E2E.

If alerts stopped after an update that fixed notification scheduling, toggle notifications off and on in Settings (Android 13+ may need to grant notification permission once).

Widget tests that hit city search or forecast APIs should use createFakeWeatherRemoteDatasource() from test/helpers/fixtures.dart so geocoding and forecast share one stubbed Dio client.

Code Generation

The project uses code generation for:

  • Isar Community โ€” local database schemas
  • Freezed โ€” immutable API models
  • JSON Serializable โ€” JSON serialization
  • Slang โ€” translations from assets/i18n/*.i18n.json

After changing models or locale files:

dart run slang
dart run build_runner build --delete-conflicting-outputs

Tech Stack (highlights)

  • Flutter + Riverpod 3 โ€ข Go Router โ€ข Isar Community
  • home_widget + Workmanager (Android widgets) โ€ข flutter_local_notifications
  • Open-Meteo Weather API โ€ข Open-Meteo Air Quality API โ€ข flutter_map + OSM tiles
  • timezone + flutter_timezone for IANA lookups and per-location wall clocks

๐ŸŒ Data Sources

Rain uses free, open weather APIs with no API key required:


๐Ÿค Contributing

We welcome contributions! Please see CONTRIBUTING.md for setup, testing, and pull request guidelines. Use the bug report or feature request templates when opening issues.


๐Ÿ’ฐ Support the Project

If Rain has become an indispensable part of your daily routine, consider supporting development:

ะฎMoney


๐Ÿ“ƒ License

This project is licensed under the MIT License.


๐Ÿ‘จโ€๐Ÿ’ป Contributors

Thanks to all our amazing contributors!


Made with โค๏ธ using Flutter