Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(ui): wrong color in dark mode and format .xml files #95

Merged
merged 14 commits into from
Jan 30, 2022
Merged
42 changes: 21 additions & 21 deletions .github/workflows/qodana.yml
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
name: Qodana
on:
push:
branches: [ master ]
paths-ignore: [ '**.md', '**.MD' ]
pull_request:
branches: [ master ]
paths-ignore: [ '**.md', '**.MD' ]
workflow_dispatch:
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: JetBrains/[email protected]
with:
linter: jetbrains/qodana-jvm-android:latest
fail-threshold: 10
name: Qodana

on:
push:
branches: [ master ]
paths-ignore: [ '**.md', '**.MD' ]
pull_request:
branches: [ master ]
paths-ignore: [ '**.md', '**.MD' ]
workflow_dispatch:

jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2

- uses: JetBrains/[email protected]
with:
linter: jetbrains/qodana-jvm-android:latest
fail-threshold: 10
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@
/.idea/assetWizardSettings.xml
.DS_Store
/build
buildSrc/build
/captures
.externalNativeBuild
.cxx
local.properties
**/build/
6 changes: 3 additions & 3 deletions .idea/misc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Binary file removed app/release/app-release.apk
Binary file not shown.
1 change: 1 addition & 0 deletions app/src/main/java/com/hoc/flowmvi/core/CoreModule.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import com.hoc.flowmvi.core.dispatchers.CoroutineDispatchers
import com.hoc.flowmvi.core_ui.navigator.Navigator
import org.koin.dsl.module

@JvmField
val coreModule = module {
single<CoroutineDispatchers> { DefaultCoroutineDispatchers() }

Expand Down
2 changes: 2 additions & 0 deletions buildSrc/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/build
.gradle
12 changes: 6 additions & 6 deletions core-ui/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.hoc.flowmvi.core_ui">
package="com.hoc.flowmvi.core_ui">

<application>
<application>

<meta-data
android:name="preloaded_fonts"
android:resource="@array/preloaded_fonts" />
<meta-data
android:name="preloaded_fonts"
android:resource="@array/preloaded_fonts" />

</application>
</application>

</manifest>
6 changes: 0 additions & 6 deletions core-ui/src/main/java/com/hoc/flowmvi/core_ui/FlowBinding.kt
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import androidx.appcompat.widget.SearchView
import androidx.core.widget.doOnTextChanged
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.channels.awaitClose
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.callbackFlow
Expand All @@ -23,7 +22,6 @@ internal fun checkMainThread() {
}
}

@ExperimentalCoroutinesApi
@CheckResult
fun EditText.firstChange(): Flow<Unit> {
return callbackFlow {
Expand All @@ -39,7 +37,6 @@ fun EditText.firstChange(): Flow<Unit> {
}.take(1)
}

@ExperimentalCoroutinesApi
@CheckResult
fun SwipeRefreshLayout.refreshes(): Flow<Unit> {
return callbackFlow {
Expand All @@ -50,7 +47,6 @@ fun SwipeRefreshLayout.refreshes(): Flow<Unit> {
}
}

@ExperimentalCoroutinesApi
@CheckResult
fun View.clicks(): Flow<View> {
return callbackFlow {
Expand All @@ -67,7 +63,6 @@ data class SearchViewQueryTextEvent(
val isSubmitted: Boolean,
)

@ExperimentalCoroutinesApi
@CheckResult
fun SearchView.queryTextEvents(): Flow<SearchViewQueryTextEvent> {
return callbackFlow {
Expand Down Expand Up @@ -109,7 +104,6 @@ fun SearchView.queryTextEvents(): Flow<SearchViewQueryTextEvent> {
}
}

@ExperimentalCoroutinesApi
@CheckResult
fun EditText.textChanges(): Flow<CharSequence?> {
return callbackFlow {
Expand Down
9 changes: 4 additions & 5 deletions core-ui/src/main/res/font/noto_sans.xml
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<font-family xmlns:app="http://schemas.android.com/apk/res-auto"
app:fontProviderAuthority="com.google.android.gms.fonts"
app:fontProviderPackage="com.google.android.gms"
app:fontProviderQuery="Noto Sans"
app:fontProviderCerts="@array/com_google_android_gms_fonts_certs">
</font-family>
app:fontProviderAuthority="com.google.android.gms.fonts"
app:fontProviderCerts="@array/com_google_android_gms_fonts_certs"
app:fontProviderPackage="com.google.android.gms"
app:fontProviderQuery="Noto Sans"></font-family>
57 changes: 29 additions & 28 deletions core-ui/src/main/res/values/themes.xml
Original file line number Diff line number Diff line change
@@ -1,30 +1,31 @@
<resources>
<style name="AppTheme" parent="Theme.Material3.DayNight">
<item name="colorPrimary">@color/md_theme_light_primary</item>
<item name="colorOnPrimary">@color/md_theme_light_onPrimary</item>
<item name="colorPrimaryContainer">@color/md_theme_light_primaryContainer</item>
<item name="colorOnPrimaryContainer">@color/md_theme_light_onPrimaryContainer</item>
<item name="colorSecondary">@color/md_theme_light_secondary</item>
<item name="colorOnSecondary">@color/md_theme_light_onSecondary</item>
<item name="colorSecondaryContainer">@color/md_theme_light_secondaryContainer</item>
<item name="colorOnSecondaryContainer">@color/md_theme_light_onSecondaryContainer</item>
<item name="colorTertiary">@color/md_theme_light_tertiary</item>
<item name="colorOnTertiary">@color/md_theme_light_onTertiary</item>
<item name="colorTertiaryContainer">@color/md_theme_light_tertiaryContainer</item>
<item name="colorOnTertiaryContainer">@color/md_theme_light_onTertiaryContainer</item>
<item name="colorError">@color/md_theme_light_error</item>
<item name="colorErrorContainer">@color/md_theme_light_errorContainer</item>
<item name="colorOnError">@color/md_theme_light_onError</item>
<item name="colorOnErrorContainer">@color/md_theme_light_onErrorContainer</item>
<item name="android:colorBackground">@color/md_theme_light_background</item>
<item name="colorOnBackground">@color/md_theme_light_onBackground</item>
<item name="colorSurface">@color/md_theme_light_surface</item>
<item name="colorOnSurface">@color/md_theme_light_onSurface</item>
<item name="colorSurfaceVariant">@color/md_theme_light_surfaceVariant</item>
<item name="colorOnSurfaceVariant">@color/md_theme_light_onSurfaceVariant</item>
<item name="colorOutline">@color/md_theme_light_outline</item>
<item name="colorOnSurfaceInverse">@color/md_theme_light_inverseOnSurface</item>
<item name="colorSurfaceInverse">@color/md_theme_light_inverseSurface</item>
<item name="colorPrimaryInverse">@color/md_theme_light_primaryInverse</item>
</style>

<style name="AppTheme" parent="Theme.Material3.DayNight">
<item name="colorPrimary">@color/md_theme_light_primary</item>
<item name="colorOnPrimary">@color/md_theme_light_onPrimary</item>
<item name="colorPrimaryContainer">@color/md_theme_light_primaryContainer</item>
<item name="colorOnPrimaryContainer">@color/md_theme_light_onPrimaryContainer</item>
<item name="colorSecondary">@color/md_theme_light_secondary</item>
<item name="colorOnSecondary">@color/md_theme_light_onSecondary</item>
<item name="colorSecondaryContainer">@color/md_theme_light_secondaryContainer</item>
<item name="colorOnSecondaryContainer">@color/md_theme_light_onSecondaryContainer</item>
<item name="colorTertiary">@color/md_theme_light_tertiary</item>
<item name="colorOnTertiary">@color/md_theme_light_onTertiary</item>
<item name="colorTertiaryContainer">@color/md_theme_light_tertiaryContainer</item>
<item name="colorOnTertiaryContainer">@color/md_theme_light_onTertiaryContainer</item>
<item name="colorError">@color/md_theme_light_error</item>
<item name="colorErrorContainer">@color/md_theme_light_errorContainer</item>
<item name="colorOnError">@color/md_theme_light_onError</item>
<item name="colorOnErrorContainer">@color/md_theme_light_onErrorContainer</item>
<item name="android:colorBackground">@color/md_theme_light_background</item>
<item name="colorOnBackground">@color/md_theme_light_onBackground</item>
<item name="colorSurface">@color/md_theme_light_surface</item>
<item name="colorOnSurface">@color/md_theme_light_onSurface</item>
<item name="colorSurfaceVariant">@color/md_theme_light_surfaceVariant</item>
<item name="colorOnSurfaceVariant">@color/md_theme_light_onSurfaceVariant</item>
<item name="colorOutline">@color/md_theme_light_outline</item>
<item name="colorOnSurfaceInverse">@color/md_theme_light_inverseOnSurface</item>
<item name="colorSurfaceInverse">@color/md_theme_light_inverseSurface</item>
<item name="colorPrimaryInverse">@color/md_theme_light_primaryInverse</item>
</style>
</resources>
31 changes: 0 additions & 31 deletions core/src/main/java/com/hoc/flowmvi/core/SuspendRetry.kt

This file was deleted.

1 change: 1 addition & 0 deletions data/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ dependencies {
implementation(domain)

implementation(deps.coroutines.core)
implementation(deps.flowExt)

implementation(deps.squareup.retrofit)
implementation(deps.squareup.moshiKotlin)
Expand Down
3 changes: 1 addition & 2 deletions data/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.hoc.flowmvi.data">
<manifest package="com.hoc.flowmvi.data">

</manifest>
3 changes: 3 additions & 0 deletions data/src/main/java/com/hoc/flowmvi/data/DataModule.kt
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import com.squareup.moshi.Moshi
import com.squareup.moshi.adapter
import com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterFactory
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.FlowPreview
import okhttp3.OkHttpClient
import okhttp3.logging.HttpLoggingInterceptor
import okhttp3.logging.HttpLoggingInterceptor.Level
Expand All @@ -22,6 +23,8 @@ import kotlin.time.ExperimentalTime

val BASE_URL_QUALIFIER = named("BASE_URL")

@JvmField
@FlowPreview
@ExperimentalStdlibApi
@ExperimentalTime
@ExperimentalCoroutinesApi
Expand Down
69 changes: 32 additions & 37 deletions data/src/main/java/com/hoc/flowmvi/data/UserRepositoryImpl.kt
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,22 @@ import arrow.core.right
import arrow.core.valueOr
import com.hoc.flowmvi.core.Mapper
import com.hoc.flowmvi.core.dispatchers.CoroutineDispatchers
import com.hoc.flowmvi.core.retrySuspend
import com.hoc.flowmvi.data.remote.UserApiService
import com.hoc.flowmvi.data.remote.UserBody
import com.hoc.flowmvi.data.remote.UserResponse
import com.hoc.flowmvi.domain.model.User
import com.hoc.flowmvi.domain.model.UserError
import com.hoc.flowmvi.domain.model.UserValidationError
import com.hoc.flowmvi.domain.repository.UserRepository
import com.hoc081098.flowext.retryWithExponentialBackoff
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.delay
import kotlinx.coroutines.FlowPreview
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.asFlow
import kotlinx.coroutines.flow.catch
import kotlinx.coroutines.flow.emitAll
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.flatMapConcat
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.flow.scan
Expand All @@ -32,6 +34,7 @@ import kotlin.time.Duration.Companion.milliseconds
import kotlin.time.ExperimentalTime
import arrow.core.Either.Companion.catch as catchEither

@FlowPreview
@ExperimentalTime
@ExperimentalCoroutinesApi
internal class UserRepositoryImpl(
Expand Down Expand Up @@ -65,44 +68,38 @@ internal class UserRepositoryImpl(
@Suppress("NOTHING_TO_INLINE")
private inline fun logError(t: Throwable, message: String) = Timber.tag(TAG).e(t, message)

private suspend fun getUsersFromRemote(): List<User> {
return withContext(dispatchers.io) {
retrySuspend(
times = 3,
initialDelay = 500.milliseconds,
factor = 2.0,
shouldRetry = { it is IOException }
) { times ->
Timber.d("[USER_REPO] Retry times=$times")
userApiService
.getUsers()
.map(responseToDomainThrows)
}
}
}

override fun getUsers() = flow {
val initial = getUsersFromRemote()

changesFlow
.onEach { Timber.d("[USER_REPO] Change=$it") }
.scan(initial) { acc, change ->
when (change) {
is Change.Removed -> acc.filter { it.id != change.removed.id }
is Change.Refreshed -> change.user
is Change.Added -> acc + change.user
private fun getUsersFromRemote(): Flow<List<User>> = suspend {
Timber.d("[USER_REPO] getUsersFromRemote ...")
userApiService
.getUsers()
.map(responseToDomainThrows)
}.asFlow()
.retryWithExponentialBackoff(
maxAttempt = 2,
initialDelay = 500.milliseconds,
factor = 2.0,
) { it is IOException }

override fun getUsers() = getUsersFromRemote()
.flatMapConcat { initial ->
changesFlow
.onEach { Timber.d("[USER_REPO] Change=$it") }
.scan(initial) { acc, change ->
when (change) {
is Change.Removed -> acc.filter { it.id != change.removed.id }
is Change.Refreshed -> change.user
is Change.Added -> acc + change.user
}
}
}
.onEach { Timber.d("[USER_REPO] Emit users.size=${it.size} ") }
.let { emitAll(it) }
}
}
.onEach { Timber.d("[USER_REPO] Emit users.size=${it.size} ") }
.map { it.right().leftWiden<UserError, Nothing, List<User>>() }
.catch {
logError(it, "getUsers")
emit(errorMapper(it).left())
}

override suspend fun refresh() = catchEither { getUsersFromRemote() }
override suspend fun refresh() = catchEither { getUsersFromRemote().first() }
.tap { sendChange(Change.Refreshed(it)) }
.map { }
.tapLeft { logError(it, "refresh") }
Expand Down Expand Up @@ -131,8 +128,6 @@ internal class UserRepositoryImpl(
.mapLeft(errorMapper)
.bind()

delay(400) // TODO

val added = responseToDomain(response)
.mapLeft { UserError.ValidationFailed(it.toSet()) }
.tapInvalid { logError(it, "add user=$user") }
Expand Down
Loading