{"id":31674653,"url":"https://github.com/mambobryan/weather","last_synced_at":"2025-10-08T04:05:49.794Z","repository":{"id":225835093,"uuid":"753014339","full_name":"MamboBryan/weather","owner":"MamboBryan","description":"A weather app for getting current weather details","archived":false,"fork":false,"pushed_at":"2024-02-05T10:17:44.000Z","size":1660,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2024-03-04T16:04:01.142Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Kotlin","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/MamboBryan.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null}},"created_at":"2024-02-05T09:53:52.000Z","updated_at":"2024-03-04T16:04:17.034Z","dependencies_parsed_at":"2024-03-04T16:04:16.486Z","dependency_job_id":null,"html_url":"https://github.com/MamboBryan/weather","commit_stats":null,"previous_names":["mambobryan/weather"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/MamboBryan/weather","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MamboBryan%2Fweather","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MamboBryan%2Fweather/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MamboBryan%2Fweather/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MamboBryan%2Fweather/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/MamboBryan","download_url":"https://codeload.github.com/MamboBryan/weather/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MamboBryan%2Fweather/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":278886444,"owners_count":26062978,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-08T02:00:06.501Z","response_time":56,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-10-08T04:01:36.238Z","updated_at":"2025-10-08T04:05:49.787Z","avatar_url":"https://github.com/MamboBryan.png","language":"Kotlin","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Weather\n\nWeather is a simple Kotlin Multiplatform application built with Compose Multiplatform that gets\nweather information data for a specific city.\n\n## Features\n\n- [X] user can get today's weather data\n- [X] user can get weather data for the next 7 days\n- [X] user can get the last 14 days weather data\n\n## Design\n\n### android\n\n|                                    Loading                                    |                                    Today                                    |                                    More                                    |\n|:-----------------------------------------------------------------------------:|:---------------------------------------------------------------------------:|:--------------------------------------------------------------------------:|\n| \u003cimg src=\"images/android/loading.png\" width=\"200\" hspace=\"2\" alt=\"loading\" /\u003e | \u003cimg src=\"images/android/today.png\" width=\"200\" hspace=\"2\" alt=\"calorie\" /\u003e | \u003cimg src=\"images/android/more.png\" width=\"200\" hspace=\"2\" alt=\"calorie\" /\u003e |\n\n### iOS\n\n|                                  Loading                                  |                                  Today                                  |                                  More                                  |\n|:-------------------------------------------------------------------------:|:-----------------------------------------------------------------------:|:----------------------------------------------------------------------:|\n| \u003cimg src=\"images/ios/loading.png\" width=\"200\" hspace=\"2\" alt=\"loading\" /\u003e | \u003cimg src=\"images/ios/today.png\" width=\"200\" hspace=\"2\" alt=\"calorie\" /\u003e | \u003cimg src=\"images/ios/more.png\" width=\"200\" hspace=\"2\" alt=\"calorie\" /\u003e |\n\n## Architecture\n\nThis project uses the MVI(Model - View - Intent) architecture based on UDF(Unidirectional Data Flow)\nand Reactive programming.\n\nWhy?\n\n- more clear and intentional separation of concerns\n- single source of truth for our UI state which can only be mutated by intent/actions\n- simpler and more direct UI testability, since we can define how the UI should look like with our\n  state objects\n\n### Packaging Structure\n\n- `sources`\n    - `remotesource`\n        - handles getting data from any server/remote source\n    - `localsource`\n        - handles getting cached device data\n- `data`\n    - handles getting and mutating data from needed sources\n- `domain`\n    - handles encasing business logic for reuse\n- `ui`\n    - handles displaying data on device\n\n### Testing\n\nThe app includes both unit and instrumented tests.\n#### Sources\n---\n\n- Remote\n\n|                             WeatherRemoteSource                              |\n|:----------------------------------------------------------------------------:|\n| \u003cimg src=\"images/testing/remote.png\" width=\"700\" hspace=\"2\" alt=\"loading\" /\u003e |\n\n- Local\n\n|             WeatherLocalSource              |\n|:-------------------------------------------:|\n| \u003cdiv width=\"700\"\u003e \u003cp\u003eIn Progress\u003c/p\u003e \u003c/div\u003e |\n\n#### Data\n---\n\n- Repositories\n\n|                             WeatherRepository                              |\n|:--------------------------------------------------------------------------:|\n| \u003cimg src=\"images/testing/repo.png\" width=\"700\" hspace=\"2\" alt=\"loading\" /\u003e |\n\n- Extensions\n\n|                                         DateTime                                          |\n|:-----------------------------------------------------------------------------------------:|\n| \u003cimg src=\"images/testing/extensions/datetime.png\" width=\"700\" hspace=\"2\" alt=\"loading\" /\u003e |\n\n|                                         String                                          |\n|:---------------------------------------------------------------------------------------:|\n| \u003cimg src=\"images/testing/extensions/string.png\" width=\"700\" hspace=\"2\" alt=\"loading\" /\u003e |\n\n|                                         Int                                          |\n|:------------------------------------------------------------------------------------:|\n| \u003cimg src=\"images/testing/extensions/int.png\" width=\"700\" hspace=\"2\" alt=\"loading\" /\u003e |\n\n#### Domain\n---\n\n|                             GetCurrentWeatherDataUseCase                             |\n|:------------------------------------------------------------------------------------:|\n| \u003cimg src=\"images/testing/domain/current.png\" width=\"700\" hspace=\"2\" alt=\"loading\" /\u003e |\n\n|                             GetHistoryWeatherDataUseCase                             |\n|:------------------------------------------------------------------------------------:|\n| \u003cimg src=\"images/testing/domain/history.png\" width=\"700\" hspace=\"2\" alt=\"loading\" /\u003e |\n\n#### ui\n---\n\n- screen-model\n\n|                                WeatherDetailScreenModel                                 |\n|:---------------------------------------------------------------------------------------:|\n| \u003cimg src=\"images/testing/ui/models/details.png\" width=\"700\" hspace=\"2\" alt=\"loading\" /\u003e |\n\n|                                WeatherListScreenModel                                |\n|:------------------------------------------------------------------------------------:|\n| \u003cimg src=\"images/testing/ui/models/list.png\" width=\"700\" hspace=\"2\" alt=\"loading\" /\u003e |\n\n- screens\n \u003e Instrumented tests can only run on the JVM so in this app's instance they will run on `androidTest`\n\n|                                   WeatherDetailScreen                                   |\n|:---------------------------------------------------------------------------------------:|\n| \u003cimg src=\"images/testing/ui/screens/detail.png\" width=\"700\" hspace=\"2\" alt=\"loading\" /\u003e |\n\n|              WeatherListScreen              |\n|:-------------------------------------------:|\n| \u003cdiv width=\"700\"\u003e \u003cp\u003eIn Progress\u003c/p\u003e \u003c/div\u003e |\n\n## Stack\n\n### Language \u0026 Framework\n\n| Title                                                                              | Description                        |\n|:-----------------------------------------------------------------------------------|:-----------------------------------|\n| [Kotlin](https://kotlinlang.org/)                                                  | `fun` programming language         |\n| [KMP - Kotlin Multiplatform](https://www.jetbrains.com/kotlin-multiplatform/)      | cross platform framework           |\n| [CMP - Compose Multiplatform](https://www.jetbrains.com/lp/compose-multiplatform/) | declarative UI rendering framework |\n| [Ktor](https://github.com/ktorio/ktor)                                             | networking client framework        |\n\n### Libraries\n\n| Title                                                                    | Description          |\n|:-------------------------------------------------------------------------|:---------------------|\n| [Kotlinx-DateTime](https://github.com/Kotlin/kotlinx-datetime)           | date/time library    |\n| [Kotlinx-Coroutines](https://github.com/Kotlin/kotlinx.coroutines)       | async programming    |\n| [Kotlinx-Serialization](https://github.com/Kotlin/kotlinx.serialization) | serialization        |\n| [Kamel](https://github.com/Kamel-Media/Kamel)                            | image loading        |\n| [Voyager](https://github.com/adrielcafe/voyager)                         | navigation           |\n| [Koin](https://github.com/InsertKoinIO/koin)                             | dependency injection |\n\n## Improvements\n### Layered\n- [ ] Sources\n  - [ ] add a local cache for the weather forecast\n- [ ] Data\n  - [ ] get the current day's weather forecast as a flow\n  - [ ] handle getting data from the remote source and caching it on device\n- [ ] UI\n  - [ ] fix the UX on the dates list screen\n### General\n- [ ] add Air Quality to the details(IMPORTANT!!!)\n- [ ] add setup screen for selecting, country, unit of measurement \u0026 language\n- [ ] add check to show if country has snow or not\n- [ ] add ability change selected data\n- [ ] add ability to change time from 24hour to 12 hour","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmambobryan%2Fweather","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmambobryan%2Fweather","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmambobryan%2Fweather/lists"}