Skip to content

Commit 20ba922

Browse files
authored
Timber (#55)
1 parent 5151982 commit 20ba922

File tree

21 files changed

+72
-38
lines changed

21 files changed

+72
-38
lines changed

LICENSE

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
MIT License
22

3-
Copyright (c) 2019 Kotlin Android Open Source
3+
Copyright (c) 2019-2021 Kotlin Android Open Source
44

55
Permission is hereby granted, free of charge, to any person obtaining a copy
66
of this software and associated documentation files (the "Software"), to deal

app/build.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ dependencies {
6767
implementation(deps.koin.android)
6868

6969
debugImplementation(deps.squareup.leakCanary)
70+
implementation(deps.timber)
7071

7172
testImplementation(deps.test.junit)
7273
androidTestImplementation(deps.test.androidxJunit)

app/src/main/java/com/hoc/flowmvi/App.kt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import org.koin.android.ext.koin.androidContext
1313
import org.koin.android.ext.koin.androidLogger
1414
import org.koin.core.context.startKoin
1515
import org.koin.core.logger.Level
16+
import timber.log.Timber
1617
import kotlin.time.ExperimentalTime
1718

1819
@FlowPreview
@@ -37,6 +38,12 @@ class App : Application() {
3738
override fun onCreate() {
3839
super.onCreate()
3940

41+
if (BuildConfig.DEBUG) {
42+
Timber.plant(Timber.DebugTree())
43+
} else {
44+
// TODO(Timber): plant release tree
45+
}
46+
4047
startKoin {
4148
androidContext(this@App)
4249

buildSrc/src/main/kotlin/deps.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ object deps {
6969
const val coil = "io.coil-kt:coil:1.2.1"
7070
const val viewBindingDelegate = "com.github.hoc081098:ViewBindingDelegate:1.2.0"
7171
const val flowExt = "io.github.hoc081098:FlowExt:0.0.7-SNAPSHOT"
72+
const val timber = "com.jakewharton.timber:timber:5.0.1"
7273

7374
object arrow {
7475
private const val version = "1.0.1"

core/build.gradle.kts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,5 +49,7 @@ dependencies {
4949
implementation(deps.lifecycle.commonJava8)
5050
implementation(deps.lifecycle.runtimeKtx)
5151

52+
implementation(deps.timber)
53+
5254
addUnitTest()
5355
}

core/src/main/java/com/hoc/flowmvi/core/CollectIn.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
package com.hoc.flowmvi.core
22

3-
import android.util.Log
43
import androidx.fragment.app.Fragment
54
import androidx.lifecycle.Lifecycle
65
import androidx.lifecycle.LifecycleOwner
@@ -10,14 +9,15 @@ import kotlinx.coroutines.Job
109
import kotlinx.coroutines.flow.Flow
1110
import kotlinx.coroutines.flow.collect
1211
import kotlinx.coroutines.launch
12+
import timber.log.Timber
1313

1414
inline fun <T> Flow<T>.collectIn(
1515
owner: LifecycleOwner,
1616
minActiveState: Lifecycle.State = Lifecycle.State.STARTED,
1717
crossinline action: suspend (value: T) -> Unit,
1818
): Job = owner.lifecycleScope.launch {
1919
owner.repeatOnLifecycle(state = minActiveState) {
20-
Log.d("collectIn", "Start collecting $owner $minActiveState...")
20+
Timber.d("Start collecting $owner $minActiveState...")
2121
collect { action(it) }
2222
}
2323
}

core/src/main/java/com/hoc/flowmvi/core/FlowBinding.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ package com.hoc.flowmvi.core
22

33
import android.content.Context
44
import android.os.Looper
5-
import android.util.Log
65
import android.view.View
76
import android.widget.EditText
87
import android.widget.Toast
@@ -17,6 +16,7 @@ import kotlinx.coroutines.flow.Flow
1716
import kotlinx.coroutines.flow.callbackFlow
1817
import kotlinx.coroutines.flow.onStart
1918
import kotlinx.coroutines.flow.take
19+
import timber.log.Timber
2020
import kotlin.coroutines.EmptyCoroutineContext
2121

2222
internal fun checkMainThread() {
@@ -35,7 +35,7 @@ fun EditText.firstChange(): Flow<Unit> {
3535
awaitClose {
3636
Dispatchers.Main.dispatch(EmptyCoroutineContext) {
3737
removeTextChangedListener(listener)
38-
Log.d("###", "removeTextChangedListener $listener ${this@firstChange}")
38+
Timber.d("removeTextChangedListener $listener $this")
3939
}
4040
}
4141
}.take(1)

data/build.gradle.kts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,5 +52,7 @@ dependencies {
5252
implementation(deps.koin.core)
5353
implementation(deps.arrow.core)
5454

55+
implementation(deps.timber)
56+
5557
addUnitTest()
5658
}

data/src/main/java/com/hoc/flowmvi/data/UserRepositoryImpl.kt

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
package com.hoc.flowmvi.data
22

3-
import android.util.Log
43
import arrow.core.Either
54
import arrow.core.left
65
import arrow.core.leftWiden
@@ -24,6 +23,7 @@ import kotlinx.coroutines.flow.map
2423
import kotlinx.coroutines.flow.onEach
2524
import kotlinx.coroutines.flow.scan
2625
import kotlinx.coroutines.withContext
26+
import timber.log.Timber
2727
import java.io.IOException
2828
import kotlin.time.Duration
2929
import kotlin.time.ExperimentalTime
@@ -54,7 +54,7 @@ internal class UserRepositoryImpl(
5454
factor = 2.0,
5555
shouldRetry = { it is IOException }
5656
) {
57-
Log.d("###", "[USER_REPO] Retry times=$it")
57+
Timber.d("[USER_REPO] Retry times=$it")
5858
userApiService.getUsers().map(responseToDomain)
5959
}
6060
}
@@ -64,46 +64,53 @@ internal class UserRepositoryImpl(
6464
val initial = getUsersFromRemote()
6565

6666
changesFlow
67-
.onEach { Log.d("###", "[USER_REPO] Change=$it") }
67+
.onEach { Timber.d("[USER_REPO] Change=$it") }
6868
.scan(initial) { acc, change ->
6969
when (change) {
7070
is Change.Removed -> acc.filter { it.id != change.removed.id }
7171
is Change.Refreshed -> change.user
7272
is Change.Added -> acc + change.user
7373
}
7474
}
75-
.onEach { Log.d("###", "[USER_REPO] Emit users.size=${it.size} ") }
75+
.onEach { Timber.d("[USER_REPO] Emit users.size=${it.size} ") }
7676
.let { emitAll(it) }
7777
}
7878
.map { it.right().leftWiden<UserError, Nothing, List<User>>() }
79-
.catch { emit(errorMapper(it).left()) }
79+
.catch {
80+
Timber.tag("UserRepositoryImpl").e(it, "getUsers")
81+
emit(errorMapper(it).left())
82+
}
8083

81-
override suspend fun refresh() = Either.catch(errorMapper) {
84+
override suspend fun refresh() = Either.catch {
8285
getUsersFromRemote().let { changesFlow.emit(Change.Refreshed(it)) }
83-
}
86+
}.tapLeft { Timber.tag("UserRepositoryImpl").e(it, "refresh") }
87+
.mapLeft(errorMapper)
8488

85-
override suspend fun remove(user: User) = Either.catch(errorMapper) {
89+
override suspend fun remove(user: User) = Either.catch {
8690
withContext(dispatchers.io) {
8791
val response = userApiService.remove(user.id)
8892
changesFlow.emit(Change.Removed(responseToDomain(response)))
8993
}
90-
}
94+
}.tapLeft { Timber.tag("UserRepositoryImpl").e(it, "remove user=$user") }
95+
.mapLeft(errorMapper)
9196

92-
override suspend fun add(user: User) = Either.catch(errorMapper) {
97+
override suspend fun add(user: User) = Either.catch {
9398
withContext(dispatchers.io) {
9499
val body = domainToBody(user)
95100
val response = userApiService.add(body)
96101
changesFlow.emit(Change.Added(responseToDomain(response)))
97102
extraDelay()
98103
}
99-
}
104+
}.tapLeft { Timber.tag("UserRepositoryImpl").e(it, "add user=$user") }
105+
.mapLeft(errorMapper)
100106

101-
override suspend fun search(query: String) = Either.catch(errorMapper) {
107+
override suspend fun search(query: String) = Either.catch {
102108
withContext(dispatchers.io) {
103109
extraDelay()
104110
userApiService.search(query).map(responseToDomain)
105111
}
106-
}
112+
}.tapLeft { Timber.tag("UserRepositoryImpl").e(it, "search query=$query") }
113+
.mapLeft(errorMapper)
107114

108115
private suspend inline fun extraDelay() = delay(400)
109116
}

feature-add/build.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ dependencies {
5858

5959
implementation(deps.viewBindingDelegate)
6060
implementation(deps.flowExt)
61+
implementation(deps.timber)
6162

6263
addUnitTest()
6364
}

feature-add/src/main/java/com/hoc/flowmvi/ui/add/AddActivity.kt

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ package com.hoc.flowmvi.ui.add
22

33
import android.content.Context
44
import android.content.Intent
5-
import android.util.Log
65
import android.view.MenuItem
76
import androidx.core.view.isInvisible
87
import androidx.transition.AutoTransition
@@ -20,6 +19,7 @@ import kotlinx.coroutines.flow.Flow
2019
import kotlinx.coroutines.flow.map
2120
import kotlinx.coroutines.flow.merge
2221
import org.koin.androidx.viewmodel.ext.android.viewModel
22+
import timber.log.Timber
2323

2424
@ExperimentalCoroutinesApi
2525
class AddActivity :
@@ -35,22 +35,21 @@ class AddActivity :
3535
}
3636

3737
override fun handleSingleEvent(event: SingleEvent) {
38-
Log.d("###", "Event=$event")
38+
Timber.d("Event=$event")
3939

4040
return when (event) {
4141
is SingleEvent.AddUserSuccess -> {
4242
toast("Add success")
4343
finish()
4444
}
4545
is SingleEvent.AddUserFailure -> {
46-
Log.d("###", event.toString())
4746
toast("Add failure")
4847
}
4948
}
5049
}
5150

5251
override fun render(viewState: ViewState) {
53-
Log.d("###", "ViewState=$viewState")
52+
Timber.d("viewState=$viewState")
5453

5554
val emailErrorMessage = if (ValidationError.INVALID_EMAIL_ADDRESS in viewState.errors) {
5655
"Invalid email"

feature-add/src/main/java/com/hoc/flowmvi/ui/add/AddVM.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
package com.hoc.flowmvi.ui.add
22

3-
import android.util.Log
43
import androidx.core.util.PatternsCompat
54
import androidx.lifecycle.SavedStateHandle
65
import androidx.lifecycle.viewModelScope
@@ -31,6 +30,7 @@ import kotlinx.coroutines.flow.onEach
3130
import kotlinx.coroutines.flow.onStart
3231
import kotlinx.coroutines.flow.scan
3332
import kotlinx.coroutines.flow.stateIn
33+
import timber.log.Timber
3434

3535
@ExperimentalCoroutinesApi
3636
class AddVM(
@@ -46,13 +46,13 @@ class AddVM(
4646
firstName = savedStateHandle.get<String?>(FIRST_NAME_KEY),
4747
lastName = savedStateHandle.get<String?>(LAST_NAME_KEY),
4848
)
49-
Log.d(logTag, "[ADD_VM] initialVS: $initialVS")
49+
Timber.tag(logTag).d("[ADD_VM] initialVS: $initialVS")
5050

5151
viewState = intentFlow
5252
.toPartialStateChangesFlow()
5353
.sendSingleEvent()
5454
.scan(initialVS) { state, change -> change.reduce(state) }
55-
.catch { Log.d(logTag, "[ADD_VM] Throwable: $it") }
55+
.catch { Timber.tag(logTag).e(it, "[ADD_VM] Throwable: $it") }
5656
.stateIn(viewModelScope, SharingStarted.Eagerly, initialVS)
5757
}
5858

feature-main/build.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ dependencies {
6767
implementation(deps.viewBindingDelegate)
6868
implementation(deps.flowExt)
6969
implementation(deps.arrow.core)
70+
implementation(deps.timber)
7071

7172
addUnitTest()
7273
testImplementation(mviTesting)

feature-main/src/main/java/com/hoc/flowmvi/ui/main/MainActivity.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
package com.hoc.flowmvi.ui.main
22

3-
import android.util.Log
43
import android.view.Menu
54
import android.view.MenuItem
65
import androidx.core.view.isVisible
@@ -27,6 +26,7 @@ import kotlinx.coroutines.flow.map
2726
import kotlinx.coroutines.flow.merge
2827
import org.koin.android.ext.android.inject
2928
import org.koin.androidx.viewmodel.ext.android.viewModel
29+
import timber.log.Timber
3030

3131
@FlowPreview
3232
@ExperimentalCoroutinesApi
@@ -81,7 +81,7 @@ class MainActivity :
8181
)
8282

8383
override fun handleSingleEvent(event: SingleEvent) {
84-
Log.d("MainActivity", "handleSingleEvent $event")
84+
Timber.d("handleSingleEvent $event")
8585
return when (event) {
8686
SingleEvent.Refresh.Success -> toast("Refresh success")
8787
is SingleEvent.Refresh.Failure -> toast("Refresh failure")
@@ -92,7 +92,7 @@ class MainActivity :
9292
}
9393

9494
override fun render(viewState: ViewState) {
95-
Log.d("MainActivity", "render $viewState")
95+
Timber.d("render $viewState")
9696

9797
userAdapter.submitList(viewState.userItems)
9898

feature-main/src/main/java/com/hoc/flowmvi/ui/main/MainVM.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
package com.hoc.flowmvi.ui.main
22

3-
import android.util.Log
43
import androidx.lifecycle.viewModelScope
54
import com.hoc.flowmvi.domain.usecase.GetUsersUseCase
65
import com.hoc.flowmvi.domain.usecase.RefreshGetUsersUseCase
@@ -28,6 +27,7 @@ import kotlinx.coroutines.flow.onStart
2827
import kotlinx.coroutines.flow.scan
2928
import kotlinx.coroutines.flow.stateIn
3029
import kotlinx.coroutines.flow.take
30+
import timber.log.Timber
3131

3232
@FlowPreview
3333
@ExperimentalCoroutinesApi
@@ -49,7 +49,7 @@ class MainVM(
4949
.toPartialChangeFlow()
5050
.sendSingleEvent()
5151
.scan(initialVS) { vs, change -> change.reduce(vs) }
52-
.catch { Log.d("###", "[MAIN_VM] Throwable: $it") }
52+
.catch { Timber.tag(logTag).e(it, "[MAIN_VM] Throwable: $it") }
5353
.stateIn(
5454
viewModelScope,
5555
SharingStarted.Eagerly,
@@ -79,7 +79,7 @@ class MainVM(
7979
private fun Flow<ViewIntent>.toPartialChangeFlow(): Flow<PartialChange> =
8080
shareWhileSubscribed().run {
8181
val getUserChanges = defer(getUsersUseCase::invoke)
82-
.onEach { either -> Log.d("###", "[MAIN_VM] Emit users.size=${either.map { it.size }}") }
82+
.onEach { either -> Timber.d("[MAIN_VM] Emit users.size=${either.map { it.size }}") }
8383
.map { result ->
8484
result.fold(
8585
ifLeft = { PartialChange.GetUser.Error(it) },

feature-search/build.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ dependencies {
6161
implementation(deps.viewBindingDelegate)
6262
implementation(deps.flowExt)
6363
implementation(deps.arrow.core)
64+
implementation(deps.timber)
6465

6566
addUnitTest()
6667
}

feature-search/src/main/java/com/hoc/flowmvi/ui/search/SearchActivity.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ package com.hoc.flowmvi.ui.search
33
import android.content.Context
44
import android.content.Intent
55
import android.content.res.Configuration
6-
import android.util.Log
76
import android.view.Menu
87
import android.view.MenuItem
98
import androidx.appcompat.widget.SearchView
@@ -30,6 +29,7 @@ import kotlinx.coroutines.flow.map
3029
import kotlinx.coroutines.flow.merge
3130
import kotlinx.coroutines.flow.onEach
3231
import org.koin.androidx.viewmodel.ext.android.viewModel
32+
import timber.log.Timber
3333
import kotlin.time.ExperimentalTime
3434

3535
@ExperimentalCoroutinesApi
@@ -79,7 +79,7 @@ class SearchActivity :
7979
override fun viewIntents(): Flow<ViewIntent> = merge(
8080
searchViewQueryTextEventChannel
8181
.consumeAsFlow()
82-
.onEach { Log.d("SearchActivity", "Query $it") }
82+
.onEach { Timber.d("Query $it") }
8383
.map { ViewIntent.Search(it.query.toString()) },
8484
binding.retryButton.clicks().map { ViewIntent.Retry },
8585
)

0 commit comments

Comments
 (0)