Skip to content

Commit d96c7a6

Browse files
committed
Merge branch 'dev' into 223-replace-rxjava-with-coroutines-radar
2 parents d147bca + 9ae71ab commit d96c7a6

36 files changed

Lines changed: 244 additions & 823 deletions

.github/workflows/build.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,11 @@ jobs:
2626
steps:
2727
- name: Checkout the code
2828
uses: actions/checkout@v2
29+
- name: Setup environment
30+
env:
31+
GOOGLE_SERVICES_JSON: ${{ secrets.GOOGLE_SERVICES_JSON }}
32+
run: |
33+
echo "${GOOGLE_SERVICES_JSON}" | base64 --decode > app/google-services.json
2934
- name: Set up JDK 1.8
3035
uses: actions/setup-java@v1
3136
with:

.github/workflows/release.yml

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,11 @@ jobs:
1515
- run: |
1616
echo "${{ secrets.KEYSTORE_FILE_BASE64 }}" > keystore.asc
1717
gpg -d --passphrase "${{ secrets.KEYSTORE_FILE_DECRYPT_PASSWORD }}" --batch keystore.asc > .keystore
18+
- name: Setup environment
19+
env:
20+
GOOGLE_SERVICES_JSON: ${{ secrets.GOOGLE_SERVICES_JSON }}
21+
run: |
22+
echo "${GOOGLE_SERVICES_JSON}" | base64 --decode > app/google-services.json
1823
- name: Set up JDK 1.8
1924
uses: actions/setup-java@v1
2025
with:
@@ -26,10 +31,6 @@ jobs:
2631
KEY_STORE_PASSWORD: ${{ secrets.KEY_STORE_PASSWORD }}
2732
run: |
2833
./gradlew assembleGithubRelease
29-
sudo apt-get -y install tree
30-
tree app/build/outputs
31-
ls -lah app/build/
32-
ls -lah
3334
- name: Get the version
3435
id: get_version
3536
run: echo ::set-output name=VERSION::${GITHUB_REF/refs\/tags\//}

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
[![github-ci](https://github.com/vadret/android/workflows/V%C3%A4dret%20Android%20App/badge.svg)](https://github.com/vadret/android/actions)
2+
[![github-releases](https://img.shields.io/github/v/release/sphrak/vadret)](https://github.com/vadret/android/releases/)
23
[![ktlint](https://img.shields.io/badge/code%20style-%E2%9D%A4-FF4081.svg)](https://ktlint.github.io/)
34
[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://github.com/vadret/android/blob/master/LICENSE)
45
[![CodeFactor](https://www.codefactor.io/repository/github/vadret/android/badge)](https://www.codefactor.io/repository/github/vadret/android)
56

67
![Vädret](https://raw.githubusercontent.com/vadret/android/master/assets/logo.png)
78

89
# Vädret
9-
A simple weather app that uses the Swedish weather service [SMHI](https://opendata-download-metfcst.smhi.se/) to fetch weather data, and [Krisinformation](https://www.krisinformation.se/en) for emergency information from Swedish authorities. Built with MVI/MVVM in mind on top of RxJava2, written entirely in Kotlin. Icons used in this project can be found [here](https://github.com/vadret/assets). The data is licensed under [Creative commons Erkännande 4.0 SE](https://www.smhi.se/klimatdata/oppna-data/information-om-oppna-data/villkor-for-anvandning-1.30622).
10+
A simple weather app that uses the Swedish weather service [SMHI](https://opendata-download-metfcst.smhi.se/) to fetch weather data, and [Krisinformation](https://www.krisinformation.se/en) for emergency information from Swedish authorities. MVI written entirely in Kotlin. Icons used in this project can be found [here](https://github.com/vadret/assets). The data is licensed under [Creative commons Erkännande 4.0 SE](https://www.smhi.se/klimatdata/oppna-data/information-om-oppna-data/villkor-for-anvandning-1.30622).
1011

1112
![Weather](https://raw.githubusercontent.com/vadret/android/master/assets/weather.png)
1213
![Warning](https://raw.githubusercontent.com/vadret/android/master/assets/warning.png)

app/build.gradle

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@ apply plugin: 'com.android.application'
22
apply plugin: 'kotlin-android'
33
apply plugin: 'kotlin-android-extensions'
44
apply plugin: 'kotlin-kapt'
5+
apply plugin: 'kotlinx-serialization'
6+
apply plugin: 'com.google.gms.google-services'
7+
apply plugin: 'com.google.firebase.crashlytics'
58

69
def static loadFromEnvironment(String key) {
710
return System.getenv(key)
@@ -39,8 +42,8 @@ android {
3942
applicationId "fi.kroon.vadret"
4043
minSdkVersion 21
4144
targetSdkVersion 30
42-
versionCode 26
43-
versionName "1.2.10"
45+
versionCode 27
46+
versionName "2.0.0"
4447
vectorDrawables.useSupportLibrary = true
4548
flavorDimensions "default"
4649
testInstrumentationRunner "androidx.top.runner.AndroidJUnitRunner"
@@ -96,6 +99,9 @@ android {
9699
productFlavors {
97100
google {
98101
signingConfig signingConfigs.release
102+
firebaseCrashlytics {
103+
mappingFileUploadEnabled true
104+
}
99105
}
100106
fdroid {
101107
signingConfig fdroid.signingConfig
@@ -131,18 +137,18 @@ dependencies {
131137
def CONSTRAINT_LAYOUT_VERSION = "2.0.2"
132138
def CORBIND_VERSION = "1.4.0"
133139
def CORE_KTX_VERSION = "1.3.2"
134-
def COROUTINES_VERSION = "1.4.0-M1"
135-
def CRASHLYTICS_VERSION = "2.10.1"
136-
def DAGGER_VERSION = "2.29.1"
140+
def COROUTINES_VERSION = "1.4.2"
141+
def DAGGER_VERSION = "2.30.1"
137142
def EITHER_VERSION = "1.2.0"
138143
def FRAGMENT_VERSION = "1.3.0-beta01"
139144
def JUNIT_VERSION = "4.13"
140145
def KOTLIN_STDLIB_VERSION = "1.4.10"
141-
def KTLINT_VERSION = "0.39.0"
146+
def KOTLINX_SERIALIZATION = "1.0.1"
147+
def KTLINT_VERSION = "0.40.0"
142148
def MATERIAL_VERSION = "1.2.1"
143149
def MOCKITO_CORE_VERSION = "3.1.0"
144150
def MOSHI_VERSION = "1.9.2"
145-
def NAVIGATION_VERSION = "2.3.1"
151+
def NAVIGATION_VERSION = "2.3.2"
146152
def OKHTTP_VERSION = "4.2.2"
147153
def OKIO_VERSION = "2.6.0"
148154
def OSMDROID_VERSION = "6.1.2"
@@ -158,6 +164,7 @@ dependencies {
158164
def THREETEN_ABP_VERSION = "1.2.1"
159165
def THREETEN_BP_VERSION = "1.4.0"
160166
def TIMBER_VERSION = "4.7.1"
167+
def LIFECYCLE_VERSION = "2.2.0"
161168

162169
implementation fileTree(dir: 'libs', include: ['*.jar'])
163170

@@ -171,6 +178,11 @@ dependencies {
171178
implementation "androidx.preference:preference-ktx:${PREFERENCE_VERSION}"
172179
implementation "com.google.android.material:material:${MATERIAL_VERSION}"
173180

181+
// Lifecycle
182+
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$LIFECYCLE_VERSION"
183+
implementation "androidx.lifecycle:lifecycle-runtime-ktx:$LIFECYCLE_VERSION"
184+
kapt "androidx.lifecycle:lifecycle-compiler:$LIFECYCLE_VERSION"
185+
174186
// Coroutines
175187
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:${COROUTINES_VERSION}"
176188
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:${COROUTINES_VERSION}"
@@ -196,6 +208,7 @@ dependencies {
196208
implementation "com.squareup.retrofit2:adapter-rxjava2:${RETROFIT_VERSION}"
197209
implementation "com.squareup.retrofit2:converter-moshi:${RETROFIT_VERSION}"
198210
implementation "com.squareup.retrofit2:retrofit:${RETROFIT_VERSION}"
211+
implementation "com.jakewharton.retrofit:retrofit2-kotlinx-serialization-converter:0.8.0"
199212

200213
// Database
201214
implementation "androidx.room:room-runtime:${ROOM_VERSION}"
@@ -208,6 +221,7 @@ dependencies {
208221
implementation "com.squareup.moshi:moshi:${MOSHI_VERSION}"
209222
implementation "com.squareup.retrofit2:converter-moshi:${RETROFIT_VERSION}"
210223
kapt "com.squareup.moshi:moshi-kotlin-codegen:${MOSHI_VERSION}"
224+
implementation "org.jetbrains.kotlinx:kotlinx-serialization-json:${KOTLINX_SERIALIZATION}"
211225

212226
// Dependency Injection
213227
implementation "com.google.dagger:dagger:${DAGGER_VERSION}"
@@ -229,9 +243,8 @@ dependencies {
229243

230244
// Debugging, Testing, Linting, Analytics
231245
debugImplementation "com.squareup.leakcanary:leakcanary-android:2.5"
232-
googleImplementation("com.crashlytics.sdk.android:crashlytics:${CRASHLYTICS_VERSION}@aar") {
233-
transitive = true
234-
}
246+
googleImplementation platform('com.google.firebase:firebase-bom:26.0.0')
247+
googleImplementation 'com.google.firebase:firebase-crashlytics-ktx'
235248
implementation "com.jakewharton.timber:timber:${TIMBER_VERSION}"
236249
ktlint "com.pinterest:ktlint:${KTLINT_VERSION}"
237250
testImplementation "junit:junit:${JUNIT_VERSION}"

app/src/googleRelease/java/fi/kroon/vadret/VadretApplication.kt

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
package fi.kroon.vadret
22

33
import android.content.Context
4-
import com.crashlytics.android.Crashlytics
5-
import com.crashlytics.android.core.CrashlyticsCore
6-
import io.fabric.sdk.android.Fabric
4+
import com.google.firebase.crashlytics.FirebaseCrashlytics
75

86
class VadretApplication : BaseApplication() {
97

@@ -19,9 +17,6 @@ class VadretApplication : BaseApplication() {
1917
}
2018

2119
private fun initCrashlytics() {
22-
val crashlyticsKit = Crashlytics.Builder()
23-
.core(CrashlyticsCore.Builder().disabled(BuildConfig.DEBUG).build())
24-
.build()
25-
Fabric.with(this, crashlyticsKit)
20+
FirebaseCrashlytics.getInstance().setCrashlyticsCollectionEnabled(!BuildConfig.DEBUG)
2621
}
2722
}

app/src/main/AndroidManifest.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
<category android:name="android.intent.category.LAUNCHER" />
2929
</intent-filter>
3030
</activity>
31+
<meta-data android:name="firebase_crashlytics_collection_enabled" android:value="false" />
3132

3233
</application>
3334
</manifest>

app/src/main/java/fi/kroon/vadret/data/weatherforecast/WeatherForecastRepository.kt

Lines changed: 18 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -11,19 +11,13 @@ import fi.kroon.vadret.data.weatherforecast.model.Weather
1111
import fi.kroon.vadret.data.weatherforecast.model.WeatherOut
1212
import fi.kroon.vadret.data.weatherforecast.net.WeatherForecastNetDataSource
1313
import fi.kroon.vadret.util.HTTP_200_OK
14-
import fi.kroon.vadret.util.HTTP_204_NO_CONTENT
15-
import fi.kroon.vadret.util.HTTP_400_BAD_REQUEST
16-
import fi.kroon.vadret.util.HTTP_403_FORBIDDEN
17-
import fi.kroon.vadret.util.HTTP_404_NOT_FOUND
18-
import fi.kroon.vadret.util.HTTP_500_INTERNAL_SERVER_ERROR
19-
import fi.kroon.vadret.util.HTTP_503_SERVICE_UNAVAILABLE
20-
import fi.kroon.vadret.util.HTTP_504_GATEWAY_TIMEOUT
2114
import fi.kroon.vadret.util.NetworkHandler
2215
import fi.kroon.vadret.util.extension.asLeft
16+
import fi.kroon.vadret.util.extension.asRight
2317
import fi.kroon.vadret.util.extension.toCoordinate
2418
import io.github.sphrak.either.Either
25-
import io.reactivex.Single
2619
import retrofit2.Response
20+
import timber.log.Timber
2721
import javax.inject.Inject
2822

2923
class WeatherForecastRepository @Inject constructor(
@@ -33,32 +27,30 @@ class WeatherForecastRepository @Inject constructor(
3327
private val exceptionHandler: ExceptionHandler
3428
) : IErrorHandler by errorHandler, IExceptionHandler<Failure> by exceptionHandler {
3529

36-
operator fun invoke(request: WeatherOut): Single<Either<Failure, Weather>> =
37-
when (networkHandler.isConnected) {
38-
true ->
30+
suspend operator fun invoke(request: WeatherOut): Either<Failure, Weather> =
31+
try {
32+
if (networkHandler.isConnected) {
3933
weatherForecastNetDataSource
4034
.get()
4135
.getWeatherForecast(
4236
request.category,
4337
request.version,
4438
request.longitude.toCoordinate(),
4539
request.latitude.toCoordinate()
46-
).map { response: Response<Weather> ->
47-
when (response.code()) {
48-
HTTP_200_OK -> Either.Right(response.body()!!)
49-
HTTP_204_NO_CONTENT -> WeatherForecastFailure.NoWeatherAvailable.asLeft()
50-
HTTP_403_FORBIDDEN -> Failure.HttpForbidden403.asLeft()
51-
HTTP_404_NOT_FOUND -> WeatherForecastFailure.NoWeatherAvailableForThisLocation.asLeft()
52-
HTTP_400_BAD_REQUEST -> Failure.HttpBadRequest400.asLeft()
53-
HTTP_500_INTERNAL_SERVER_ERROR -> Failure.HttpInternalServerError500.asLeft()
54-
HTTP_503_SERVICE_UNAVAILABLE -> Failure.HttpServiceUnavailable503.asLeft()
55-
HTTP_504_GATEWAY_TIMEOUT -> Failure.HttpGatewayTimeout504.asLeft()
56-
else -> WeatherForecastFailure.NoWeatherAvailable.asLeft()
40+
).let { response: Response<Weather> ->
41+
if (response.code() == HTTP_200_OK) {
42+
response.body()?.asRight() ?: WeatherForecastFailure.NoWeatherAvailable.asLeft()
43+
} else {
44+
WeatherForecastFailure.NoWeatherAvailable.asLeft()
5745
}
5846
}
59-
false -> getNetworkOfflineError()
60-
}.onErrorReturn {
61-
exceptionHandler(it)
62-
.asLeft()
47+
} else {
48+
Failure
49+
.NetworkOfflineError("error: network offline or not available")
50+
.asLeft()
51+
}
52+
} catch (exception: Exception) {
53+
Timber.e(exception)
54+
Failure.NetworkError().asLeft()
6355
}
6456
}

app/src/main/java/fi/kroon/vadret/data/weatherforecast/cache/WeatherForecastCacheDataSource.kt

Lines changed: 0 additions & 75 deletions
This file was deleted.

0 commit comments

Comments
 (0)