├── .github
├── ci-gradle.properties
└── workflows
│ └── Check.yaml
├── .gitignore
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── app
├── .gitignore
├── build.gradle
├── proguard-rules.pro
└── src
│ └── main
│ ├── AndroidManifest.xml
│ ├── java
│ └── com
│ │ └── example
│ │ └── androiddevchallenge
│ │ ├── application
│ │ └── WeatherApplication.kt
│ │ ├── city
│ │ ├── CityManager.kt
│ │ ├── CityManagerImpl.kt
│ │ └── CityModule.kt
│ │ ├── city_edit_view
│ │ ├── CityEditView.kt
│ │ ├── CityEditViewContract.kt
│ │ └── CityEditViewPresenter.kt
│ │ ├── date
│ │ ├── DateManager.kt
│ │ ├── DateManagerImpl.kt
│ │ └── DateModule.kt
│ │ ├── error_view
│ │ └── ErrorView.kt
│ │ ├── forecast_cell_view
│ │ ├── ForecastCellView.kt
│ │ ├── ForecastCellViewContract.kt
│ │ └── ForecastCellViewPresenter.kt
│ │ ├── graph
│ │ ├── WeatherGraph.kt
│ │ ├── WeatherGraphInitializationManager.kt
│ │ ├── WeatherGraphInitializationManagerImpl.kt
│ │ └── WeatherGraphInitializationModule.kt
│ │ ├── main_activity
│ │ ├── MainActivity.kt
│ │ ├── MainActivityContract.kt
│ │ └── MainActivityPresenter.kt
│ │ ├── main_view
│ │ ├── MainView.kt
│ │ ├── MainViewContract.kt
│ │ └── MainViewPresenter.kt
│ │ ├── main_view_background_view
│ │ └── MainViewBackgroundView.kt
│ │ ├── main_view_top_bar_view
│ │ ├── MainViewTopBarView.kt
│ │ ├── MainViewTopBarViewContract.kt
│ │ └── MainViewTopBarViewPresenter.kt
│ │ ├── main_weather_animated_view
│ │ └── MainWeatherAnimatedView.kt
│ │ ├── network
│ │ ├── NetworkManager.kt
│ │ ├── NetworkManagerImpl.kt
│ │ └── NetworkModule.kt
│ │ ├── neumorphism_card_square_view
│ │ └── NeumorphismCardSquareView.kt
│ │ ├── theme
│ │ ├── Shape.kt
│ │ ├── ThemeCompose.kt
│ │ ├── ThemeManager.kt
│ │ ├── ThemeManagerImpl.kt
│ │ ├── ThemeModule.kt
│ │ └── Type.kt
│ │ ├── weather
│ │ ├── Weather.kt
│ │ ├── WeatherManager.kt
│ │ ├── WeatherManagerImpl.kt
│ │ └── WeatherModule.kt
│ │ ├── weather_api
│ │ ├── WeatherApiException.kt
│ │ ├── WeatherApiManager.kt
│ │ ├── WeatherApiManagerImpl.kt
│ │ └── WeatherApiModule.kt
│ │ ├── weather_icon_view
│ │ └── WeatherIconView.kt
│ │ ├── weather_repository
│ │ ├── WeatherRepository.kt
│ │ ├── WeatherRepositoryImpl.kt
│ │ └── WeatherRepositoryModule.kt
│ │ └── weather_unit
│ │ ├── WeatherUnit.kt
│ │ ├── WeatherUnitManager.kt
│ │ ├── WeatherUnitManagerImpl.kt
│ │ └── WeatherUnitModule.kt
│ └── res
│ ├── city_edit_view
│ ├── drawable-night
│ │ ├── city_edit_view_ic_outline_info_24.xml
│ │ └── city_edit_view_loop.xml
│ ├── drawable
│ │ ├── city_edit_view_ic_outline_info_24.xml
│ │ └── city_edit_view_loop.xml
│ ├── values-fr
│ │ └── strings.xml
│ └── values
│ │ └── strings.xml
│ ├── error_view
│ ├── values-fr
│ │ └── strings.xml
│ └── values
│ │ └── strings.xml
│ ├── icon
│ ├── color
│ │ ├── ic_launcher_background_gradient.xml
│ │ └── ic_launcher_background_gradient_dark.xml
│ ├── drawable-night
│ │ └── ic_launcher_background.xml
│ ├── drawable-v24
│ │ └── ic_foreground_weather.png
│ ├── drawable
│ │ ├── ic_launcher_background.xml
│ │ └── ic_launcher_background_night.xml
│ ├── mipmap-anydpi-v26
│ │ └── ic_launcher.xml
│ ├── mipmap-hdpi
│ │ └── ic_launcher.png
│ ├── mipmap-mdpi
│ │ └── ic_launcher.png
│ ├── mipmap-xhdpi
│ │ └── ic_launcher.png
│ ├── mipmap-xxhdpi
│ │ └── ic_launcher.png
│ └── mipmap-xxxhdpi
│ │ └── ic_launcher.png
│ ├── main
│ ├── values-night
│ │ └── themes.xml
│ └── values
│ │ ├── strings.xml
│ │ └── themes.xml
│ ├── main_activity
│ ├── drawable-hdpi
│ │ └── main_activity_splash_image.png
│ ├── drawable-mdpi
│ │ └── main_activity_splash_image.png
│ ├── drawable-night
│ │ └── main_activity_splash_background.xml
│ ├── drawable-xhdpi
│ │ └── main_activity_splash_image.png
│ ├── drawable-xxhdpi
│ │ └── main_activity_splash_image.png
│ ├── drawable-xxxhdpi
│ │ └── main_activity_splash_image.png
│ ├── drawable
│ │ └── main_activity_splash_background.xml
│ ├── values-night
│ │ └── colors.xml
│ └── values
│ │ ├── colors.xml
│ │ └── styles.xml
│ ├── main_activity_splash_dark
│ ├── drawable-hdpi
│ │ └── main_activity_splash_image_dark.png
│ ├── drawable-mdpi
│ │ └── main_activity_splash_image_dark.png
│ ├── drawable-xhdpi
│ │ └── main_activity_splash_image_dark.png
│ ├── drawable-xxhdpi
│ │ └── main_activity_splash_image_dark.png
│ └── drawable-xxxhdpi
│ │ └── main_activity_splash_image_dark.png
│ ├── main_weather_animated_view
│ ├── drawable-hdpi
│ │ └── main_weather_animated_view_circle_with_shadow.webp
│ ├── drawable-mdpi
│ │ └── main_weather_animated_view_circle_with_shadow.webp
│ ├── drawable-xhdpi
│ │ └── main_weather_animated_view_circle_with_shadow.webp
│ ├── drawable-xxhdpi
│ │ └── main_weather_animated_view_circle_with_shadow.webp
│ ├── drawable-xxxhdpi
│ │ └── main_weather_animated_view_circle_with_shadow.webp
│ └── drawable
│ │ └── main_weather_animated_view_circle_gradient_yellow.xml
│ ├── main_weather_animated_view_figure
│ ├── drawable-hdpi
│ │ ├── main_weather_animated_view_figure_1.webp
│ │ ├── main_weather_animated_view_figure_2.webp
│ │ ├── main_weather_animated_view_figure_3.webp
│ │ ├── main_weather_animated_view_figure_4.webp
│ │ ├── main_weather_animated_view_figure_5.webp
│ │ ├── main_weather_animated_view_figure_6.webp
│ │ ├── main_weather_animated_view_figure_7.webp
│ │ └── main_weather_animated_view_figure_8.webp
│ ├── drawable-mdpi
│ │ ├── main_weather_animated_view_figure_1.webp
│ │ ├── main_weather_animated_view_figure_2.webp
│ │ ├── main_weather_animated_view_figure_3.webp
│ │ ├── main_weather_animated_view_figure_4.webp
│ │ ├── main_weather_animated_view_figure_5.webp
│ │ ├── main_weather_animated_view_figure_6.webp
│ │ ├── main_weather_animated_view_figure_7.webp
│ │ └── main_weather_animated_view_figure_8.webp
│ ├── drawable-xhdpi
│ │ ├── main_weather_animated_view_figure_1.webp
│ │ ├── main_weather_animated_view_figure_2.webp
│ │ ├── main_weather_animated_view_figure_3.webp
│ │ ├── main_weather_animated_view_figure_4.webp
│ │ ├── main_weather_animated_view_figure_5.webp
│ │ ├── main_weather_animated_view_figure_6.webp
│ │ ├── main_weather_animated_view_figure_7.webp
│ │ └── main_weather_animated_view_figure_8.webp
│ ├── drawable-xxhdpi
│ │ ├── main_weather_animated_view_figure_1.webp
│ │ ├── main_weather_animated_view_figure_2.webp
│ │ ├── main_weather_animated_view_figure_3.webp
│ │ ├── main_weather_animated_view_figure_4.webp
│ │ ├── main_weather_animated_view_figure_5.webp
│ │ ├── main_weather_animated_view_figure_6.webp
│ │ ├── main_weather_animated_view_figure_7.webp
│ │ └── main_weather_animated_view_figure_8.webp
│ └── drawable-xxxhdpi
│ │ ├── main_weather_animated_view_figure_1.webp
│ │ ├── main_weather_animated_view_figure_2.webp
│ │ ├── main_weather_animated_view_figure_3.webp
│ │ ├── main_weather_animated_view_figure_4.webp
│ │ ├── main_weather_animated_view_figure_5.webp
│ │ ├── main_weather_animated_view_figure_6.webp
│ │ ├── main_weather_animated_view_figure_7.webp
│ │ └── main_weather_animated_view_figure_8.webp
│ ├── theme
│ ├── values-night
│ │ └── booleans.xml
│ └── values
│ │ ├── booleans.xml
│ │ └── colors.xml
│ ├── weather_icon_2_view
│ └── drawable-nodpi
│ │ ├── weather_2_blizzard.webp
│ │ ├── weather_2_clear.webp
│ │ ├── weather_2_cloud_rain_thunder.webp
│ │ ├── weather_2_cloud_sleet_snow_thunder.webp
│ │ ├── weather_2_cloudy.webp
│ │ ├── weather_2_fog.webp
│ │ ├── weather_2_freezing_drizzle.webp
│ │ ├── weather_2_freezing_fog.webp
│ │ ├── weather_2_freezing_rain.webp
│ │ ├── weather_2_heavy_rain.webp
│ │ ├── weather_2_heavy_rain_swrs_day.webp
│ │ ├── weather_2_heavy_rain_swrs_night.webp
│ │ ├── weather_2_heavy_sleet.webp
│ │ ├── weather_2_heavy_sleet_swrs_day.webp
│ │ ├── weather_2_heavy_sleet_swrs_night.webp
│ │ ├── weather_2_heavy_snow.webp
│ │ ├── weather_2_heavy_snow_swrs_day.webp
│ │ ├── weather_2_heavy_snow_swrs_night.webp
│ │ ├── weather_2_iso_rain_swrs_day.webp
│ │ ├── weather_2_iso_rain_swrs_night.webp
│ │ ├── weather_2_iso_sleet_swrs_day.webp
│ │ ├── weather_2_iso_sleet_swrs_night.webp
│ │ ├── weather_2_iso_snow_swrs_day.webp
│ │ ├── weather_2_iso_snow_swrs_night.webp
│ │ ├── weather_2_mist.webp
│ │ ├── weather_2_mod_rain.webp
│ │ ├── weather_2_mod_rain_swrs_day.webp
│ │ ├── weather_2_mod_rain_swrs_night.webp
│ │ ├── weather_2_mod_sleet.webp
│ │ ├── weather_2_mod_sleet_swrs_day.webp
│ │ ├── weather_2_mod_sleet_swrs_night.webp
│ │ ├── weather_2_mod_snow.webp
│ │ ├── weather_2_mod_snow_swrs_day.webp
│ │ ├── weather_2_mod_snow_swrs_night.webp
│ │ ├── weather_2_occ_light_rain.webp
│ │ ├── weather_2_occ_light_sleet.webp
│ │ ├── weather_2_occ_light_snow.webp
│ │ ├── weather_2_overcast.webp
│ │ ├── weather_2_part_cloud_rain_thunder_day.webp
│ │ ├── weather_2_part_cloud_rain_thunder_night.webp
│ │ ├── weather_2_part_cloud_sleet_snow_thunder_day.webp
│ │ ├── weather_2_part_cloud_sleet_snow_thunder_night.webp
│ │ ├── weather_2_partly_cloudy_day.webp
│ │ ├── weather_2_partly_cloudy_night.webp
│ │ ├── weather_2_sunny.webp
│ │ └── weather_2_wind.webp
│ └── weather_icon_view
│ ├── drawable-hdpi
│ ├── weather_cloud_storm.webp
│ ├── weather_mid_snow_fast_winds.webp
│ ├── weather_moon_cloud_fast_wind.webp
│ ├── weather_moon_cloud_mid_rain.webp
│ ├── weather_moon_fast_wind.webp
│ ├── weather_rain.webp
│ ├── weather_snow.webp
│ ├── weather_storm.webp
│ ├── weather_sun.webp
│ ├── weather_sun_cloud_angled_rain.webp
│ ├── weather_sun_cloud_little_rain.webp
│ └── weather_tornado.webp
│ ├── drawable-mdpi
│ ├── weather_cloud_storm.webp
│ ├── weather_mid_snow_fast_winds.webp
│ ├── weather_moon_cloud_fast_wind.webp
│ ├── weather_moon_cloud_mid_rain.webp
│ ├── weather_moon_fast_wind.webp
│ ├── weather_rain.webp
│ ├── weather_snow.webp
│ ├── weather_storm.webp
│ ├── weather_sun.webp
│ ├── weather_sun_cloud_angled_rain.webp
│ ├── weather_sun_cloud_little_rain.webp
│ └── weather_tornado.webp
│ ├── drawable-xhdpi
│ ├── weather_cloud_storm.webp
│ ├── weather_mid_snow_fast_winds.webp
│ ├── weather_moon_cloud_fast_wind.webp
│ ├── weather_moon_cloud_mid_rain.webp
│ ├── weather_moon_fast_wind.webp
│ ├── weather_rain.webp
│ ├── weather_snow.webp
│ ├── weather_storm.webp
│ ├── weather_sun.webp
│ ├── weather_sun_cloud_angled_rain.webp
│ ├── weather_sun_cloud_little_rain.webp
│ └── weather_tornado.webp
│ ├── drawable-xxhdpi
│ ├── weather_cloud_storm.webp
│ ├── weather_mid_snow_fast_winds.webp
│ ├── weather_moon_cloud_fast_wind.webp
│ ├── weather_moon_cloud_mid_rain.webp
│ ├── weather_moon_fast_wind.webp
│ ├── weather_rain.webp
│ ├── weather_snow.webp
│ ├── weather_storm.webp
│ ├── weather_sun.webp
│ ├── weather_sun_cloud_angled_rain.webp
│ ├── weather_sun_cloud_little_rain.webp
│ └── weather_tornado.webp
│ └── drawable-xxxhdpi
│ ├── weather_cloud_storm.webp
│ ├── weather_mid_snow_fast_winds.webp
│ ├── weather_moon_cloud_fast_wind.webp
│ ├── weather_moon_cloud_mid_rain.webp
│ ├── weather_moon_fast_wind.webp
│ ├── weather_rain.webp
│ ├── weather_snow.webp
│ ├── weather_storm.webp
│ ├── weather_sun.webp
│ ├── weather_sun_cloud_angled_rain.webp
│ ├── weather_sun_cloud_little_rain.webp
│ └── weather_tornado.webp
├── build.gradle
├── debug.keystore
├── gradle.properties
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── results
├── banner.jpg
├── screenshot_1.png
├── screenshot_2.png
├── screenshot_3.png
├── screenshot_4.png
├── screenshot_5.png
├── video.mp4
└── video_as_gif.gif
├── settings.gradle
└── spotless
└── copyright.kt
/.github/ci-gradle.properties:
--------------------------------------------------------------------------------
1 |
2 | #
3 | # Copyright 2020 The Android Open Source Project
4 | #
5 | # Licensed under the Apache License, Version 2.0 (the "License");
6 | # you may not use this file except in compliance with the License.
7 | # You may obtain a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | # Unless required by applicable law or agreed to in writing, software
12 | # distributed under the License is distributed on an "AS IS" BASIS,
13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | # See the License for the specific language governing permissions and
15 | # limitations under the License.
16 | #
17 |
18 | org.gradle.daemon=false
19 | org.gradle.parallel=true
20 | org.gradle.jvmargs=-Xmx5120m
21 | org.gradle.workers.max=2
22 |
23 | kotlin.incremental=false
24 | kotlin.compiler.execution.strategy=in-process
25 |
--------------------------------------------------------------------------------
/.github/workflows/Check.yaml:
--------------------------------------------------------------------------------
1 | name: Check
2 |
3 | on:
4 | push:
5 | branches:
6 | - main
7 |
8 | jobs:
9 | build:
10 | runs-on: ubuntu-latest
11 | timeout-minutes: 30
12 |
13 | steps:
14 | - name: Checkout
15 | uses: actions/checkout@v2
16 |
17 | - name: Copy CI gradle.properties
18 | run: mkdir -p ~/.gradle ; cp .github/ci-gradle.properties ~/.gradle/gradle.properties
19 |
20 | - name: Set up JDK 11
21 | uses: actions/setup-java@v1
22 | with:
23 | java-version: 11
24 |
25 | - name: Build project
26 | run: ./gradlew spotlessCheck assembleDebug lintDebug --stacktrace
27 |
28 | - name: Upload build outputs (APKs)
29 | uses: actions/upload-artifact@v2
30 | with:
31 | name: build-outputs
32 | path: app/build/outputs
33 |
34 | - name: Upload build reports
35 | if: always()
36 | uses: actions/upload-artifact@v2
37 | with:
38 | name: build-reports
39 | path: app/build/reports
40 |
41 | test:
42 | needs: build
43 | runs-on: macOS-latest # enables hardware acceleration in the virtual machine
44 | timeout-minutes: 30
45 | strategy:
46 | matrix:
47 | api-level: [23, 26, 29]
48 |
49 | steps:
50 | - name: Checkout
51 | uses: actions/checkout@v2
52 |
53 | - name: Copy CI gradle.properties
54 | run: mkdir -p ~/.gradle ; cp .github/ci-gradle.properties ~/.gradle/gradle.properties
55 |
56 | - name: Set up JDK 11
57 | uses: actions/setup-java@v1
58 | with:
59 | java-version: 11
60 |
61 | - name: Run instrumentation tests
62 | uses: reactivecircus/android-emulator-runner@v2
63 | with:
64 | api-level: ${{ matrix.api-level }}
65 | arch: x86
66 | disable-animations: true
67 | script: ./gradlew connectedCheck --stacktrace
68 |
69 | - name: Upload test reports
70 | if: always()
71 | uses: actions/upload-artifact@v2
72 | with:
73 | name: test-reports
74 | path: app/build/reports
75 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # built application files
2 | *.apk
3 | *.ap_
4 |
5 | # Mac files
6 | .DS_Store
7 |
8 | # files for the dex VM
9 | *.dex
10 |
11 | # Java class files
12 | *.class
13 |
14 | # generated files
15 | bin/
16 | gen/
17 |
18 | # Ignore gradle files
19 | .gradle/
20 | build/
21 |
22 | # Local configuration file (sdk path, etc)
23 | local.properties
24 |
25 | # Proguard folder generated by Eclipse
26 | proguard/
27 | proguard-project.txt
28 |
29 | # Eclipse files
30 | .project
31 | .classpath
32 | .settings/
33 |
34 | # Android Studio/IDEA
35 | *.iml
36 | .idea
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # How to Contribute
2 |
3 | We'd love to accept your patches and contributions to this project. There are
4 | just a few small guidelines you need to follow.
5 |
6 | ## Contributor License Agreement
7 |
8 | Contributions to this project must be accompanied by a Contributor License
9 | Agreement. You (or your employer) retain the copyright to your contribution,
10 | this simply gives us permission to use and redistribute your contributions as
11 | part of the project. Head over to to see
12 | your current agreements on file or to sign a new one.
13 |
14 | You generally only need to submit a CLA once, so if you've already submitted one
15 | (even if it was for a different project), you probably don't need to do it
16 | again.
17 |
18 | ## Code reviews
19 |
20 | All submissions, including submissions by project members, require review. We
21 | use GitHub pull requests for this purpose. Consult
22 | [GitHub Help](https://help.github.com/articles/about-pull-requests/) for more
23 | information on using pull requests.
24 |
25 | ## Community Guidelines
26 |
27 | This project follows [Google's Open Source Community
28 | Guidelines](https://opensource.google.com/conduct/).
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | 
2 |
3 | # C-Weather: Compose with weather
4 |
5 |
6 |
7 | 
8 |
9 | Requirement: Replace `WeatherApiManagerImpl#YOUR_KEY_HERE_WITH_FORECAST_AVAILABLE` by your openweathermap key
10 |
11 | ## :scroll: Description
12 |
13 |
14 | * Neumorphism simple weather app that support different temperature units and cities.
15 | * Based on [Jetpack Compose](https://developer.android.com/jetpack/compose) and [openweathermap.org](https://openweathermap.org/), built for the [Jetpack Compose challenge](https://developer.android.com/dev-challenge) week 4.
16 |
17 | ## :bulb: Motivation and Context
18 |
19 |
20 |
21 |
27 |
28 | **What am I proud of?**
29 | - Split UI and logic
30 | - "Useful" app
31 | - -> Real data forecast
32 | - -> Persistence of the forecast
33 | - -> Change your City / temperature Unit
34 | - Neumorphism UI
35 |
36 | ## :camera_flash: Screenshots
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 | ## Side notes
45 |
46 | This is the first time I'm trying Jetpack Compose.
47 | Even if the spirit seems to be reactive paradigm, I will try to use it on a more "classic" way.
48 |
49 | **Why?**
50 | - Because, if one day I will use this techno in production, I will need a "transition" phase to not move all my code to the "reactive" way.
51 | - Because stay "non reactive" is easier for the reactive-beginner that I am. I hope that my project demonstrates that Jetpack Compose work well without intensive use of ViewModel, LiveData...
52 | - Because stay "non reactive" allow you to produce almost the same code on any platform easily (Unity, iOS, server...)
53 |
54 | **My goals will be:**
55 | - Discover Jetpack Compose
56 | - Split as much as possible logic from the UI with the good old "MVP"
57 | - Great UI / Great app quality (app we can publish on Google Play)
58 |
59 | **Architecture**
60 | - Code and resources split by `feature` instead of `layer` to be able to scale
61 | - DepInjection done manually and user Dagger notions: graph, module, manager...
62 | - Basic MVP explicit in Contract interfaces
63 |
64 | **Bonus**
65 | - Translated in french 🇫🇷
66 |
67 | **Requirement if you a coming from "stable Android Studio" on MacOs**
68 | - Download Java 11 (for example [here](https://jdk.java.net/archive/))
69 | - Add it like that: `/Users/jonathan/Library/Java/JavaVirtualMachines/jdk-11.0.2.jdk`
70 | - If cannot open the jdk due to mac os permission, [here](https://superuser.com/a/1537706) a tip)
71 |
72 | **Thank you to:**
73 | - [Edwin.P that introduce me to Figma](https://www.figma.com/file/K940hjRsZGY6LrOdvJeV28/Untitled?node-id=201%3A2)
74 | - Designers on figma that provide images [here](https://www.figma.com/file/kCYEnx8j7LCxOiBcr2sjFM/Weatherly-3D-Icons-Demo-version-Community?node-id=0%3A10), [here](https://www.figma.com/community/file/890095002328610853) and [here](https://www.figma.com/file/LfxPlArXOlJ74YNfQwpz8s/SALY---3D-Illustration-Pack-(Community)?node-id=0%3A1)
75 | - The neumorphism library [here](https://github.com/fornewid/neumorphism)
76 | - Google and Jetpack compose team ❤️
77 |
78 | ## License
79 | ```
80 | Copyright 2020 The Android Open Source Project
81 |
82 | Licensed under the Apache License, Version 2.0 (the "License");
83 | you may not use this file except in compliance with the License.
84 | You may obtain a copy of the License at
85 |
86 | https://www.apache.org/licenses/LICENSE-2.0
87 |
88 | Unless required by applicable law or agreed to in writing, software
89 | distributed under the License is distributed on an "AS IS" BASIS,
90 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
91 | See the License for the specific language governing permissions and
92 | limitations under the License.
93 | ```
--------------------------------------------------------------------------------
/app/.gitignore:
--------------------------------------------------------------------------------
1 | # Gradle
2 | .gradle
3 | build/
4 |
5 | captures
6 |
7 | /local.properties
8 |
9 | # IntelliJ .idea folder
10 | /.idea
11 | *.iml
12 |
13 | # General
14 | .DS_Store
15 | .externalNativeBuild
--------------------------------------------------------------------------------
/app/build.gradle:
--------------------------------------------------------------------------------
1 | plugins {
2 | id 'com.android.application'
3 | id 'kotlin-android'
4 | }
5 |
6 | android {
7 | compileSdkVersion 30
8 |
9 | defaultConfig {
10 | applicationId "com.example.androiddevchallenge"
11 | minSdkVersion 23
12 | targetSdkVersion 30
13 | versionCode 1
14 | versionName "1.0"
15 |
16 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
17 | }
18 |
19 | signingConfigs {
20 | // We use a bundled debug keystore, to allow debug builds from CI to be upgradable
21 | debug {
22 | storeFile rootProject.file('debug.keystore')
23 | storePassword 'android'
24 | keyAlias 'androiddebugkey'
25 | keyPassword 'android'
26 | }
27 | }
28 |
29 | buildTypes {
30 | debug {
31 | signingConfig signingConfigs.debug
32 | }
33 | release {
34 | minifyEnabled false
35 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
36 | }
37 | }
38 |
39 | kotlinOptions {
40 | jvmTarget = "1.8"
41 | }
42 |
43 | buildFeatures {
44 | compose true
45 |
46 | // Disable unused AGP features
47 | buildConfig false
48 | aidl false
49 | renderScript false
50 | resValues false
51 | shaders false
52 | }
53 |
54 | composeOptions {
55 | kotlinCompilerExtensionVersion compose_version
56 | }
57 |
58 | packagingOptions {
59 | // Multiple dependency bring these files in. Exclude them to enable
60 | // our test APK to build (has no effect on our AARs)
61 | excludes += "/META-INF/AL2.0"
62 | excludes += "/META-INF/LGPL2.1"
63 | }
64 |
65 |
66 | sourceSets {
67 | main {
68 | // Split resources.
69 | // https://medium.com/google-developer-experts/android-project-structure-alternative-way-29ce766682f0#.sjnhetuhb
70 | res.srcDirs = [
71 | 'src/main/res/city_edit_view',
72 | 'src/main/res/error_view',
73 | 'src/main/res/icon',
74 | 'src/main/res/main',
75 | 'src/main/res/main_activity',
76 | 'src/main/res/main_activity_splash_dark',
77 | 'src/main/res/main_weather_animated_view',
78 | 'src/main/res/main_weather_animated_view_figure',
79 | 'src/main/res/theme',
80 | 'src/main/res/weather_icon_2_view',
81 | 'src/main/res/weather_icon_view'
82 | ]
83 | }
84 | }
85 | }
86 |
87 | dependencies {
88 | implementation 'androidx.core:core-ktx:1.3.2'
89 | implementation 'androidx.appcompat:appcompat:1.3.0-beta01'
90 | implementation 'com.google.android.material:material:1.3.0'
91 | implementation "androidx.activity:activity-compose:1.3.0-alpha04"
92 | implementation "androidx.compose.ui:ui:$compose_version"
93 | implementation "androidx.compose.material:material:$compose_version"
94 | implementation "androidx.compose.material:material-icons-extended:$compose_version"
95 | implementation "androidx.compose.ui:ui-tooling:$compose_version"
96 | implementation "androidx.annotation:annotation:1.1.0"
97 |
98 | // https://github.com/fornewid/neumorphism
99 | implementation 'com.github.fornewid:neumorphism:0.3.0'
100 |
101 | implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.3.0'
102 | implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.3.0'
103 | implementation "androidx.compose.runtime:runtime-livedata:$compose_version"
104 |
105 | implementation "androidx.compose.animation:animation:$compose_version"
106 |
107 | implementation("com.squareup.okhttp3:okhttp:3.12.13")
108 |
109 | testImplementation 'junit:junit:4.13.2'
110 |
111 | androidTestImplementation 'androidx.test.ext:junit:1.1.2'
112 | androidTestImplementation "androidx.compose.ui:ui-test-junit4:$compose_version"
113 | }
--------------------------------------------------------------------------------
/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
11 |
12 |
14 |
15 |
16 |
17 |
25 |
26 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/app/src/main/java/com/example/androiddevchallenge/application/WeatherApplication.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.example.androiddevchallenge.application
17 |
18 | import android.app.Application
19 | import com.example.androiddevchallenge.graph.WeatherGraph
20 |
21 | class WeatherApplication : Application() {
22 |
23 | override fun onCreate() {
24 | super.onCreate()
25 | WeatherGraph.initialize(this)
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/app/src/main/java/com/example/androiddevchallenge/city/CityManager.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.example.androiddevchallenge.city
17 |
18 | interface CityManager {
19 |
20 | fun getCity(): String
21 |
22 | fun setCity(city: String)
23 |
24 | fun addListener(listener: Listener)
25 |
26 | fun removeListener(listener: Listener)
27 |
28 | interface Listener {
29 |
30 | fun onChanged()
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/app/src/main/java/com/example/androiddevchallenge/city/CityManagerImpl.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.example.androiddevchallenge.city
17 |
18 | import android.content.SharedPreferences
19 |
20 | class CityManagerImpl(
21 | private val sharedPreferences: SharedPreferences
22 | ) : CityManager {
23 |
24 | private val listeners = ArrayList()
25 | private var city = "Paris, France"
26 | private var loaded = false
27 |
28 | override fun getCity(): String {
29 | loadIfNeeded()
30 | return city
31 | }
32 |
33 | override fun setCity(city: String) {
34 | loadIfNeeded()
35 | if (this.city == city) {
36 | return
37 | }
38 | this.city = city
39 | save()
40 | for (listener in listeners) {
41 | listener.onChanged()
42 | }
43 | }
44 |
45 | override fun addListener(listener: CityManager.Listener) {
46 | if (listeners.contains(listener)) {
47 | return
48 | }
49 | listeners.add(listener)
50 | }
51 |
52 | override fun removeListener(listener: CityManager.Listener) {
53 | listeners.remove(listener)
54 | }
55 |
56 | private fun loadIfNeeded() {
57 | if (loaded) {
58 | return
59 | }
60 | city = sharedPreferences.getString("city", city) ?: "city"
61 | loaded = true
62 | }
63 |
64 | private fun save() {
65 | sharedPreferences.edit().putString("city", city).apply()
66 | }
67 |
68 | companion object {
69 |
70 | const val PREFERENCE_NAME = "weather_current_city"
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/app/src/main/java/com/example/androiddevchallenge/city/CityModule.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.example.androiddevchallenge.city
17 |
18 | import android.content.Context
19 | import android.content.SharedPreferences
20 | import com.example.androiddevchallenge.graph.WeatherGraph
21 |
22 | class CityModule {
23 |
24 | fun createCityManager(): CityManager {
25 | return CityManagerImpl(
26 | createSharedPreferences()
27 | )
28 | }
29 |
30 | private fun createSharedPreferences(): SharedPreferences {
31 | val context = WeatherGraph.getContext()
32 | return context.getSharedPreferences(
33 | CityManagerImpl.PREFERENCE_NAME,
34 | Context.MODE_PRIVATE
35 | )
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/app/src/main/java/com/example/androiddevchallenge/city_edit_view/CityEditViewContract.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.example.androiddevchallenge.city_edit_view
17 |
18 | interface CityEditViewContract {
19 |
20 | interface UserAction {
21 |
22 | fun onCityValidated(text: String)
23 |
24 | fun onInfoClicked()
25 | }
26 |
27 | interface Screen
28 | }
29 |
--------------------------------------------------------------------------------
/app/src/main/java/com/example/androiddevchallenge/city_edit_view/CityEditViewPresenter.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.example.androiddevchallenge.city_edit_view
17 |
18 | import com.example.androiddevchallenge.city.CityManager
19 | import java.util.Locale
20 |
21 | class CityEditViewPresenter(
22 | private val screen: CityEditViewContract.Screen,
23 | private val cityManager: CityManager
24 | ) : CityEditViewContract.UserAction {
25 |
26 | override fun onCityValidated(text: String) {
27 | cityManager.setCity(text.capitalize(Locale.getDefault()))
28 | }
29 |
30 | override fun onInfoClicked() {
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/app/src/main/java/com/example/androiddevchallenge/date/DateManager.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.example.androiddevchallenge.date
17 |
18 | interface DateManager {
19 |
20 | // Mon 18
21 | fun convertTimestampToSpecificFormat1(timestamp: Long): String
22 | }
23 |
--------------------------------------------------------------------------------
/app/src/main/java/com/example/androiddevchallenge/date/DateManagerImpl.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.example.androiddevchallenge.date
17 |
18 | import java.text.SimpleDateFormat
19 | import java.util.Date
20 | import java.util.Locale
21 |
22 | class DateManagerImpl : DateManager {
23 |
24 | override fun convertTimestampToSpecificFormat1(timestampSecond: Long): String {
25 | val locale = Locale.getDefault()
26 | val simpleDateFormat = SimpleDateFormat("E dd", locale)
27 | return simpleDateFormat.format(Date(timestampSecond * 1_000)).capitalize(locale)
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/app/src/main/java/com/example/androiddevchallenge/date/DateModule.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.example.androiddevchallenge.date
17 |
18 | class DateModule {
19 |
20 | fun createDateManager(): DateManager {
21 | return DateManagerImpl()
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/app/src/main/java/com/example/androiddevchallenge/error_view/ErrorView.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.example.androiddevchallenge.error_view
17 |
18 | import androidx.compose.foundation.Image
19 | import androidx.compose.foundation.layout.Column
20 | import androidx.compose.foundation.layout.Spacer
21 | import androidx.compose.foundation.layout.height
22 | import androidx.compose.foundation.layout.width
23 | import androidx.compose.material.MaterialTheme
24 | import androidx.compose.material.Text
25 | import androidx.compose.runtime.Composable
26 | import androidx.compose.ui.Alignment
27 | import androidx.compose.ui.Modifier
28 | import androidx.compose.ui.res.painterResource
29 | import androidx.compose.ui.res.stringResource
30 | import androidx.compose.ui.text.font.FontWeight
31 | import androidx.compose.ui.unit.dp
32 | import androidx.compose.ui.unit.sp
33 | import com.example.androiddevchallenge.R
34 | import com.example.androiddevchallenge.theme.getTextPrimaryColor
35 | import com.example.androiddevchallenge.theme.getTextSecondaryColor
36 | import com.example.androiddevchallenge.theme.getTextThirdColor
37 |
38 | @Composable
39 | fun ErrorView(
40 | modifier: Modifier = Modifier,
41 | preview: Boolean = false
42 | ) {
43 | Column {
44 | Spacer(modifier = Modifier.height(12.dp))
45 | Text(
46 | text = stringResource(R.string.error_view_title),
47 | fontSize = 28.sp,
48 | color = MaterialTheme.colors.getTextPrimaryColor(),
49 | fontWeight = FontWeight(900),
50 | )
51 | Spacer(modifier = Modifier.height(14.dp))
52 | Image(
53 | painter = painterResource(R.drawable.main_weather_animated_view_figure_7),
54 | contentDescription = stringResource(R.string.error_view_image_content_description),
55 | modifier = Modifier
56 | .width(180.dp)
57 | .height(180.dp)
58 | .align(Alignment.CenterHorizontally)
59 | )
60 | Spacer(modifier = Modifier.height(14.dp))
61 | Text(
62 | text = stringResource(R.string.error_view_subtitle),
63 | modifier = Modifier.align(Alignment.CenterHorizontally),
64 | fontSize = 22.sp,
65 | color = MaterialTheme.colors.getTextSecondaryColor(),
66 | fontWeight = FontWeight(700),
67 | )
68 | Spacer(modifier = Modifier.height(12.dp))
69 | Text(
70 | text = stringResource(R.string.error_view_point_1),
71 | fontSize = 16.sp,
72 | color = MaterialTheme.colors.getTextThirdColor(),
73 | fontWeight = FontWeight(600),
74 | )
75 | Spacer(modifier = Modifier.height(4.dp))
76 | Text(
77 | text = stringResource(R.string.error_view_point_2),
78 | fontSize = 16.sp,
79 | color = MaterialTheme.colors.getTextThirdColor(),
80 | fontWeight = FontWeight(600),
81 | )
82 | Spacer(modifier = Modifier.height(4.dp))
83 | Text(
84 | text = stringResource(R.string.error_view_point_3),
85 | fontSize = 16.sp,
86 | color = MaterialTheme.colors.getTextThirdColor(),
87 | fontWeight = FontWeight(600),
88 | )
89 | }
90 | }
91 |
--------------------------------------------------------------------------------
/app/src/main/java/com/example/androiddevchallenge/forecast_cell_view/ForecastCellViewContract.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.example.androiddevchallenge.forecast_cell_view
17 |
18 | class ForecastCellViewContract {
19 |
20 | interface UserAction {
21 |
22 | fun onDisplayTextTemperature(): String
23 | }
24 |
25 | interface Screen
26 | }
27 |
--------------------------------------------------------------------------------
/app/src/main/java/com/example/androiddevchallenge/forecast_cell_view/ForecastCellViewPresenter.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.example.androiddevchallenge.forecast_cell_view
17 |
18 | import com.example.androiddevchallenge.date.DateManager
19 | import com.example.androiddevchallenge.weather.Weather
20 |
21 | class ForecastCellViewPresenter(
22 | private val screen: ForecastCellViewContract.Screen,
23 | private val weather: Weather?,
24 | private val dateManager: DateManager
25 | ) : ForecastCellViewContract.UserAction {
26 |
27 | override fun onDisplayTextTemperature(): String {
28 | return createTemperatureToDisplay()
29 | }
30 |
31 | private fun createTemperatureToDisplay(): String {
32 | val weather = weather ?: return ""
33 | return dateManager.convertTimestampToSpecificFormat1(weather.timestampSecond)
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/app/src/main/java/com/example/androiddevchallenge/graph/WeatherGraph.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.example.androiddevchallenge.graph
17 |
18 | import android.annotation.SuppressLint
19 | import android.content.Context
20 | import com.example.androiddevchallenge.city.CityModule
21 | import com.example.androiddevchallenge.date.DateModule
22 | import com.example.androiddevchallenge.network.NetworkModule
23 | import com.example.androiddevchallenge.theme.ThemeModule
24 | import com.example.androiddevchallenge.weather.WeatherModule
25 | import com.example.androiddevchallenge.weather_unit.WeatherUnitModule
26 |
27 | class WeatherGraph private constructor(
28 | private val context: Context
29 | ) {
30 |
31 | private val cityManager by lazy { CityModule().createCityManager() }
32 | private val dateManager by lazy { DateModule().createDateManager() }
33 | private val networkManager by lazy { NetworkModule().createNetworkManager() }
34 | private val themeManager by lazy { ThemeModule().createThemeManager() }
35 | private val weatherGraphInitializationManager by lazy { WeatherGraphInitializationModule().createWeatherGraphInitializationManager() }
36 | private val weatherManager by lazy { WeatherModule().createWeatherManager() }
37 | private val weatherUnitManager by lazy { WeatherUnitModule().createWeatherUnitManager() }
38 |
39 | companion object {
40 |
41 | @SuppressLint("StaticFieldLeak")
42 | private var graph: WeatherGraph? = null
43 |
44 | fun initialize(context: Context) {
45 | if (graph != null) {
46 | return
47 | }
48 | graph = WeatherGraph(context.applicationContext)
49 | graph!!.weatherGraphInitializationManager.initialize()
50 | }
51 |
52 | fun getCityManager() = graph!!.cityManager
53 | fun getDateManager() = graph!!.dateManager
54 | fun getContext() = graph!!.context
55 | fun getNetworkManager() = graph!!.networkManager
56 | fun getThemeManager() = graph!!.themeManager
57 | fun getWeatherManager() = graph!!.weatherManager
58 | fun getWeatherUnitManager() = graph!!.weatherUnitManager
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/app/src/main/java/com/example/androiddevchallenge/graph/WeatherGraphInitializationManager.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.example.androiddevchallenge.graph
17 |
18 | interface WeatherGraphInitializationManager {
19 |
20 | fun initialize()
21 | }
22 |
--------------------------------------------------------------------------------
/app/src/main/java/com/example/androiddevchallenge/graph/WeatherGraphInitializationManagerImpl.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.example.androiddevchallenge.graph
17 |
18 | import com.example.androiddevchallenge.city.CityManager
19 | import com.example.androiddevchallenge.weather.WeatherManager
20 | import com.example.androiddevchallenge.weather_unit.WeatherUnitManager
21 |
22 | class WeatherGraphInitializationManagerImpl(
23 | private val cityManager: CityManager,
24 | private val weatherManager: WeatherManager,
25 | private val weatherUnitManager: WeatherUnitManager
26 | ) : WeatherGraphInitializationManager {
27 |
28 | override fun initialize() {
29 | cityManager.addListener(createCityListener())
30 | weatherUnitManager.addListener(createWeatherUnitListener())
31 | }
32 |
33 | private fun createCityListener() = object : CityManager.Listener {
34 | override fun onChanged() {
35 | weatherManager.clearCache()
36 | weatherManager.load()
37 | }
38 | }
39 |
40 | private fun createWeatherUnitListener() = object : WeatherUnitManager.Listener {
41 | override fun onChanged() {
42 | weatherManager.clearCache()
43 | weatherManager.load()
44 | }
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/app/src/main/java/com/example/androiddevchallenge/graph/WeatherGraphInitializationModule.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.example.androiddevchallenge.graph
17 |
18 | class WeatherGraphInitializationModule {
19 |
20 | fun createWeatherGraphInitializationManager(): WeatherGraphInitializationManager {
21 | return WeatherGraphInitializationManagerImpl(
22 | WeatherGraph.getCityManager(),
23 | WeatherGraph.getWeatherManager(),
24 | WeatherGraph.getWeatherUnitManager()
25 | )
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/app/src/main/java/com/example/androiddevchallenge/main_activity/MainActivity.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.example.androiddevchallenge.main_activity
17 |
18 | import android.graphics.Color
19 | import android.os.Build
20 | import android.os.Bundle
21 | import android.view.View
22 | import android.view.Window
23 | import android.view.WindowInsetsController
24 | import androidx.activity.compose.setContent
25 | import androidx.annotation.ColorRes
26 | import androidx.annotation.RequiresApi
27 | import androidx.appcompat.app.AppCompatActivity
28 | import androidx.core.content.ContextCompat
29 | import com.example.androiddevchallenge.graph.WeatherGraph
30 | import com.example.androiddevchallenge.main_view.MainView
31 | import com.example.androiddevchallenge.theme.MainTheme
32 |
33 | class MainActivity : AppCompatActivity() {
34 |
35 | private val userAction by lazy { createUserAction() }
36 |
37 | override fun onCreate(savedInstanceState: Bundle?) {
38 | super.onCreate(savedInstanceState)
39 | setContent {
40 | MainTheme {
41 | MainView()
42 | }
43 | }
44 | userAction.onCreate(savedInstanceState == null)
45 | }
46 |
47 | override fun onResume() {
48 | super.onResume()
49 | userAction.onResume()
50 | }
51 |
52 | private fun createScreen() = object : MainActivityContract.Screen {
53 |
54 | @Suppress("DEPRECATION")
55 | override fun setStatusBarTheme(@ColorRes colorRes: Int, themeDark: Boolean) {
56 | val color = ContextCompat.getColor(this@MainActivity, colorRes)
57 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
58 | window.insetsController!!.setSystemBarsAppearance(
59 | if (themeDark) 0 else WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS,
60 | WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS
61 | )
62 | window.statusBarColor = color
63 | } else {
64 | window.statusBarColor = color
65 | val flags = window.decorView.systemUiVisibility
66 | window.decorView.systemUiVisibility = if (themeDark) {
67 | flags and View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR.inv()
68 | } else {
69 | flags or View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR
70 | }
71 | }
72 | }
73 |
74 | override fun setNavigationBarTheme(@ColorRes colorRes: Int, themeDark: Boolean) {
75 | val color = ContextCompat.getColor(this@MainActivity, colorRes)
76 | window.navigationBarColor = if (color == Color.WHITE) {
77 | // Not supported nicely as buttons will stay white, so use black color instead.
78 | Color.BLACK
79 | } else {
80 | color
81 | }
82 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
83 | window.insetsController!!.setSystemBarsAppearance(
84 | if (themeDark) 0 else WindowInsetsController.APPEARANCE_LIGHT_NAVIGATION_BARS,
85 | WindowInsetsController.APPEARANCE_LIGHT_NAVIGATION_BARS
86 | )
87 | } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
88 | setNavigationBarButtonColor(window, !themeDark)
89 | }
90 | }
91 |
92 | @RequiresApi(api = Build.VERSION_CODES.O)
93 | private fun setNavigationBarButtonColor(window: Window, darkButton: Boolean) {
94 | val flags = window.decorView.systemUiVisibility
95 | window.decorView.systemUiVisibility = if (darkButton) {
96 | flags or View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR
97 | } else {
98 | flags and View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR.inv()
99 | }
100 | }
101 | }
102 |
103 | private fun createUserAction(): MainActivityContract.UserAction {
104 | return MainActivityPresenter(
105 | createScreen(),
106 | WeatherGraph.getThemeManager(),
107 | WeatherGraph.getWeatherManager()
108 | )
109 | }
110 | }
111 |
--------------------------------------------------------------------------------
/app/src/main/java/com/example/androiddevchallenge/main_activity/MainActivityContract.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.example.androiddevchallenge.main_activity
17 |
18 | import androidx.annotation.ColorRes
19 |
20 | interface MainActivityContract {
21 |
22 | interface UserAction {
23 |
24 | fun onCreate(savedInstanceStateNull: Boolean)
25 |
26 | fun onResume()
27 | }
28 |
29 | interface Screen {
30 |
31 | fun setStatusBarTheme(@ColorRes colorRes: Int, themeDark: Boolean)
32 |
33 | fun setNavigationBarTheme(@ColorRes colorRes: Int, themeDark: Boolean)
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/app/src/main/java/com/example/androiddevchallenge/main_activity/MainActivityPresenter.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.example.androiddevchallenge.main_activity
17 |
18 | import com.example.androiddevchallenge.R
19 | import com.example.androiddevchallenge.theme.ThemeManager
20 | import com.example.androiddevchallenge.weather.WeatherManager
21 |
22 | class MainActivityPresenter(
23 | private val screen: MainActivityContract.Screen,
24 | private val themeManager: ThemeManager,
25 | private val weatherManager: WeatherManager
26 | ) : MainActivityContract.UserAction {
27 |
28 | override fun onCreate(savedInstanceStateNull: Boolean) {
29 | updateScreen()
30 | weatherManager.load()
31 | }
32 |
33 | override fun onResume() {
34 | weatherManager.load()
35 | }
36 |
37 | private fun updateScreen() {
38 | updateTheme()
39 | }
40 |
41 | private fun updateTheme() {
42 | val light = themeManager.isLight()
43 | screen.setStatusBarTheme(
44 | if (light) {
45 | R.color.main_activity_status_bar_light_theme_color
46 | } else {
47 | R.color.main_activity_status_bar_dark_theme_color
48 | },
49 | themeDark = !light
50 | )
51 | screen.setNavigationBarTheme(
52 | if (light) {
53 | R.color.main_activity_navigation_bar_light_theme_color
54 | } else {
55 | R.color.main_activity_navigation_bar_dark_theme_color
56 | },
57 | themeDark = !light
58 | )
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/app/src/main/java/com/example/androiddevchallenge/main_view/MainViewContract.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.example.androiddevchallenge.main_view
17 |
18 | import androidx.lifecycle.MutableLiveData
19 | import com.example.androiddevchallenge.weather.Weather
20 |
21 | interface MainViewContract {
22 |
23 | interface UserAction {
24 |
25 | fun getWeathers(): MutableLiveData>
26 |
27 | fun getError(): MutableLiveData
28 | }
29 |
30 | interface Screen
31 | }
32 |
--------------------------------------------------------------------------------
/app/src/main/java/com/example/androiddevchallenge/main_view/MainViewPresenter.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.example.androiddevchallenge.main_view
17 |
18 | import androidx.lifecycle.MutableLiveData
19 | import com.example.androiddevchallenge.weather.Weather
20 | import com.example.androiddevchallenge.weather.WeatherManager
21 |
22 | class MainViewPresenter(
23 | private val screen: MainViewContract.Screen,
24 | private val weatherManager: WeatherManager
25 | ) : MainViewContract.UserAction {
26 |
27 | private var weathers = MutableLiveData(createWeathers())
28 | private var error = MutableLiveData(createError())
29 |
30 | init {
31 | // Leak?
32 | weatherManager.addListener(createWeatherListener())
33 | }
34 |
35 | override fun getWeathers(): MutableLiveData> {
36 | return weathers
37 | }
38 |
39 | override fun getError(): MutableLiveData {
40 | return error
41 | }
42 |
43 | private fun updateWeathers() {
44 | weathers.value = createWeathers()
45 | }
46 |
47 | private fun updateError() {
48 | error.value = createError()
49 | }
50 |
51 | private fun createWeathers(): List {
52 | return weatherManager.getWeathers()
53 | }
54 |
55 | private fun createError(): Boolean {
56 | return weatherManager.getWeathers().size < 4
57 | }
58 |
59 | private fun createWeatherListener() = object : WeatherManager.Listener {
60 | override fun onChanged() {
61 | updateWeathers()
62 | updateError()
63 | }
64 |
65 | override fun onFailed() {
66 | updateError()
67 | }
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/app/src/main/java/com/example/androiddevchallenge/main_view_background_view/MainViewBackgroundView.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.example.androiddevchallenge.main_view_background_view
17 |
18 | import androidx.compose.foundation.background
19 | import androidx.compose.foundation.layout.Box
20 | import androidx.compose.foundation.layout.BoxScope
21 | import androidx.compose.material.MaterialTheme
22 | import androidx.compose.runtime.Composable
23 | import androidx.compose.ui.Modifier
24 | import androidx.compose.ui.graphics.Brush
25 | import com.example.androiddevchallenge.theme.getMainViewBottomBackgroundColor
26 | import com.example.androiddevchallenge.theme.getMainViewTopBackgroundColor
27 |
28 | @Composable
29 | fun MainViewBackgroundView(
30 | modifier: Modifier = Modifier,
31 | content: @Composable BoxScope.() -> Unit
32 | ) {
33 | Box(
34 | modifier = modifier.background(
35 | brush = Brush.verticalGradient(
36 | colors = listOf(
37 | MaterialTheme.colors.getMainViewTopBackgroundColor(),
38 | MaterialTheme.colors.getMainViewBottomBackgroundColor()
39 | )
40 | )
41 | )
42 | ) {
43 | content()
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/app/src/main/java/com/example/androiddevchallenge/main_view_top_bar_view/MainViewTopBarViewContract.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.example.androiddevchallenge.main_view_top_bar_view
17 |
18 | import androidx.lifecycle.MutableLiveData
19 | import com.example.androiddevchallenge.weather.Weather
20 | import com.example.androiddevchallenge.weather_unit.WeatherUnit
21 |
22 | interface MainViewTopBarViewContract {
23 |
24 | interface UserAction {
25 |
26 | fun getCity(): MutableLiveData
27 |
28 | fun getDate(): MutableLiveData
29 |
30 | fun getTemperature(): MutableLiveData
31 |
32 | fun getWeatherType(): MutableLiveData
33 |
34 | fun onTemperatureClick()
35 |
36 | fun onCityClicked()
37 |
38 | fun onTemperatureUnitClicked(weatherUnit: WeatherUnit)
39 |
40 | /**
41 | * @return True if current
42 | */
43 | fun onTemperatureUnitDisplay(metric: WeatherUnit): Boolean
44 | }
45 |
46 | interface Screen
47 | }
48 |
--------------------------------------------------------------------------------
/app/src/main/java/com/example/androiddevchallenge/main_view_top_bar_view/MainViewTopBarViewPresenter.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.example.androiddevchallenge.main_view_top_bar_view
17 |
18 | import androidx.lifecycle.MutableLiveData
19 | import com.example.androiddevchallenge.city.CityManager
20 | import com.example.androiddevchallenge.date.DateManager
21 | import com.example.androiddevchallenge.weather.Weather
22 | import com.example.androiddevchallenge.weather.WeatherManager
23 | import com.example.androiddevchallenge.weather_unit.WeatherUnit
24 | import com.example.androiddevchallenge.weather_unit.WeatherUnitManager
25 |
26 | class MainViewTopBarViewPresenter(
27 | private val screen: MainViewTopBarViewContract.Screen,
28 | private val cityManager: CityManager,
29 | private val dateManager: DateManager,
30 | private val weatherManager: WeatherManager,
31 | private val weatherUnitManager: WeatherUnitManager
32 | ) : MainViewTopBarViewContract.UserAction {
33 |
34 | private var city = MutableLiveData(createCity())
35 | private var date = MutableLiveData(createDate())
36 | private var temperature = MutableLiveData(createTemperature())
37 | private var weatherType = MutableLiveData(Weather.Type.SNOW)
38 |
39 | init {
40 | // Require remove call?
41 | cityManager.addListener(createCityListener())
42 | weatherManager.addListener(createWeatherListener())
43 | }
44 |
45 | override fun getCity(): MutableLiveData {
46 | return city
47 | }
48 |
49 | override fun getDate(): MutableLiveData {
50 | return date
51 | }
52 |
53 | override fun getTemperature(): MutableLiveData {
54 | return temperature
55 | }
56 |
57 | override fun getWeatherType(): MutableLiveData {
58 | return weatherType
59 | }
60 |
61 | override fun onTemperatureClick() {
62 | }
63 |
64 | override fun onCityClicked() {
65 | }
66 |
67 | override fun onTemperatureUnitClicked(weatherUnit: WeatherUnit) {
68 | weatherUnitManager.setWeatherUnit(weatherUnit)
69 | }
70 |
71 | override fun onTemperatureUnitDisplay(metric: WeatherUnit): Boolean {
72 | return weatherUnitManager.getWeatherUnit() == metric
73 | }
74 |
75 | private fun updateCity() {
76 | city.value = createCity()
77 | }
78 |
79 | private fun updateDate() {
80 | date.value = createDate()
81 | }
82 |
83 | private fun updateTemperature() {
84 | temperature.value = createTemperature()
85 | }
86 |
87 | private fun updateWeatherType() {
88 | weatherType.value = createWeatherType()
89 | }
90 |
91 | private fun createCity(): String {
92 | return cityManager.getCity()
93 | }
94 |
95 | private fun createDate(): String {
96 | val weather = weatherManager.getWeathers().firstOrNull() ?: return ""
97 | return dateManager.convertTimestampToSpecificFormat1(weather.timestampSecond)
98 | }
99 |
100 | private fun createTemperature(): String {
101 | val weather = weatherManager.getWeathers().firstOrNull() ?: return ""
102 | val temperature = weather.temperature.toInt()
103 | return "$temperature°"
104 | }
105 |
106 | private fun createWeatherType(): Weather.Type {
107 | val weather = weatherManager.getWeathers().firstOrNull() ?: return Weather.Type.SNOW
108 | return weather.type
109 | }
110 |
111 | private fun createCityListener() = object : CityManager.Listener {
112 | override fun onChanged() {
113 | updateCity()
114 | }
115 | }
116 |
117 | private fun createWeatherListener() = object : WeatherManager.Listener {
118 | override fun onChanged() {
119 | updateDate()
120 | updateTemperature()
121 | updateWeatherType()
122 | }
123 |
124 | override fun onFailed() {
125 | }
126 | }
127 | }
128 |
--------------------------------------------------------------------------------
/app/src/main/java/com/example/androiddevchallenge/network/NetworkManager.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.example.androiddevchallenge.network
17 |
18 | import androidx.annotation.WorkerThread
19 |
20 | interface NetworkManager {
21 |
22 | @WorkerThread
23 | fun get(url: String): String?
24 | }
25 |
--------------------------------------------------------------------------------
/app/src/main/java/com/example/androiddevchallenge/network/NetworkManagerImpl.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.example.androiddevchallenge.network
17 |
18 | import androidx.annotation.WorkerThread
19 | import okhttp3.OkHttpClient
20 | import okhttp3.Response
21 | import okhttp3.ResponseBody
22 | import java.io.Closeable
23 | import java.io.IOException
24 | import java.util.concurrent.TimeUnit
25 |
26 | class NetworkManagerImpl : NetworkManager {
27 |
28 | @WorkerThread
29 | override fun get(url: String): String? {
30 | val okHttpRequestBuilder = okhttp3.Request.Builder()
31 | .url(url)
32 | .get()
33 | var okHttpResponse: Response? = null
34 | var body: ResponseBody? = null
35 | return try {
36 | okHttpResponse = okHttpClient.value.newCall(okHttpRequestBuilder.build()).execute()
37 | body = okHttpResponse.body()
38 | body?.string()
39 | } catch (e: IOException) {
40 | throw IllegalStateException(e)
41 | } finally {
42 | closeSilently(body, okHttpResponse)
43 | }
44 | }
45 |
46 | companion object {
47 |
48 | private val okHttpClient = lazy {
49 | val builder = OkHttpClient.Builder()
50 | builder.connectTimeout(15, TimeUnit.SECONDS)
51 | builder.build()
52 | }
53 |
54 | private fun closeSilently(vararg xs: Closeable?) {
55 | for (x in xs) {
56 | try {
57 | x?.close()
58 | } catch (ignored: Throwable) {
59 | }
60 | }
61 | }
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/app/src/main/java/com/example/androiddevchallenge/network/NetworkModule.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.example.androiddevchallenge.network
17 |
18 | class NetworkModule {
19 |
20 | fun createNetworkManager(): NetworkManager {
21 | return NetworkManagerImpl()
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/app/src/main/java/com/example/androiddevchallenge/neumorphism_card_square_view/NeumorphismCardSquareView.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.example.androiddevchallenge.neumorphism_card_square_view
17 |
18 | import android.animation.AnimatorInflater
19 | import androidx.compose.foundation.layout.Box
20 | import androidx.compose.foundation.layout.BoxScope
21 | import androidx.compose.foundation.layout.fillMaxHeight
22 | import androidx.compose.foundation.layout.fillMaxWidth
23 | import androidx.compose.foundation.layout.height
24 | import androidx.compose.foundation.layout.width
25 | import androidx.compose.material.MaterialTheme
26 | import androidx.compose.runtime.Composable
27 | import androidx.compose.ui.Alignment
28 | import androidx.compose.ui.Modifier
29 | import androidx.compose.ui.graphics.Color
30 | import androidx.compose.ui.tooling.preview.Preview
31 | import androidx.compose.ui.unit.dp
32 | import androidx.compose.ui.viewinterop.AndroidView
33 | import com.example.androiddevchallenge.R
34 | import com.example.androiddevchallenge.main_view_background_view.MainViewBackgroundView
35 | import com.example.androiddevchallenge.theme.MainTheme
36 | import soup.neumorphism.NeumorphImageButton
37 | import soup.neumorphism.ShapeType
38 |
39 | @Composable
40 | fun NeumorphismCardSquareView(
41 | modifier: Modifier = Modifier,
42 | onClick: (() -> Unit)? = null,
43 | @ShapeType shapeType: Int = ShapeType.DEFAULT,
44 | backgroundColor: Color = Color.Transparent,
45 | content: @Composable BoxScope.() -> Unit
46 | ) {
47 | Box(
48 | modifier = modifier
49 | ) {
50 | val light = MaterialTheme.colors.isLight
51 | val topStartShadowColor = if (light) "#C6CEDA" else "#101010"
52 | val bottomEndShadowColor = if (light) "#FEFEFF" else "#262C37"
53 | AndroidView(
54 | modifier = modifier
55 | .fillMaxWidth()
56 | .fillMaxHeight(),
57 | factory = { context ->
58 | NeumorphImageButton(context).apply {
59 | setShadowColorLight(android.graphics.Color.parseColor(bottomEndShadowColor))
60 | setShadowColorDark(android.graphics.Color.parseColor(topStartShadowColor))
61 | setShapeType(shapeType)
62 | setBackgroundColor(
63 | argb(
64 | backgroundColor.alpha,
65 | backgroundColor.red,
66 | backgroundColor.green,
67 | backgroundColor.blue
68 | )
69 | )
70 | stateListAnimator = AnimatorInflater.loadStateListAnimator(
71 | context,
72 | R.animator.button_state_list_anim_neumorph
73 | )
74 | if (onClick != null) {
75 | setOnClickListener {
76 | onClick()
77 | }
78 | }
79 | }
80 | }
81 | )
82 | content()
83 | }
84 | }
85 |
86 | @Preview("Light Theme", widthDp = 360, heightDp = 640)
87 | @Composable
88 | fun NeumorphismCardSquareViewLightPreview() {
89 | MainTheme {
90 | MainViewBackgroundView {
91 | NeumorphismCardSquareView(
92 | modifier = Modifier
93 | .align(Alignment.Center)
94 | .width(160.dp)
95 | .height(160.dp)
96 | ) {
97 | }
98 | }
99 | }
100 | }
101 |
102 | @Preview("Dark Theme", widthDp = 360, heightDp = 640)
103 | @Composable
104 | fun NeumorphismCardSquareViewDarkPreview() {
105 | MainTheme(darkTheme = true) {
106 | MainViewBackgroundView {
107 | NeumorphismCardSquareView(
108 | modifier = Modifier
109 | .align(Alignment.Center)
110 | .width(160.dp)
111 | .height(160.dp)
112 | ) {
113 | }
114 | }
115 | }
116 | }
117 |
118 | private fun argb(alpha: Float, red: Float, green: Float, blue: Float): Int {
119 | return (alpha * 255.0f + 0.5f).toInt() shl 24 or
120 | ((red * 255.0f + 0.5f).toInt() shl 16) or
121 | ((green * 255.0f + 0.5f).toInt() shl 8) or
122 | (blue * 255.0f + 0.5f).toInt()
123 | }
124 |
--------------------------------------------------------------------------------
/app/src/main/java/com/example/androiddevchallenge/theme/Shape.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.example.androiddevchallenge.theme
17 |
18 | import androidx.compose.foundation.shape.RoundedCornerShape
19 | import androidx.compose.material.Shapes
20 | import androidx.compose.ui.unit.dp
21 |
22 | val shapes = Shapes(
23 | small = RoundedCornerShape(4.dp),
24 | medium = RoundedCornerShape(4.dp),
25 | large = RoundedCornerShape(0.dp)
26 | )
27 |
--------------------------------------------------------------------------------
/app/src/main/java/com/example/androiddevchallenge/theme/ThemeCompose.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.example.androiddevchallenge.theme
17 |
18 | import androidx.compose.foundation.isSystemInDarkTheme
19 | import androidx.compose.material.Colors
20 | import androidx.compose.material.MaterialTheme
21 | import androidx.compose.material.darkColors
22 | import androidx.compose.material.lightColors
23 | import androidx.compose.runtime.Composable
24 | import androidx.compose.ui.graphics.Color
25 | import com.example.androiddevchallenge.weather.Weather
26 |
27 | private val DarkColorPalette = darkColors(
28 | primary = Color(0xFFFDE807),
29 | primaryVariant = Color(0xFFFDE807),
30 | secondary = Color(0xFF30B0D3),
31 | background = Color(0xFF0B222F)
32 | )
33 |
34 | private val LightColorPalette = lightColors(
35 | primary = Color(0xFF0B222F),
36 | primaryVariant = Color(0xFF0B222F),
37 | secondary = Color(0xFF30B0D3),
38 | background = Color(0xFFEEF0F5),
39 | surface = Color.White,
40 | onPrimary = Color.White,
41 | onSecondary = Color.Black,
42 | onBackground = Color.Black,
43 | onSurface = Color.Black,
44 | )
45 |
46 | @Composable
47 | fun Colors.getMainViewTopBackgroundColor(): Color {
48 | return if (isLight) {
49 | Color(0XFFEEF0F5)
50 | } else {
51 | Color(0XFF394253)
52 | }
53 | }
54 |
55 | @Composable
56 | fun Colors.getMainViewBottomBackgroundColor(): Color {
57 | return if (isLight) {
58 | Color(0XFFEEF0F5)
59 | } else {
60 | Color(0XFF181C27)
61 | }
62 | }
63 |
64 | @Composable
65 | fun Colors.getMainViewTopBarViewTextColor(): Color {
66 | return if (isLight) {
67 | Color.Black
68 | } else {
69 | Color.White
70 | }
71 | }
72 |
73 | @Composable
74 | fun Colors.getMainViewTopBarViewDateTextColor(weatherType: Weather.Type): Color {
75 | when (weatherType) {
76 | Weather.Type.CLEAR -> if (isLight) {
77 | Color(0xFFEB8202)
78 | } else {
79 | Color(0xFFD89037)
80 | }
81 | Weather.Type.THUNDERSTORM -> {
82 | }
83 | Weather.Type.DRIZZLE -> {
84 | }
85 | Weather.Type.CLOUDS,
86 | Weather.Type.CLOUDS_SCATTERED_CLOUDS,
87 | Weather.Type.CLOUDS_BROKEN_CLOUDS,
88 | Weather.Type.CLOUDS_FEW_CLOUDS -> return if (isLight) {
89 | Color(0xFF575757)
90 | } else {
91 | Color(0xFFBBBBBB)
92 | }
93 | Weather.Type.RAIN,
94 | Weather.Type.RAIN_FREEZING_RAIN,
95 | Weather.Type.RAIN_VERY_HEAVY_RAIN,
96 | Weather.Type.RAIN_HEAVY_INTENSITY -> return if (isLight) {
97 | Color(0xFF00A1CE)
98 | } else {
99 | Color(0xFF30B0D3)
100 | }
101 | Weather.Type.RAIN_MODERATE_RAIN -> {
102 | }
103 | Weather.Type.RAIN_LIGHT_RAIN -> {
104 | }
105 | Weather.Type.SNOW -> {
106 | }
107 | Weather.Type.SNOW_LIGHT_SNOW -> {
108 | }
109 | Weather.Type.MIST -> {
110 | }
111 | }
112 | return if (isLight) {
113 | Color(0xFFEBCC02)
114 | } else {
115 | Color(0xFFFDE807)
116 | }
117 | }
118 |
119 | @Composable
120 | fun Colors.getMainViewTopViewCardColor(): Color {
121 | return if (isLight) {
122 | Color(0XFFEEF0F5)
123 | } else {
124 | Color(0XFF394253)
125 | }
126 | }
127 |
128 | @Composable
129 | fun Colors.getTextPrimaryColor(): Color {
130 | return if (isLight) {
131 | Color(0XFF000000)
132 | } else {
133 | Color(0XFFFFFFFF)
134 | }
135 | }
136 |
137 | @Composable
138 | fun Colors.getTextSecondaryColor(): Color {
139 | return if (isLight) {
140 | Color(0XFF404040)
141 | } else {
142 | Color(0XFFC0C0C0)
143 | }
144 | }
145 |
146 | @Composable
147 | fun Colors.getTextThirdColor(): Color {
148 | return if (isLight) {
149 | Color(0XFF808080)
150 | } else {
151 | Color(0XFFA0A0A0)
152 | }
153 | }
154 |
155 | @Composable
156 | fun Colors.getTextHintColor(): Color {
157 | return if (isLight) {
158 | Color(0XFFB0B0B0)
159 | } else {
160 | Color(0XFF909090)
161 | }
162 | }
163 |
164 | @Composable
165 | fun Colors.getForecastViewCardColor(): Color {
166 | return if (isLight) {
167 | Color(0XFFEEF0F5)
168 | } else {
169 | Color(0XFF181C27)
170 | }
171 | }
172 |
173 | @Composable
174 | fun MainTheme(
175 | darkTheme: Boolean = isSystemInDarkTheme(),
176 | content: @Composable() () -> Unit
177 | ) {
178 | val colors = if (darkTheme) {
179 | DarkColorPalette
180 | } else {
181 | LightColorPalette
182 | }
183 |
184 | MaterialTheme(
185 | colors = colors,
186 | typography = typography,
187 | shapes = shapes,
188 | content = content
189 | )
190 | }
191 |
--------------------------------------------------------------------------------
/app/src/main/java/com/example/androiddevchallenge/theme/ThemeManager.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.example.androiddevchallenge.theme
17 |
18 | interface ThemeManager {
19 |
20 | fun isLight(): Boolean
21 | }
22 |
--------------------------------------------------------------------------------
/app/src/main/java/com/example/androiddevchallenge/theme/ThemeManagerImpl.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.example.androiddevchallenge.theme
17 |
18 | import android.content.Context
19 | import com.example.androiddevchallenge.R
20 |
21 | class ThemeManagerImpl(
22 | private val context: Context
23 | ) : ThemeManager {
24 |
25 | override fun isLight(): Boolean {
26 | return context.resources.getBoolean(R.bool.theme_bool_light_mode)
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/app/src/main/java/com/example/androiddevchallenge/theme/ThemeModule.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.example.androiddevchallenge.theme
17 |
18 | import com.example.androiddevchallenge.graph.WeatherGraph
19 |
20 | class ThemeModule {
21 |
22 | fun createThemeManager(): ThemeManager {
23 | return ThemeManagerImpl(WeatherGraph.getContext())
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/app/src/main/java/com/example/androiddevchallenge/theme/Type.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.example.androiddevchallenge.theme
17 |
18 | import androidx.compose.material.Typography
19 | import androidx.compose.ui.text.TextStyle
20 | import androidx.compose.ui.text.font.FontFamily
21 | import androidx.compose.ui.text.font.FontWeight
22 | import androidx.compose.ui.unit.sp
23 |
24 | val typography = Typography(
25 | body1 = TextStyle(
26 | fontFamily = FontFamily.Default,
27 | fontWeight = FontWeight.Normal,
28 | fontSize = 16.sp
29 | ),
30 | button = TextStyle(
31 | fontFamily = FontFamily.Default,
32 | fontWeight = FontWeight.W500,
33 | fontSize = 14.sp
34 | ),
35 | caption = TextStyle(
36 | fontFamily = FontFamily.Default,
37 | fontWeight = FontWeight.Normal,
38 | fontSize = 12.sp
39 | )
40 | )
41 |
--------------------------------------------------------------------------------
/app/src/main/java/com/example/androiddevchallenge/weather/Weather.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.example.androiddevchallenge.weather
17 |
18 | import com.example.androiddevchallenge.weather_unit.WeatherUnit
19 | import java.util.concurrent.TimeUnit
20 |
21 | data class Weather(
22 | val city: String,
23 | val weatherUnit: WeatherUnit,
24 | val type: Type,
25 | val temperature: Float,
26 | val humidity: Int,
27 | val pressure: Int,
28 | val timestampSecond: Long
29 | ) {
30 |
31 | init {
32 | if (timestampSecond < 10_000) {
33 | throw IllegalStateException("Timestamp < 10_000: $timestampSecond")
34 | }
35 | }
36 |
37 | enum class Type {
38 | CLEAR,
39 | THUNDERSTORM,
40 | DRIZZLE,
41 | CLOUDS,
42 | CLOUDS_SCATTERED_CLOUDS,
43 | CLOUDS_BROKEN_CLOUDS,
44 | CLOUDS_FEW_CLOUDS,
45 | RAIN,
46 | RAIN_FREEZING_RAIN,
47 | RAIN_VERY_HEAVY_RAIN,
48 | RAIN_HEAVY_INTENSITY,
49 | RAIN_MODERATE_RAIN,
50 | RAIN_LIGHT_RAIN,
51 | SNOW,
52 | SNOW_LIGHT_SNOW,
53 | MIST
54 | }
55 |
56 | companion object {
57 |
58 | val fakeWeathers = listOf(
59 | Weather(
60 | city = "Paris, France",
61 | weatherUnit = WeatherUnit.METRIC,
62 | type = Type.THUNDERSTORM,
63 | temperature = 19f,
64 | humidity = 90,
65 | pressure = 900,
66 | timestampSecond = 1616321094
67 | ),
68 | Weather(
69 | city = "Paris, France",
70 | weatherUnit = WeatherUnit.METRIC,
71 | type = Type.CLOUDS,
72 | temperature = 12f,
73 | humidity = 90,
74 | pressure = 900,
75 | timestampSecond = 1616321094 + TimeUnit.DAYS.toMillis(1)
76 | ),
77 | Weather(
78 | city = "Paris, France",
79 | weatherUnit = WeatherUnit.METRIC,
80 | type = Type.CLEAR,
81 | temperature = 30f,
82 | humidity = 90,
83 | pressure = 900,
84 | timestampSecond = 1616321094 + TimeUnit.DAYS.toMillis(2)
85 | ),
86 | Weather(
87 | city = "Paris, France",
88 | weatherUnit = WeatherUnit.METRIC,
89 | type = Type.SNOW,
90 | temperature = -2f,
91 | humidity = 90,
92 | pressure = 900,
93 | timestampSecond = 1616321094 + TimeUnit.DAYS.toMillis(3)
94 | )
95 | )
96 |
97 | fun List.getOrNull(index: Int): Weather? {
98 | if (index >= size) {
99 | return null
100 | }
101 | return get(index)
102 | }
103 | }
104 | }
105 |
--------------------------------------------------------------------------------
/app/src/main/java/com/example/androiddevchallenge/weather/WeatherManager.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.example.androiddevchallenge.weather
17 |
18 | interface WeatherManager {
19 |
20 | fun load()
21 |
22 | /**
23 | * 0 is today, 1 is tomorrow...
24 | */
25 | fun getWeathers(): List
26 |
27 | fun clearCache()
28 |
29 | fun addListener(listener: Listener)
30 |
31 | fun removeListener(listener: Listener)
32 |
33 | interface Listener {
34 |
35 | fun onChanged()
36 |
37 | fun onFailed()
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/app/src/main/java/com/example/androiddevchallenge/weather/WeatherManagerImpl.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.example.androiddevchallenge.weather
17 |
18 | import com.example.androiddevchallenge.city.CityManager
19 | import com.example.androiddevchallenge.date.DateManager
20 | import com.example.androiddevchallenge.weather_api.WeatherApiException
21 | import com.example.androiddevchallenge.weather_api.WeatherApiManager
22 | import com.example.androiddevchallenge.weather_repository.WeatherRepository
23 | import com.example.androiddevchallenge.weather_unit.WeatherUnitManager
24 |
25 | class WeatherManagerImpl(
26 | private val weatherApiManager: WeatherApiManager,
27 | private val cityManager: CityManager,
28 | private val dateManager: DateManager,
29 | private val weatherRepository: WeatherRepository,
30 | private val weatherUnitManager: WeatherUnitManager,
31 | private val addOn: AddOn
32 | ) : WeatherManager {
33 |
34 | private val listeners = ArrayList()
35 |
36 | override fun load() {
37 | val city = cityManager.getCity()
38 | val weatherUnit = weatherUnitManager.getWeatherUnit()
39 | addOn.postWorkerThread {
40 | val weather = try {
41 | weatherApiManager.getWeather(
42 | city = city,
43 | weatherUnit = weatherUnit
44 | )
45 | } catch (e: WeatherApiException) {
46 | null
47 | }
48 | val weatherForecastDaily = try {
49 | weatherApiManager.getWeatherForecastDaily(
50 | city = city,
51 | weatherUnit = weatherUnit,
52 | numberOfDays = 7
53 | )
54 | } catch (e: WeatherApiException) {
55 | emptyList()
56 | }
57 | addOn.postMainThread {
58 | val succeeded = weather != null && weatherForecastDaily.isNotEmpty()
59 | if (!succeeded) {
60 | for (listener in listeners) {
61 | listener.onChanged()
62 | }
63 | for (listener in listeners) {
64 | listener.onFailed()
65 | }
66 | return@postMainThread
67 | }
68 | weatherRepository.setWeather(weather)
69 | weatherRepository.setWeatherForecastDaily(weatherForecastDaily)
70 | for (listener in listeners) {
71 | listener.onChanged()
72 | }
73 | }
74 | }
75 | }
76 |
77 | override fun getWeathers(): List {
78 | val weathers = ArrayList()
79 | val weather = weatherRepository.getWeather() ?: return weathers
80 | weathers.add(weather)
81 | weathers.addAll(
82 | weatherRepository.getWeatherForecastDaily().filter {
83 | dateManager.convertTimestampToSpecificFormat1(it.timestampSecond) !=
84 | dateManager.convertTimestampToSpecificFormat1(weather.timestampSecond)
85 | }
86 | )
87 | return weathers
88 | }
89 |
90 | override fun clearCache() {
91 | weatherRepository.setWeather(null)
92 | weatherRepository.setWeatherForecastDaily(emptyList())
93 | for (listener in listeners) {
94 | listener.onChanged()
95 | }
96 | }
97 |
98 | override fun addListener(listener: WeatherManager.Listener) {
99 | if (listeners.contains(listener)) {
100 | return
101 | }
102 | listeners.add(listener)
103 | }
104 |
105 | override fun removeListener(listener: WeatherManager.Listener) {
106 | listeners.remove(listener)
107 | }
108 |
109 | interface AddOn {
110 |
111 | fun postWorkerThread(runnable: Runnable)
112 |
113 | fun postMainThread(runnable: Runnable)
114 | }
115 | }
116 |
--------------------------------------------------------------------------------
/app/src/main/java/com/example/androiddevchallenge/weather/WeatherModule.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.example.androiddevchallenge.weather
17 |
18 | import android.os.Handler
19 | import android.os.HandlerThread
20 | import android.os.Looper
21 | import com.example.androiddevchallenge.graph.WeatherGraph
22 | import com.example.androiddevchallenge.weather_api.WeatherApiModule
23 | import com.example.androiddevchallenge.weather_repository.WeatherRepositoryModule
24 |
25 | class WeatherModule {
26 |
27 | fun createWeatherManager(): WeatherManager {
28 | return WeatherManagerImpl(
29 | WeatherApiModule().createWeatherApiManager(),
30 | WeatherGraph.getCityManager(),
31 | WeatherGraph.getDateManager(),
32 | WeatherRepositoryModule().createWeatherRepository(),
33 | WeatherGraph.getWeatherUnitManager(),
34 | createWeatherManagerImplAddOn()
35 | )
36 | }
37 |
38 | private fun createWeatherManagerImplAddOn() = object : WeatherManagerImpl.AddOn {
39 |
40 | private val workerThread by lazy { createWorkerThread() }
41 | private val workerThreadHandler by lazy { Handler(workerThread.looper) }
42 | private val mainHandler by lazy { Handler(Looper.getMainLooper()) }
43 |
44 | override fun postWorkerThread(runnable: Runnable) {
45 | workerThreadHandler.post(runnable)
46 | }
47 |
48 | override fun postMainThread(runnable: Runnable) {
49 | mainHandler.post(runnable)
50 | }
51 |
52 | private fun createWorkerThread(): HandlerThread {
53 | val tmp = HandlerThread("weather_load")
54 | tmp.start()
55 | return tmp
56 | }
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/app/src/main/java/com/example/androiddevchallenge/weather_api/WeatherApiException.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.example.androiddevchallenge.weather_api
17 |
18 | class WeatherApiException(
19 | message: String,
20 | e: Throwable? = null
21 | ) : Exception(
22 | message,
23 | e
24 | )
25 |
--------------------------------------------------------------------------------
/app/src/main/java/com/example/androiddevchallenge/weather_api/WeatherApiManager.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.example.androiddevchallenge.weather_api
17 |
18 | import androidx.annotation.IntRange
19 | import androidx.annotation.WorkerThread
20 | import com.example.androiddevchallenge.weather.Weather
21 | import com.example.androiddevchallenge.weather_unit.WeatherUnit
22 |
23 | interface WeatherApiManager {
24 |
25 | /**
26 | * @throws WeatherApiException
27 | */
28 | @WorkerThread
29 | fun getWeather(
30 | city: String,
31 | weatherUnit: WeatherUnit
32 | ): Weather
33 |
34 | /**
35 | * @throws WeatherApiException
36 | */
37 | @WorkerThread
38 | fun getWeatherForecastDaily(
39 | city: String,
40 | weatherUnit: WeatherUnit,
41 | @IntRange(from = 1, to = 16)
42 | numberOfDays: Int
43 | ): List
44 | }
45 |
--------------------------------------------------------------------------------
/app/src/main/java/com/example/androiddevchallenge/weather_api/WeatherApiModule.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.example.androiddevchallenge.weather_api
17 |
18 | import com.example.androiddevchallenge.graph.WeatherGraph
19 |
20 | class WeatherApiModule {
21 |
22 | fun createWeatherApiManager(): WeatherApiManager {
23 | return WeatherApiManagerImpl(
24 | WeatherGraph.getNetworkManager()
25 | )
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/app/src/main/java/com/example/androiddevchallenge/weather_icon_view/WeatherIconView.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.example.androiddevchallenge.weather_icon_view
17 |
18 | import androidx.compose.foundation.Image
19 | import androidx.compose.foundation.layout.fillMaxHeight
20 | import androidx.compose.foundation.layout.fillMaxWidth
21 | import androidx.compose.runtime.Composable
22 | import androidx.compose.ui.Modifier
23 | import androidx.compose.ui.res.painterResource
24 | import com.example.androiddevchallenge.R
25 | import com.example.androiddevchallenge.weather.Weather
26 |
27 | @Composable
28 | fun WeatherIconView(
29 | modifier: Modifier = Modifier,
30 | weatherType: Weather.Type
31 | ) {
32 | Image(
33 | painter = painterResource(weatherType.toDrawableRes()),
34 | contentDescription = weatherType.toImageContentDescription(),
35 | modifier = modifier
36 | .fillMaxWidth()
37 | .fillMaxHeight()
38 | )
39 | }
40 |
41 | private fun Weather.Type.toImageContentDescription(): String {
42 | return "Weather is: " + when (this) {
43 | Weather.Type.CLEAR -> "clear"
44 | Weather.Type.THUNDERSTORM -> "thunderstorm"
45 | Weather.Type.DRIZZLE -> "drizzle"
46 | Weather.Type.CLOUDS -> "clouds"
47 | Weather.Type.CLOUDS_SCATTERED_CLOUDS -> "scattered clouds"
48 | Weather.Type.CLOUDS_BROKEN_CLOUDS -> "broken clouds"
49 | Weather.Type.CLOUDS_FEW_CLOUDS -> "few clouds"
50 | Weather.Type.RAIN -> "rain"
51 | Weather.Type.RAIN_FREEZING_RAIN -> "freezing rain"
52 | Weather.Type.RAIN_VERY_HEAVY_RAIN -> "very heavy rain"
53 | Weather.Type.RAIN_HEAVY_INTENSITY -> "heavy intensity rain"
54 | Weather.Type.RAIN_MODERATE_RAIN -> "moderate rain"
55 | Weather.Type.RAIN_LIGHT_RAIN -> "light rain"
56 | Weather.Type.SNOW -> "snow"
57 | Weather.Type.SNOW_LIGHT_SNOW -> "light snow"
58 | Weather.Type.MIST -> "mist"
59 | }
60 | }
61 |
62 | private fun Weather.Type.toDrawableRes(): Int {
63 | return when (this) {
64 | Weather.Type.CLEAR -> R.drawable.weather_sun
65 | Weather.Type.THUNDERSTORM -> R.drawable.weather_storm
66 | Weather.Type.DRIZZLE -> R.drawable.weather_2_freezing_drizzle
67 | Weather.Type.CLOUDS -> R.drawable.weather_2_cloudy
68 | Weather.Type.CLOUDS_SCATTERED_CLOUDS -> R.drawable.weather_2_partly_cloudy_day
69 | Weather.Type.CLOUDS_BROKEN_CLOUDS -> R.drawable.weather_2_partly_cloudy_day
70 | Weather.Type.CLOUDS_FEW_CLOUDS -> R.drawable.weather_2_partly_cloudy_day
71 | Weather.Type.RAIN -> R.drawable.weather_rain
72 | Weather.Type.RAIN_FREEZING_RAIN -> R.drawable.weather_sun_cloud_angled_rain
73 | Weather.Type.RAIN_VERY_HEAVY_RAIN -> R.drawable.weather_sun_cloud_angled_rain
74 | Weather.Type.RAIN_HEAVY_INTENSITY -> R.drawable.weather_sun_cloud_angled_rain
75 | Weather.Type.RAIN_MODERATE_RAIN -> R.drawable.weather_sun_cloud_little_rain
76 | Weather.Type.RAIN_LIGHT_RAIN -> R.drawable.weather_rain
77 | Weather.Type.SNOW -> R.drawable.weather_mid_snow_fast_winds
78 | Weather.Type.SNOW_LIGHT_SNOW -> R.drawable.weather_snow
79 | Weather.Type.MIST -> R.drawable.weather_2_mist
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/app/src/main/java/com/example/androiddevchallenge/weather_repository/WeatherRepository.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.example.androiddevchallenge.weather_repository
17 |
18 | import com.example.androiddevchallenge.weather.Weather
19 |
20 | interface WeatherRepository {
21 |
22 | fun getWeather(): Weather?
23 |
24 | fun setWeather(weather: Weather?)
25 |
26 | fun getWeatherForecastDaily(): List
27 |
28 | fun setWeatherForecastDaily(weathers: List)
29 |
30 | fun addListener(listener: Listener)
31 |
32 | fun removeListener(listener: Listener)
33 |
34 | interface Listener {
35 |
36 | fun onChanged()
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/app/src/main/java/com/example/androiddevchallenge/weather_repository/WeatherRepositoryModule.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.example.androiddevchallenge.weather_repository
17 |
18 | import android.content.Context
19 | import android.content.SharedPreferences
20 | import com.example.androiddevchallenge.graph.WeatherGraph
21 |
22 | class WeatherRepositoryModule {
23 |
24 | fun createWeatherRepository(): WeatherRepository {
25 | return WeatherRepositoryImpl(
26 | createSharedPreferences()
27 | )
28 | }
29 |
30 | private fun createSharedPreferences(): SharedPreferences {
31 | val context = WeatherGraph.getContext()
32 | return context.getSharedPreferences(
33 | WeatherRepositoryImpl.PREFERENCE_NAME,
34 | Context.MODE_PRIVATE
35 | )
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/app/src/main/java/com/example/androiddevchallenge/weather_unit/WeatherUnit.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.example.androiddevchallenge.weather_unit
17 |
18 | enum class WeatherUnit {
19 | STANDARD,
20 | METRIC,
21 | IMPERIAL
22 | }
23 |
--------------------------------------------------------------------------------
/app/src/main/java/com/example/androiddevchallenge/weather_unit/WeatherUnitManager.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.example.androiddevchallenge.weather_unit
17 |
18 | interface WeatherUnitManager {
19 |
20 | fun getWeatherUnit(): WeatherUnit
21 |
22 | fun setWeatherUnit(weatherUnit: WeatherUnit)
23 |
24 | fun addListener(listener: Listener)
25 |
26 | fun removeListener(listener: Listener)
27 |
28 | interface Listener {
29 |
30 | fun onChanged()
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/app/src/main/java/com/example/androiddevchallenge/weather_unit/WeatherUnitManagerImpl.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.example.androiddevchallenge.weather_unit
17 |
18 | import android.content.SharedPreferences
19 |
20 | class WeatherUnitManagerImpl(
21 | private val sharedPreferences: SharedPreferences
22 | ) : WeatherUnitManager {
23 |
24 | private val listeners = ArrayList()
25 | private var weatherUnit = WeatherUnit.METRIC
26 | private var loaded = false
27 |
28 | override fun getWeatherUnit(): WeatherUnit {
29 | loadIfNeeded()
30 | return weatherUnit
31 | }
32 |
33 | override fun setWeatherUnit(weatherUnit: WeatherUnit) {
34 | loadIfNeeded()
35 | if (this.weatherUnit == weatherUnit) {
36 | return
37 | }
38 | this.weatherUnit = weatherUnit
39 | save()
40 | for (listener in listeners) {
41 | listener.onChanged()
42 | }
43 | }
44 |
45 | override fun addListener(listener: WeatherUnitManager.Listener) {
46 | if (listeners.contains(listener)) {
47 | return
48 | }
49 | listeners.add(listener)
50 | }
51 |
52 | override fun removeListener(listener: WeatherUnitManager.Listener) {
53 | listeners.remove(listener)
54 | }
55 |
56 | private fun loadIfNeeded() {
57 | if (loaded) {
58 | return
59 | }
60 | weatherUnit = when (sharedPreferences.getString("unit", "metric")) {
61 | "standard" -> WeatherUnit.STANDARD
62 | "metric" -> WeatherUnit.METRIC
63 | "imperial" -> WeatherUnit.IMPERIAL
64 | else -> WeatherUnit.METRIC
65 | }
66 | loaded = true
67 | }
68 |
69 | private fun save() {
70 | sharedPreferences.edit()
71 | .putString(
72 | "unit",
73 | when (weatherUnit) {
74 | WeatherUnit.STANDARD -> "standard"
75 | WeatherUnit.METRIC -> "metric"
76 | WeatherUnit.IMPERIAL -> "imperial"
77 | }
78 | ).apply()
79 | }
80 |
81 | companion object {
82 |
83 | const val PREFERENCE_NAME = "weather_unit"
84 | }
85 | }
86 |
--------------------------------------------------------------------------------
/app/src/main/java/com/example/androiddevchallenge/weather_unit/WeatherUnitModule.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.example.androiddevchallenge.weather_unit
17 |
18 | import android.content.Context
19 | import android.content.SharedPreferences
20 | import com.example.androiddevchallenge.graph.WeatherGraph
21 |
22 | class WeatherUnitModule {
23 |
24 | fun createWeatherUnitManager(): WeatherUnitManager {
25 | return WeatherUnitManagerImpl(
26 | createSharedPreferences()
27 | )
28 | }
29 |
30 | private fun createSharedPreferences(): SharedPreferences {
31 | val context = WeatherGraph.getContext()
32 | return context.getSharedPreferences(
33 | WeatherUnitManagerImpl.PREFERENCE_NAME,
34 | Context.MODE_PRIVATE
35 | )
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/app/src/main/res/city_edit_view/drawable-night/city_edit_view_ic_outline_info_24.xml:
--------------------------------------------------------------------------------
1 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/city_edit_view/drawable-night/city_edit_view_loop.xml:
--------------------------------------------------------------------------------
1 |
6 |
13 |
20 |
21 |
--------------------------------------------------------------------------------
/app/src/main/res/city_edit_view/drawable/city_edit_view_ic_outline_info_24.xml:
--------------------------------------------------------------------------------
1 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/city_edit_view/drawable/city_edit_view_loop.xml:
--------------------------------------------------------------------------------
1 |
6 |
13 |
20 |
21 |
--------------------------------------------------------------------------------
/app/src/main/res/city_edit_view/values-fr/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
12 | Ville
13 | Cherche une ville
14 | C-Weather
15 | Fait par Jonathan Mercandalli (Mercandj sur GitHub)
16 | \n\n
17 | Fait pour le challenge de Jetpack compose de la semaine 4.
18 | \n\n
19 | Supporte les 2 themes: sombre et clair. L\'interface graphique est neumorphism.
20 |
--------------------------------------------------------------------------------
/app/src/main/res/city_edit_view/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
12 | City
13 | Search a city
14 | C-Weather
15 | Done by Jonathan Mercandalli (Mercandj on GitHub)
16 | \n\n
17 | Done for the Jetpack compose challenge week 4.
18 | \n\n
19 | Support Light and Dark theme. UI neumorphism.
20 |
--------------------------------------------------------------------------------
/app/src/main/res/error_view/values-fr/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
12 | Pas trouvé
13 | Les raisons possibles:
14 | Image montrant que ça à raté
15 | - La ville rentrée n\'existe pas
16 | - Tu n\'as pas internet
17 | - Le server est OFF
18 |
--------------------------------------------------------------------------------
/app/src/main/res/error_view/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
12 | No weather found
13 | Possible reasons:
14 | Error image
15 | - The city is unknown
16 | - You do not have internet
17 | - The server is OFF
18 |
--------------------------------------------------------------------------------
/app/src/main/res/icon/color/ic_launcher_background_gradient.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/app/src/main/res/icon/color/ic_launcher_background_gradient_dark.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/app/src/main/res/icon/drawable-night/ic_launcher_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/icon/drawable-v24/ic_foreground_weather.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/icon/drawable-v24/ic_foreground_weather.png
--------------------------------------------------------------------------------
/app/src/main/res/icon/drawable/ic_launcher_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/icon/drawable/ic_launcher_background_night.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/icon/mipmap-anydpi-v26/ic_launcher.xml:
--------------------------------------------------------------------------------
1 |
2 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/app/src/main/res/icon/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/icon/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/icon/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/icon/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/icon/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/icon/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/icon/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/icon/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/icon/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/icon/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/main/values-night/themes.xml:
--------------------------------------------------------------------------------
1 |
2 |
12 |
13 |
24 |
--------------------------------------------------------------------------------
/app/src/main/res/main/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
12 | C-Weather
13 |
--------------------------------------------------------------------------------
/app/src/main/res/main/values/themes.xml:
--------------------------------------------------------------------------------
1 |
2 |
12 |
13 |
24 |
25 |
29 |
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/app/src/main/res/main_activity/drawable-hdpi/main_activity_splash_image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/main_activity/drawable-hdpi/main_activity_splash_image.png
--------------------------------------------------------------------------------
/app/src/main/res/main_activity/drawable-mdpi/main_activity_splash_image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/main_activity/drawable-mdpi/main_activity_splash_image.png
--------------------------------------------------------------------------------
/app/src/main/res/main_activity/drawable-night/main_activity_splash_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | -
7 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/app/src/main/res/main_activity/drawable-xhdpi/main_activity_splash_image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/main_activity/drawable-xhdpi/main_activity_splash_image.png
--------------------------------------------------------------------------------
/app/src/main/res/main_activity/drawable-xxhdpi/main_activity_splash_image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/main_activity/drawable-xxhdpi/main_activity_splash_image.png
--------------------------------------------------------------------------------
/app/src/main/res/main_activity/drawable-xxxhdpi/main_activity_splash_image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/main_activity/drawable-xxxhdpi/main_activity_splash_image.png
--------------------------------------------------------------------------------
/app/src/main/res/main_activity/drawable/main_activity_splash_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | -
7 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/app/src/main/res/main_activity/values-night/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | #FF394253
5 |
6 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/main_activity/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | #E5E5E5
5 |
6 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/main_activity/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/app/src/main/res/main_activity_splash_dark/drawable-hdpi/main_activity_splash_image_dark.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/main_activity_splash_dark/drawable-hdpi/main_activity_splash_image_dark.png
--------------------------------------------------------------------------------
/app/src/main/res/main_activity_splash_dark/drawable-mdpi/main_activity_splash_image_dark.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/main_activity_splash_dark/drawable-mdpi/main_activity_splash_image_dark.png
--------------------------------------------------------------------------------
/app/src/main/res/main_activity_splash_dark/drawable-xhdpi/main_activity_splash_image_dark.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/main_activity_splash_dark/drawable-xhdpi/main_activity_splash_image_dark.png
--------------------------------------------------------------------------------
/app/src/main/res/main_activity_splash_dark/drawable-xxhdpi/main_activity_splash_image_dark.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/main_activity_splash_dark/drawable-xxhdpi/main_activity_splash_image_dark.png
--------------------------------------------------------------------------------
/app/src/main/res/main_activity_splash_dark/drawable-xxxhdpi/main_activity_splash_image_dark.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/main_activity_splash_dark/drawable-xxxhdpi/main_activity_splash_image_dark.png
--------------------------------------------------------------------------------
/app/src/main/res/main_weather_animated_view/drawable-hdpi/main_weather_animated_view_circle_with_shadow.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/main_weather_animated_view/drawable-hdpi/main_weather_animated_view_circle_with_shadow.webp
--------------------------------------------------------------------------------
/app/src/main/res/main_weather_animated_view/drawable-mdpi/main_weather_animated_view_circle_with_shadow.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/main_weather_animated_view/drawable-mdpi/main_weather_animated_view_circle_with_shadow.webp
--------------------------------------------------------------------------------
/app/src/main/res/main_weather_animated_view/drawable-xhdpi/main_weather_animated_view_circle_with_shadow.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/main_weather_animated_view/drawable-xhdpi/main_weather_animated_view_circle_with_shadow.webp
--------------------------------------------------------------------------------
/app/src/main/res/main_weather_animated_view/drawable-xxhdpi/main_weather_animated_view_circle_with_shadow.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/main_weather_animated_view/drawable-xxhdpi/main_weather_animated_view_circle_with_shadow.webp
--------------------------------------------------------------------------------
/app/src/main/res/main_weather_animated_view/drawable-xxxhdpi/main_weather_animated_view_circle_with_shadow.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/main_weather_animated_view/drawable-xxxhdpi/main_weather_animated_view_circle_with_shadow.webp
--------------------------------------------------------------------------------
/app/src/main/res/main_weather_animated_view/drawable/main_weather_animated_view_circle_gradient_yellow.xml:
--------------------------------------------------------------------------------
1 |
7 |
11 |
12 |
18 |
21 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/app/src/main/res/main_weather_animated_view_figure/drawable-hdpi/main_weather_animated_view_figure_1.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/main_weather_animated_view_figure/drawable-hdpi/main_weather_animated_view_figure_1.webp
--------------------------------------------------------------------------------
/app/src/main/res/main_weather_animated_view_figure/drawable-hdpi/main_weather_animated_view_figure_2.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/main_weather_animated_view_figure/drawable-hdpi/main_weather_animated_view_figure_2.webp
--------------------------------------------------------------------------------
/app/src/main/res/main_weather_animated_view_figure/drawable-hdpi/main_weather_animated_view_figure_3.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/main_weather_animated_view_figure/drawable-hdpi/main_weather_animated_view_figure_3.webp
--------------------------------------------------------------------------------
/app/src/main/res/main_weather_animated_view_figure/drawable-hdpi/main_weather_animated_view_figure_4.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/main_weather_animated_view_figure/drawable-hdpi/main_weather_animated_view_figure_4.webp
--------------------------------------------------------------------------------
/app/src/main/res/main_weather_animated_view_figure/drawable-hdpi/main_weather_animated_view_figure_5.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/main_weather_animated_view_figure/drawable-hdpi/main_weather_animated_view_figure_5.webp
--------------------------------------------------------------------------------
/app/src/main/res/main_weather_animated_view_figure/drawable-hdpi/main_weather_animated_view_figure_6.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/main_weather_animated_view_figure/drawable-hdpi/main_weather_animated_view_figure_6.webp
--------------------------------------------------------------------------------
/app/src/main/res/main_weather_animated_view_figure/drawable-hdpi/main_weather_animated_view_figure_7.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/main_weather_animated_view_figure/drawable-hdpi/main_weather_animated_view_figure_7.webp
--------------------------------------------------------------------------------
/app/src/main/res/main_weather_animated_view_figure/drawable-hdpi/main_weather_animated_view_figure_8.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/main_weather_animated_view_figure/drawable-hdpi/main_weather_animated_view_figure_8.webp
--------------------------------------------------------------------------------
/app/src/main/res/main_weather_animated_view_figure/drawable-mdpi/main_weather_animated_view_figure_1.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/main_weather_animated_view_figure/drawable-mdpi/main_weather_animated_view_figure_1.webp
--------------------------------------------------------------------------------
/app/src/main/res/main_weather_animated_view_figure/drawable-mdpi/main_weather_animated_view_figure_2.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/main_weather_animated_view_figure/drawable-mdpi/main_weather_animated_view_figure_2.webp
--------------------------------------------------------------------------------
/app/src/main/res/main_weather_animated_view_figure/drawable-mdpi/main_weather_animated_view_figure_3.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/main_weather_animated_view_figure/drawable-mdpi/main_weather_animated_view_figure_3.webp
--------------------------------------------------------------------------------
/app/src/main/res/main_weather_animated_view_figure/drawable-mdpi/main_weather_animated_view_figure_4.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/main_weather_animated_view_figure/drawable-mdpi/main_weather_animated_view_figure_4.webp
--------------------------------------------------------------------------------
/app/src/main/res/main_weather_animated_view_figure/drawable-mdpi/main_weather_animated_view_figure_5.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/main_weather_animated_view_figure/drawable-mdpi/main_weather_animated_view_figure_5.webp
--------------------------------------------------------------------------------
/app/src/main/res/main_weather_animated_view_figure/drawable-mdpi/main_weather_animated_view_figure_6.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/main_weather_animated_view_figure/drawable-mdpi/main_weather_animated_view_figure_6.webp
--------------------------------------------------------------------------------
/app/src/main/res/main_weather_animated_view_figure/drawable-mdpi/main_weather_animated_view_figure_7.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/main_weather_animated_view_figure/drawable-mdpi/main_weather_animated_view_figure_7.webp
--------------------------------------------------------------------------------
/app/src/main/res/main_weather_animated_view_figure/drawable-mdpi/main_weather_animated_view_figure_8.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/main_weather_animated_view_figure/drawable-mdpi/main_weather_animated_view_figure_8.webp
--------------------------------------------------------------------------------
/app/src/main/res/main_weather_animated_view_figure/drawable-xhdpi/main_weather_animated_view_figure_1.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/main_weather_animated_view_figure/drawable-xhdpi/main_weather_animated_view_figure_1.webp
--------------------------------------------------------------------------------
/app/src/main/res/main_weather_animated_view_figure/drawable-xhdpi/main_weather_animated_view_figure_2.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/main_weather_animated_view_figure/drawable-xhdpi/main_weather_animated_view_figure_2.webp
--------------------------------------------------------------------------------
/app/src/main/res/main_weather_animated_view_figure/drawable-xhdpi/main_weather_animated_view_figure_3.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/main_weather_animated_view_figure/drawable-xhdpi/main_weather_animated_view_figure_3.webp
--------------------------------------------------------------------------------
/app/src/main/res/main_weather_animated_view_figure/drawable-xhdpi/main_weather_animated_view_figure_4.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/main_weather_animated_view_figure/drawable-xhdpi/main_weather_animated_view_figure_4.webp
--------------------------------------------------------------------------------
/app/src/main/res/main_weather_animated_view_figure/drawable-xhdpi/main_weather_animated_view_figure_5.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/main_weather_animated_view_figure/drawable-xhdpi/main_weather_animated_view_figure_5.webp
--------------------------------------------------------------------------------
/app/src/main/res/main_weather_animated_view_figure/drawable-xhdpi/main_weather_animated_view_figure_6.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/main_weather_animated_view_figure/drawable-xhdpi/main_weather_animated_view_figure_6.webp
--------------------------------------------------------------------------------
/app/src/main/res/main_weather_animated_view_figure/drawable-xhdpi/main_weather_animated_view_figure_7.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/main_weather_animated_view_figure/drawable-xhdpi/main_weather_animated_view_figure_7.webp
--------------------------------------------------------------------------------
/app/src/main/res/main_weather_animated_view_figure/drawable-xhdpi/main_weather_animated_view_figure_8.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/main_weather_animated_view_figure/drawable-xhdpi/main_weather_animated_view_figure_8.webp
--------------------------------------------------------------------------------
/app/src/main/res/main_weather_animated_view_figure/drawable-xxhdpi/main_weather_animated_view_figure_1.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/main_weather_animated_view_figure/drawable-xxhdpi/main_weather_animated_view_figure_1.webp
--------------------------------------------------------------------------------
/app/src/main/res/main_weather_animated_view_figure/drawable-xxhdpi/main_weather_animated_view_figure_2.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/main_weather_animated_view_figure/drawable-xxhdpi/main_weather_animated_view_figure_2.webp
--------------------------------------------------------------------------------
/app/src/main/res/main_weather_animated_view_figure/drawable-xxhdpi/main_weather_animated_view_figure_3.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/main_weather_animated_view_figure/drawable-xxhdpi/main_weather_animated_view_figure_3.webp
--------------------------------------------------------------------------------
/app/src/main/res/main_weather_animated_view_figure/drawable-xxhdpi/main_weather_animated_view_figure_4.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/main_weather_animated_view_figure/drawable-xxhdpi/main_weather_animated_view_figure_4.webp
--------------------------------------------------------------------------------
/app/src/main/res/main_weather_animated_view_figure/drawable-xxhdpi/main_weather_animated_view_figure_5.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/main_weather_animated_view_figure/drawable-xxhdpi/main_weather_animated_view_figure_5.webp
--------------------------------------------------------------------------------
/app/src/main/res/main_weather_animated_view_figure/drawable-xxhdpi/main_weather_animated_view_figure_6.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/main_weather_animated_view_figure/drawable-xxhdpi/main_weather_animated_view_figure_6.webp
--------------------------------------------------------------------------------
/app/src/main/res/main_weather_animated_view_figure/drawable-xxhdpi/main_weather_animated_view_figure_7.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/main_weather_animated_view_figure/drawable-xxhdpi/main_weather_animated_view_figure_7.webp
--------------------------------------------------------------------------------
/app/src/main/res/main_weather_animated_view_figure/drawable-xxhdpi/main_weather_animated_view_figure_8.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/main_weather_animated_view_figure/drawable-xxhdpi/main_weather_animated_view_figure_8.webp
--------------------------------------------------------------------------------
/app/src/main/res/main_weather_animated_view_figure/drawable-xxxhdpi/main_weather_animated_view_figure_1.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/main_weather_animated_view_figure/drawable-xxxhdpi/main_weather_animated_view_figure_1.webp
--------------------------------------------------------------------------------
/app/src/main/res/main_weather_animated_view_figure/drawable-xxxhdpi/main_weather_animated_view_figure_2.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/main_weather_animated_view_figure/drawable-xxxhdpi/main_weather_animated_view_figure_2.webp
--------------------------------------------------------------------------------
/app/src/main/res/main_weather_animated_view_figure/drawable-xxxhdpi/main_weather_animated_view_figure_3.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/main_weather_animated_view_figure/drawable-xxxhdpi/main_weather_animated_view_figure_3.webp
--------------------------------------------------------------------------------
/app/src/main/res/main_weather_animated_view_figure/drawable-xxxhdpi/main_weather_animated_view_figure_4.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/main_weather_animated_view_figure/drawable-xxxhdpi/main_weather_animated_view_figure_4.webp
--------------------------------------------------------------------------------
/app/src/main/res/main_weather_animated_view_figure/drawable-xxxhdpi/main_weather_animated_view_figure_5.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/main_weather_animated_view_figure/drawable-xxxhdpi/main_weather_animated_view_figure_5.webp
--------------------------------------------------------------------------------
/app/src/main/res/main_weather_animated_view_figure/drawable-xxxhdpi/main_weather_animated_view_figure_6.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/main_weather_animated_view_figure/drawable-xxxhdpi/main_weather_animated_view_figure_6.webp
--------------------------------------------------------------------------------
/app/src/main/res/main_weather_animated_view_figure/drawable-xxxhdpi/main_weather_animated_view_figure_7.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/main_weather_animated_view_figure/drawable-xxxhdpi/main_weather_animated_view_figure_7.webp
--------------------------------------------------------------------------------
/app/src/main/res/main_weather_animated_view_figure/drawable-xxxhdpi/main_weather_animated_view_figure_8.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/main_weather_animated_view_figure/drawable-xxxhdpi/main_weather_animated_view_figure_8.webp
--------------------------------------------------------------------------------
/app/src/main/res/theme/values-night/booleans.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | false
4 |
--------------------------------------------------------------------------------
/app/src/main/res/theme/values/booleans.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | true
4 |
--------------------------------------------------------------------------------
/app/src/main/res/theme/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
12 |
13 | #FFEEF0F5
14 | #FF394253
15 | #FFEEF0F5
16 | #FF181C27
17 |
--------------------------------------------------------------------------------
/app/src/main/res/weather_icon_2_view/drawable-nodpi/weather_2_blizzard.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/weather_icon_2_view/drawable-nodpi/weather_2_blizzard.webp
--------------------------------------------------------------------------------
/app/src/main/res/weather_icon_2_view/drawable-nodpi/weather_2_clear.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/weather_icon_2_view/drawable-nodpi/weather_2_clear.webp
--------------------------------------------------------------------------------
/app/src/main/res/weather_icon_2_view/drawable-nodpi/weather_2_cloud_rain_thunder.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/weather_icon_2_view/drawable-nodpi/weather_2_cloud_rain_thunder.webp
--------------------------------------------------------------------------------
/app/src/main/res/weather_icon_2_view/drawable-nodpi/weather_2_cloud_sleet_snow_thunder.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/weather_icon_2_view/drawable-nodpi/weather_2_cloud_sleet_snow_thunder.webp
--------------------------------------------------------------------------------
/app/src/main/res/weather_icon_2_view/drawable-nodpi/weather_2_cloudy.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/weather_icon_2_view/drawable-nodpi/weather_2_cloudy.webp
--------------------------------------------------------------------------------
/app/src/main/res/weather_icon_2_view/drawable-nodpi/weather_2_fog.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/weather_icon_2_view/drawable-nodpi/weather_2_fog.webp
--------------------------------------------------------------------------------
/app/src/main/res/weather_icon_2_view/drawable-nodpi/weather_2_freezing_drizzle.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/weather_icon_2_view/drawable-nodpi/weather_2_freezing_drizzle.webp
--------------------------------------------------------------------------------
/app/src/main/res/weather_icon_2_view/drawable-nodpi/weather_2_freezing_fog.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/weather_icon_2_view/drawable-nodpi/weather_2_freezing_fog.webp
--------------------------------------------------------------------------------
/app/src/main/res/weather_icon_2_view/drawable-nodpi/weather_2_freezing_rain.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/weather_icon_2_view/drawable-nodpi/weather_2_freezing_rain.webp
--------------------------------------------------------------------------------
/app/src/main/res/weather_icon_2_view/drawable-nodpi/weather_2_heavy_rain.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/weather_icon_2_view/drawable-nodpi/weather_2_heavy_rain.webp
--------------------------------------------------------------------------------
/app/src/main/res/weather_icon_2_view/drawable-nodpi/weather_2_heavy_rain_swrs_day.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/weather_icon_2_view/drawable-nodpi/weather_2_heavy_rain_swrs_day.webp
--------------------------------------------------------------------------------
/app/src/main/res/weather_icon_2_view/drawable-nodpi/weather_2_heavy_rain_swrs_night.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/weather_icon_2_view/drawable-nodpi/weather_2_heavy_rain_swrs_night.webp
--------------------------------------------------------------------------------
/app/src/main/res/weather_icon_2_view/drawable-nodpi/weather_2_heavy_sleet.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/weather_icon_2_view/drawable-nodpi/weather_2_heavy_sleet.webp
--------------------------------------------------------------------------------
/app/src/main/res/weather_icon_2_view/drawable-nodpi/weather_2_heavy_sleet_swrs_day.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/weather_icon_2_view/drawable-nodpi/weather_2_heavy_sleet_swrs_day.webp
--------------------------------------------------------------------------------
/app/src/main/res/weather_icon_2_view/drawable-nodpi/weather_2_heavy_sleet_swrs_night.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/weather_icon_2_view/drawable-nodpi/weather_2_heavy_sleet_swrs_night.webp
--------------------------------------------------------------------------------
/app/src/main/res/weather_icon_2_view/drawable-nodpi/weather_2_heavy_snow.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/weather_icon_2_view/drawable-nodpi/weather_2_heavy_snow.webp
--------------------------------------------------------------------------------
/app/src/main/res/weather_icon_2_view/drawable-nodpi/weather_2_heavy_snow_swrs_day.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/weather_icon_2_view/drawable-nodpi/weather_2_heavy_snow_swrs_day.webp
--------------------------------------------------------------------------------
/app/src/main/res/weather_icon_2_view/drawable-nodpi/weather_2_heavy_snow_swrs_night.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/weather_icon_2_view/drawable-nodpi/weather_2_heavy_snow_swrs_night.webp
--------------------------------------------------------------------------------
/app/src/main/res/weather_icon_2_view/drawable-nodpi/weather_2_iso_rain_swrs_day.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/weather_icon_2_view/drawable-nodpi/weather_2_iso_rain_swrs_day.webp
--------------------------------------------------------------------------------
/app/src/main/res/weather_icon_2_view/drawable-nodpi/weather_2_iso_rain_swrs_night.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/weather_icon_2_view/drawable-nodpi/weather_2_iso_rain_swrs_night.webp
--------------------------------------------------------------------------------
/app/src/main/res/weather_icon_2_view/drawable-nodpi/weather_2_iso_sleet_swrs_day.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/weather_icon_2_view/drawable-nodpi/weather_2_iso_sleet_swrs_day.webp
--------------------------------------------------------------------------------
/app/src/main/res/weather_icon_2_view/drawable-nodpi/weather_2_iso_sleet_swrs_night.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/weather_icon_2_view/drawable-nodpi/weather_2_iso_sleet_swrs_night.webp
--------------------------------------------------------------------------------
/app/src/main/res/weather_icon_2_view/drawable-nodpi/weather_2_iso_snow_swrs_day.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/weather_icon_2_view/drawable-nodpi/weather_2_iso_snow_swrs_day.webp
--------------------------------------------------------------------------------
/app/src/main/res/weather_icon_2_view/drawable-nodpi/weather_2_iso_snow_swrs_night.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/weather_icon_2_view/drawable-nodpi/weather_2_iso_snow_swrs_night.webp
--------------------------------------------------------------------------------
/app/src/main/res/weather_icon_2_view/drawable-nodpi/weather_2_mist.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/weather_icon_2_view/drawable-nodpi/weather_2_mist.webp
--------------------------------------------------------------------------------
/app/src/main/res/weather_icon_2_view/drawable-nodpi/weather_2_mod_rain.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/weather_icon_2_view/drawable-nodpi/weather_2_mod_rain.webp
--------------------------------------------------------------------------------
/app/src/main/res/weather_icon_2_view/drawable-nodpi/weather_2_mod_rain_swrs_day.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/weather_icon_2_view/drawable-nodpi/weather_2_mod_rain_swrs_day.webp
--------------------------------------------------------------------------------
/app/src/main/res/weather_icon_2_view/drawable-nodpi/weather_2_mod_rain_swrs_night.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/weather_icon_2_view/drawable-nodpi/weather_2_mod_rain_swrs_night.webp
--------------------------------------------------------------------------------
/app/src/main/res/weather_icon_2_view/drawable-nodpi/weather_2_mod_sleet.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/weather_icon_2_view/drawable-nodpi/weather_2_mod_sleet.webp
--------------------------------------------------------------------------------
/app/src/main/res/weather_icon_2_view/drawable-nodpi/weather_2_mod_sleet_swrs_day.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/weather_icon_2_view/drawable-nodpi/weather_2_mod_sleet_swrs_day.webp
--------------------------------------------------------------------------------
/app/src/main/res/weather_icon_2_view/drawable-nodpi/weather_2_mod_sleet_swrs_night.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/weather_icon_2_view/drawable-nodpi/weather_2_mod_sleet_swrs_night.webp
--------------------------------------------------------------------------------
/app/src/main/res/weather_icon_2_view/drawable-nodpi/weather_2_mod_snow.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/weather_icon_2_view/drawable-nodpi/weather_2_mod_snow.webp
--------------------------------------------------------------------------------
/app/src/main/res/weather_icon_2_view/drawable-nodpi/weather_2_mod_snow_swrs_day.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/weather_icon_2_view/drawable-nodpi/weather_2_mod_snow_swrs_day.webp
--------------------------------------------------------------------------------
/app/src/main/res/weather_icon_2_view/drawable-nodpi/weather_2_mod_snow_swrs_night.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/weather_icon_2_view/drawable-nodpi/weather_2_mod_snow_swrs_night.webp
--------------------------------------------------------------------------------
/app/src/main/res/weather_icon_2_view/drawable-nodpi/weather_2_occ_light_rain.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/weather_icon_2_view/drawable-nodpi/weather_2_occ_light_rain.webp
--------------------------------------------------------------------------------
/app/src/main/res/weather_icon_2_view/drawable-nodpi/weather_2_occ_light_sleet.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/weather_icon_2_view/drawable-nodpi/weather_2_occ_light_sleet.webp
--------------------------------------------------------------------------------
/app/src/main/res/weather_icon_2_view/drawable-nodpi/weather_2_occ_light_snow.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/weather_icon_2_view/drawable-nodpi/weather_2_occ_light_snow.webp
--------------------------------------------------------------------------------
/app/src/main/res/weather_icon_2_view/drawable-nodpi/weather_2_overcast.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/weather_icon_2_view/drawable-nodpi/weather_2_overcast.webp
--------------------------------------------------------------------------------
/app/src/main/res/weather_icon_2_view/drawable-nodpi/weather_2_part_cloud_rain_thunder_day.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/weather_icon_2_view/drawable-nodpi/weather_2_part_cloud_rain_thunder_day.webp
--------------------------------------------------------------------------------
/app/src/main/res/weather_icon_2_view/drawable-nodpi/weather_2_part_cloud_rain_thunder_night.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/weather_icon_2_view/drawable-nodpi/weather_2_part_cloud_rain_thunder_night.webp
--------------------------------------------------------------------------------
/app/src/main/res/weather_icon_2_view/drawable-nodpi/weather_2_part_cloud_sleet_snow_thunder_day.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/weather_icon_2_view/drawable-nodpi/weather_2_part_cloud_sleet_snow_thunder_day.webp
--------------------------------------------------------------------------------
/app/src/main/res/weather_icon_2_view/drawable-nodpi/weather_2_part_cloud_sleet_snow_thunder_night.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/weather_icon_2_view/drawable-nodpi/weather_2_part_cloud_sleet_snow_thunder_night.webp
--------------------------------------------------------------------------------
/app/src/main/res/weather_icon_2_view/drawable-nodpi/weather_2_partly_cloudy_day.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/weather_icon_2_view/drawable-nodpi/weather_2_partly_cloudy_day.webp
--------------------------------------------------------------------------------
/app/src/main/res/weather_icon_2_view/drawable-nodpi/weather_2_partly_cloudy_night.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/weather_icon_2_view/drawable-nodpi/weather_2_partly_cloudy_night.webp
--------------------------------------------------------------------------------
/app/src/main/res/weather_icon_2_view/drawable-nodpi/weather_2_sunny.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/weather_icon_2_view/drawable-nodpi/weather_2_sunny.webp
--------------------------------------------------------------------------------
/app/src/main/res/weather_icon_2_view/drawable-nodpi/weather_2_wind.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/weather_icon_2_view/drawable-nodpi/weather_2_wind.webp
--------------------------------------------------------------------------------
/app/src/main/res/weather_icon_view/drawable-hdpi/weather_cloud_storm.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/weather_icon_view/drawable-hdpi/weather_cloud_storm.webp
--------------------------------------------------------------------------------
/app/src/main/res/weather_icon_view/drawable-hdpi/weather_mid_snow_fast_winds.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/weather_icon_view/drawable-hdpi/weather_mid_snow_fast_winds.webp
--------------------------------------------------------------------------------
/app/src/main/res/weather_icon_view/drawable-hdpi/weather_moon_cloud_fast_wind.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/weather_icon_view/drawable-hdpi/weather_moon_cloud_fast_wind.webp
--------------------------------------------------------------------------------
/app/src/main/res/weather_icon_view/drawable-hdpi/weather_moon_cloud_mid_rain.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/weather_icon_view/drawable-hdpi/weather_moon_cloud_mid_rain.webp
--------------------------------------------------------------------------------
/app/src/main/res/weather_icon_view/drawable-hdpi/weather_moon_fast_wind.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/weather_icon_view/drawable-hdpi/weather_moon_fast_wind.webp
--------------------------------------------------------------------------------
/app/src/main/res/weather_icon_view/drawable-hdpi/weather_rain.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/weather_icon_view/drawable-hdpi/weather_rain.webp
--------------------------------------------------------------------------------
/app/src/main/res/weather_icon_view/drawable-hdpi/weather_snow.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/weather_icon_view/drawable-hdpi/weather_snow.webp
--------------------------------------------------------------------------------
/app/src/main/res/weather_icon_view/drawable-hdpi/weather_storm.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/weather_icon_view/drawable-hdpi/weather_storm.webp
--------------------------------------------------------------------------------
/app/src/main/res/weather_icon_view/drawable-hdpi/weather_sun.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/weather_icon_view/drawable-hdpi/weather_sun.webp
--------------------------------------------------------------------------------
/app/src/main/res/weather_icon_view/drawable-hdpi/weather_sun_cloud_angled_rain.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/weather_icon_view/drawable-hdpi/weather_sun_cloud_angled_rain.webp
--------------------------------------------------------------------------------
/app/src/main/res/weather_icon_view/drawable-hdpi/weather_sun_cloud_little_rain.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/weather_icon_view/drawable-hdpi/weather_sun_cloud_little_rain.webp
--------------------------------------------------------------------------------
/app/src/main/res/weather_icon_view/drawable-hdpi/weather_tornado.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/weather_icon_view/drawable-hdpi/weather_tornado.webp
--------------------------------------------------------------------------------
/app/src/main/res/weather_icon_view/drawable-mdpi/weather_cloud_storm.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/weather_icon_view/drawable-mdpi/weather_cloud_storm.webp
--------------------------------------------------------------------------------
/app/src/main/res/weather_icon_view/drawable-mdpi/weather_mid_snow_fast_winds.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/weather_icon_view/drawable-mdpi/weather_mid_snow_fast_winds.webp
--------------------------------------------------------------------------------
/app/src/main/res/weather_icon_view/drawable-mdpi/weather_moon_cloud_fast_wind.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/weather_icon_view/drawable-mdpi/weather_moon_cloud_fast_wind.webp
--------------------------------------------------------------------------------
/app/src/main/res/weather_icon_view/drawable-mdpi/weather_moon_cloud_mid_rain.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/weather_icon_view/drawable-mdpi/weather_moon_cloud_mid_rain.webp
--------------------------------------------------------------------------------
/app/src/main/res/weather_icon_view/drawable-mdpi/weather_moon_fast_wind.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/weather_icon_view/drawable-mdpi/weather_moon_fast_wind.webp
--------------------------------------------------------------------------------
/app/src/main/res/weather_icon_view/drawable-mdpi/weather_rain.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/weather_icon_view/drawable-mdpi/weather_rain.webp
--------------------------------------------------------------------------------
/app/src/main/res/weather_icon_view/drawable-mdpi/weather_snow.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/weather_icon_view/drawable-mdpi/weather_snow.webp
--------------------------------------------------------------------------------
/app/src/main/res/weather_icon_view/drawable-mdpi/weather_storm.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/weather_icon_view/drawable-mdpi/weather_storm.webp
--------------------------------------------------------------------------------
/app/src/main/res/weather_icon_view/drawable-mdpi/weather_sun.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/weather_icon_view/drawable-mdpi/weather_sun.webp
--------------------------------------------------------------------------------
/app/src/main/res/weather_icon_view/drawable-mdpi/weather_sun_cloud_angled_rain.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/weather_icon_view/drawable-mdpi/weather_sun_cloud_angled_rain.webp
--------------------------------------------------------------------------------
/app/src/main/res/weather_icon_view/drawable-mdpi/weather_sun_cloud_little_rain.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/weather_icon_view/drawable-mdpi/weather_sun_cloud_little_rain.webp
--------------------------------------------------------------------------------
/app/src/main/res/weather_icon_view/drawable-mdpi/weather_tornado.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/weather_icon_view/drawable-mdpi/weather_tornado.webp
--------------------------------------------------------------------------------
/app/src/main/res/weather_icon_view/drawable-xhdpi/weather_cloud_storm.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/weather_icon_view/drawable-xhdpi/weather_cloud_storm.webp
--------------------------------------------------------------------------------
/app/src/main/res/weather_icon_view/drawable-xhdpi/weather_mid_snow_fast_winds.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/weather_icon_view/drawable-xhdpi/weather_mid_snow_fast_winds.webp
--------------------------------------------------------------------------------
/app/src/main/res/weather_icon_view/drawable-xhdpi/weather_moon_cloud_fast_wind.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/weather_icon_view/drawable-xhdpi/weather_moon_cloud_fast_wind.webp
--------------------------------------------------------------------------------
/app/src/main/res/weather_icon_view/drawable-xhdpi/weather_moon_cloud_mid_rain.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/weather_icon_view/drawable-xhdpi/weather_moon_cloud_mid_rain.webp
--------------------------------------------------------------------------------
/app/src/main/res/weather_icon_view/drawable-xhdpi/weather_moon_fast_wind.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/weather_icon_view/drawable-xhdpi/weather_moon_fast_wind.webp
--------------------------------------------------------------------------------
/app/src/main/res/weather_icon_view/drawable-xhdpi/weather_rain.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/weather_icon_view/drawable-xhdpi/weather_rain.webp
--------------------------------------------------------------------------------
/app/src/main/res/weather_icon_view/drawable-xhdpi/weather_snow.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/weather_icon_view/drawable-xhdpi/weather_snow.webp
--------------------------------------------------------------------------------
/app/src/main/res/weather_icon_view/drawable-xhdpi/weather_storm.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/weather_icon_view/drawable-xhdpi/weather_storm.webp
--------------------------------------------------------------------------------
/app/src/main/res/weather_icon_view/drawable-xhdpi/weather_sun.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/weather_icon_view/drawable-xhdpi/weather_sun.webp
--------------------------------------------------------------------------------
/app/src/main/res/weather_icon_view/drawable-xhdpi/weather_sun_cloud_angled_rain.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/weather_icon_view/drawable-xhdpi/weather_sun_cloud_angled_rain.webp
--------------------------------------------------------------------------------
/app/src/main/res/weather_icon_view/drawable-xhdpi/weather_sun_cloud_little_rain.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/weather_icon_view/drawable-xhdpi/weather_sun_cloud_little_rain.webp
--------------------------------------------------------------------------------
/app/src/main/res/weather_icon_view/drawable-xhdpi/weather_tornado.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/weather_icon_view/drawable-xhdpi/weather_tornado.webp
--------------------------------------------------------------------------------
/app/src/main/res/weather_icon_view/drawable-xxhdpi/weather_cloud_storm.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/weather_icon_view/drawable-xxhdpi/weather_cloud_storm.webp
--------------------------------------------------------------------------------
/app/src/main/res/weather_icon_view/drawable-xxhdpi/weather_mid_snow_fast_winds.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/weather_icon_view/drawable-xxhdpi/weather_mid_snow_fast_winds.webp
--------------------------------------------------------------------------------
/app/src/main/res/weather_icon_view/drawable-xxhdpi/weather_moon_cloud_fast_wind.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/weather_icon_view/drawable-xxhdpi/weather_moon_cloud_fast_wind.webp
--------------------------------------------------------------------------------
/app/src/main/res/weather_icon_view/drawable-xxhdpi/weather_moon_cloud_mid_rain.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/weather_icon_view/drawable-xxhdpi/weather_moon_cloud_mid_rain.webp
--------------------------------------------------------------------------------
/app/src/main/res/weather_icon_view/drawable-xxhdpi/weather_moon_fast_wind.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/weather_icon_view/drawable-xxhdpi/weather_moon_fast_wind.webp
--------------------------------------------------------------------------------
/app/src/main/res/weather_icon_view/drawable-xxhdpi/weather_rain.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/weather_icon_view/drawable-xxhdpi/weather_rain.webp
--------------------------------------------------------------------------------
/app/src/main/res/weather_icon_view/drawable-xxhdpi/weather_snow.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/weather_icon_view/drawable-xxhdpi/weather_snow.webp
--------------------------------------------------------------------------------
/app/src/main/res/weather_icon_view/drawable-xxhdpi/weather_storm.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/weather_icon_view/drawable-xxhdpi/weather_storm.webp
--------------------------------------------------------------------------------
/app/src/main/res/weather_icon_view/drawable-xxhdpi/weather_sun.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/weather_icon_view/drawable-xxhdpi/weather_sun.webp
--------------------------------------------------------------------------------
/app/src/main/res/weather_icon_view/drawable-xxhdpi/weather_sun_cloud_angled_rain.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/weather_icon_view/drawable-xxhdpi/weather_sun_cloud_angled_rain.webp
--------------------------------------------------------------------------------
/app/src/main/res/weather_icon_view/drawable-xxhdpi/weather_sun_cloud_little_rain.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/weather_icon_view/drawable-xxhdpi/weather_sun_cloud_little_rain.webp
--------------------------------------------------------------------------------
/app/src/main/res/weather_icon_view/drawable-xxhdpi/weather_tornado.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/weather_icon_view/drawable-xxhdpi/weather_tornado.webp
--------------------------------------------------------------------------------
/app/src/main/res/weather_icon_view/drawable-xxxhdpi/weather_cloud_storm.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/weather_icon_view/drawable-xxxhdpi/weather_cloud_storm.webp
--------------------------------------------------------------------------------
/app/src/main/res/weather_icon_view/drawable-xxxhdpi/weather_mid_snow_fast_winds.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/weather_icon_view/drawable-xxxhdpi/weather_mid_snow_fast_winds.webp
--------------------------------------------------------------------------------
/app/src/main/res/weather_icon_view/drawable-xxxhdpi/weather_moon_cloud_fast_wind.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/weather_icon_view/drawable-xxxhdpi/weather_moon_cloud_fast_wind.webp
--------------------------------------------------------------------------------
/app/src/main/res/weather_icon_view/drawable-xxxhdpi/weather_moon_cloud_mid_rain.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/weather_icon_view/drawable-xxxhdpi/weather_moon_cloud_mid_rain.webp
--------------------------------------------------------------------------------
/app/src/main/res/weather_icon_view/drawable-xxxhdpi/weather_moon_fast_wind.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/weather_icon_view/drawable-xxxhdpi/weather_moon_fast_wind.webp
--------------------------------------------------------------------------------
/app/src/main/res/weather_icon_view/drawable-xxxhdpi/weather_rain.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/weather_icon_view/drawable-xxxhdpi/weather_rain.webp
--------------------------------------------------------------------------------
/app/src/main/res/weather_icon_view/drawable-xxxhdpi/weather_snow.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/weather_icon_view/drawable-xxxhdpi/weather_snow.webp
--------------------------------------------------------------------------------
/app/src/main/res/weather_icon_view/drawable-xxxhdpi/weather_storm.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/weather_icon_view/drawable-xxxhdpi/weather_storm.webp
--------------------------------------------------------------------------------
/app/src/main/res/weather_icon_view/drawable-xxxhdpi/weather_sun.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/weather_icon_view/drawable-xxxhdpi/weather_sun.webp
--------------------------------------------------------------------------------
/app/src/main/res/weather_icon_view/drawable-xxxhdpi/weather_sun_cloud_angled_rain.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/weather_icon_view/drawable-xxxhdpi/weather_sun_cloud_angled_rain.webp
--------------------------------------------------------------------------------
/app/src/main/res/weather_icon_view/drawable-xxxhdpi/weather_sun_cloud_little_rain.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/weather_icon_view/drawable-xxxhdpi/weather_sun_cloud_little_rain.webp
--------------------------------------------------------------------------------
/app/src/main/res/weather_icon_view/drawable-xxxhdpi/weather_tornado.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/app/src/main/res/weather_icon_view/drawable-xxxhdpi/weather_tornado.webp
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | buildscript {
18 | ext.kotlin_version = '1.4.31'
19 | ext.compose_version = '1.0.0-beta02'
20 | ext.coroutines_version = '1.4.2'
21 |
22 | repositories {
23 | google()
24 | jcenter()
25 | }
26 |
27 | dependencies {
28 | classpath 'com.android.tools.build:gradle:7.0.0-rc01'
29 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
30 | }
31 | }
32 |
33 | plugins {
34 | id 'com.diffplug.spotless' version '5.7.0'
35 | }
36 |
37 | allprojects {
38 | repositories {
39 | maven { url "https://jitpack.io" }
40 | }
41 | }
42 |
43 | subprojects {
44 | repositories {
45 | google()
46 | jcenter()
47 | }
48 |
49 | apply plugin: 'com.diffplug.spotless'
50 | spotless {
51 | kotlin {
52 | target '**/*.kt'
53 | targetExclude("$buildDir/**/*.kt")
54 | targetExclude('bin/**/*.kt')
55 |
56 | ktlint("0.40.0")
57 | licenseHeaderFile rootProject.file('spotless/copyright.kt')
58 | }
59 | }
60 | }
--------------------------------------------------------------------------------
/debug.keystore:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/debug.keystore
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 | # IDE (e.g. Android Studio) users:
3 | # Gradle settings configured through the IDE *will override*
4 | # any settings specified in this file.
5 | # For more details on how to configure your build environment visit
6 | # http://www.gradle.org/docs/current/userguide/build_environment.html
7 | # Specifies the JVM arguments used for the daemon process.
8 | # The setting is particularly useful for tweaking memory settings.
9 | org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
10 | # When configured, Gradle will run in incubating parallel mode.
11 | # This option should only be used with decoupled projects. More details, visit
12 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
13 | # org.gradle.parallel=true
14 | # AndroidX package structure to make it clearer which packages are bundled with the
15 | # Android operating system, and which are packaged with your app"s APK
16 | # https://developer.android.com/topic/libraries/support-library/androidx-rn
17 | android.useAndroidX=true
18 | # Automatically convert third-party libraries to use AndroidX
19 | android.enableJetifier=true
20 | # Kotlin code style for this project: "official" or "obsolete":
21 | kotlin.code.style=official
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Wed Feb 24 18:05:51 CET 2021
2 | distributionBase=GRADLE_USER_HOME
3 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.1.1-bin.zip
4 | distributionPath=wrapper/dists
5 | zipStorePath=wrapper/dists
6 | zipStoreBase=GRADLE_USER_HOME
7 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Attempt to set APP_HOME
10 | # Resolve links: $0 may be a link
11 | PRG="$0"
12 | # Need this for relative symlinks.
13 | while [ -h "$PRG" ] ; do
14 | ls=`ls -ld "$PRG"`
15 | link=`expr "$ls" : '.*-> \(.*\)$'`
16 | if expr "$link" : '/.*' > /dev/null; then
17 | PRG="$link"
18 | else
19 | PRG=`dirname "$PRG"`"/$link"
20 | fi
21 | done
22 | SAVED="`pwd`"
23 | cd "`dirname \"$PRG\"`/" >/dev/null
24 | APP_HOME="`pwd -P`"
25 | cd "$SAVED" >/dev/null
26 |
27 | APP_NAME="Gradle"
28 | APP_BASE_NAME=`basename "$0"`
29 |
30 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
31 | DEFAULT_JVM_OPTS=""
32 |
33 | # Use the maximum available, or set MAX_FD != -1 to use that value.
34 | MAX_FD="maximum"
35 |
36 | warn () {
37 | echo "$*"
38 | }
39 |
40 | die () {
41 | echo
42 | echo "$*"
43 | echo
44 | exit 1
45 | }
46 |
47 | # OS specific support (must be 'true' or 'false').
48 | cygwin=false
49 | msys=false
50 | darwin=false
51 | nonstop=false
52 | case "`uname`" in
53 | CYGWIN* )
54 | cygwin=true
55 | ;;
56 | Darwin* )
57 | darwin=true
58 | ;;
59 | MINGW* )
60 | msys=true
61 | ;;
62 | NONSTOP* )
63 | nonstop=true
64 | ;;
65 | esac
66 |
67 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
68 |
69 | # Determine the Java command to use to start the JVM.
70 | if [ -n "$JAVA_HOME" ] ; then
71 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
72 | # IBM's JDK on AIX uses strange locations for the executables
73 | JAVACMD="$JAVA_HOME/jre/sh/java"
74 | else
75 | JAVACMD="$JAVA_HOME/bin/java"
76 | fi
77 | if [ ! -x "$JAVACMD" ] ; then
78 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
79 |
80 | Please set the JAVA_HOME variable in your environment to match the
81 | location of your Java installation."
82 | fi
83 | else
84 | JAVACMD="java"
85 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
86 |
87 | Please set the JAVA_HOME variable in your environment to match the
88 | location of your Java installation."
89 | fi
90 |
91 | # Increase the maximum file descriptors if we can.
92 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
93 | MAX_FD_LIMIT=`ulimit -H -n`
94 | if [ $? -eq 0 ] ; then
95 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
96 | MAX_FD="$MAX_FD_LIMIT"
97 | fi
98 | ulimit -n $MAX_FD
99 | if [ $? -ne 0 ] ; then
100 | warn "Could not set maximum file descriptor limit: $MAX_FD"
101 | fi
102 | else
103 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
104 | fi
105 | fi
106 |
107 | # For Darwin, add options to specify how the application appears in the dock
108 | if $darwin; then
109 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
110 | fi
111 |
112 | # For Cygwin, switch paths to Windows format before running java
113 | if $cygwin ; then
114 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
115 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
116 | JAVACMD=`cygpath --unix "$JAVACMD"`
117 |
118 | # We build the pattern for arguments to be converted via cygpath
119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
120 | SEP=""
121 | for dir in $ROOTDIRSRAW ; do
122 | ROOTDIRS="$ROOTDIRS$SEP$dir"
123 | SEP="|"
124 | done
125 | OURCYGPATTERN="(^($ROOTDIRS))"
126 | # Add a user-defined pattern to the cygpath arguments
127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
129 | fi
130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
131 | i=0
132 | for arg in "$@" ; do
133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
135 |
136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
138 | else
139 | eval `echo args$i`="\"$arg\""
140 | fi
141 | i=$((i+1))
142 | done
143 | case $i in
144 | (0) set -- ;;
145 | (1) set -- "$args0" ;;
146 | (2) set -- "$args0" "$args1" ;;
147 | (3) set -- "$args0" "$args1" "$args2" ;;
148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
154 | esac
155 | fi
156 |
157 | # Escape application args
158 | save () {
159 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
160 | echo " "
161 | }
162 | APP_ARGS=$(save "$@")
163 |
164 | # Collect all arguments for the java command, following the shell quoting and substitution rules
165 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
166 |
167 | # by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
168 | if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
169 | cd "$(dirname "$0")"
170 | fi
171 |
172 | exec "$JAVACMD" "$@"
173 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | set DIRNAME=%~dp0
12 | if "%DIRNAME%" == "" set DIRNAME=.
13 | set APP_BASE_NAME=%~n0
14 | set APP_HOME=%DIRNAME%
15 |
16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
17 | set DEFAULT_JVM_OPTS=
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windows variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 |
53 | :win9xME_args
54 | @rem Slurp the command line arguments.
55 | set CMD_LINE_ARGS=
56 | set _SKIP=2
57 |
58 | :win9xME_args_slurp
59 | if "x%~1" == "x" goto execute
60 |
61 | set CMD_LINE_ARGS=%*
62 |
63 | :execute
64 | @rem Setup the command line
65 |
66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
67 |
68 | @rem Execute Gradle
69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
70 |
71 | :end
72 | @rem End local scope for the variables with windows NT shell
73 | if "%ERRORLEVEL%"=="0" goto mainEnd
74 |
75 | :fail
76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
77 | rem the _cmd.exe /c_ return code!
78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
79 | exit /b 1
80 |
81 | :mainEnd
82 | if "%OS%"=="Windows_NT" endlocal
83 |
84 | :omega
85 |
--------------------------------------------------------------------------------
/results/banner.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/results/banner.jpg
--------------------------------------------------------------------------------
/results/screenshot_1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/results/screenshot_1.png
--------------------------------------------------------------------------------
/results/screenshot_2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/results/screenshot_2.png
--------------------------------------------------------------------------------
/results/screenshot_3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/results/screenshot_3.png
--------------------------------------------------------------------------------
/results/screenshot_4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/results/screenshot_4.png
--------------------------------------------------------------------------------
/results/screenshot_5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/results/screenshot_5.png
--------------------------------------------------------------------------------
/results/video.mp4:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/results/video.mp4
--------------------------------------------------------------------------------
/results/video_as_gif.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mercandj/android-dev-challenge-compose-4/d0b653174d7df1f5c72c7b146a35b37fe16e43f1/results/video_as_gif.gif
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | rootProject.name = "android-dev-challenge-weather"
2 | include ':app'
3 |
--------------------------------------------------------------------------------
/spotless/copyright.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright $YEAR The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
--------------------------------------------------------------------------------