diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 0bb98174..9fd2282c 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -21,9 +21,6 @@ jobs:
- name: Make gradlew executable
run: chmod +x ./gradlew
- - name: Spotless check
- run: ./gradlew spotlessCheck
-
- name: Build debug APK
run: ./gradlew assembleDebug --warning-mode all --stacktrace
diff --git a/.github/workflows/remove-old-artifacts.yml b/.github/workflows/remove-old-artifacts.yml
new file mode 100644
index 00000000..7d3aaa1f
--- /dev/null
+++ b/.github/workflows/remove-old-artifacts.yml
@@ -0,0 +1,22 @@
+name: Remove old artifacts
+
+on:
+# push:
+# branches: [ master ]
+
+ schedule:
+ # Runs at 01:00 UTC on the 1, 8, 15, 22 and 29th of every month.
+ - cron: '0 1 */7 * *'
+
+jobs:
+ remove-old-artifacts:
+ runs-on: ubuntu-latest
+ timeout-minutes: 10
+
+ steps:
+ - name: Remove old artifacts
+ uses: c-hive/gha-remove-artifacts@v1
+ with:
+ age: '1 month'
+ skip-tags: true
+ skip-recent: 5
\ No newline at end of file
diff --git a/.github/workflows/spotless.yml b/.github/workflows/spotless.yml
new file mode 100644
index 00000000..6ee1984f
--- /dev/null
+++ b/.github/workflows/spotless.yml
@@ -0,0 +1,25 @@
+name: Spotless check
+
+on:
+ push:
+ branches: [ master ]
+ pull_request:
+ branches: [ master ]
+
+jobs:
+ build:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v2
+
+ - name: Set up JDK
+ uses: actions/setup-java@v2
+ with:
+ distribution: 'zulu'
+ java-version: '11'
+
+ - name: Make gradlew executable
+ run: chmod +x ./gradlew
+
+ - name: Spotless check
+ run: ./gradlew spotlessCheck
diff --git a/.idea/jarRepositories.xml b/.idea/jarRepositories.xml
index 4eec7a1d..bc68000d 100644
--- a/.idea/jarRepositories.xml
+++ b/.idea/jarRepositories.xml
@@ -46,5 +46,10 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/README.md b/README.md
index 52ceaf2b..d5adbee8 100644
--- a/README.md
+++ b/README.md
@@ -29,7 +29,7 @@ This project brings to the table set of best practices, tools, and solutions:
[Download latest debug APK here](https://nightly.link/hoc081098/ComicReaderApp_MVI_Coroutine_RxKotlin_Jetpack/workflows/build/master/app-debug.zip)
# Develop
-- You must use **Android Studio Bumblebee (2021.1.1) Canary 1** (**note: Java 11 is now the minimum version required**)
+- You must use **Android Studio Arctic Fox (2020.3.1)** (**note: Java 11 is now the minimum version required**)
- Clone: `git clone https://github.com/hoc081098/ComicReaderApp_MVI_Coroutine_RxKotlin.git`
- _Optional: **Delete `.idea` folder** if cannot open project_
- Open project by `Android Studio` and run as usual
@@ -69,21 +69,3 @@ Clone this repository: https://github.com/hoc081098/comic_app_server_nodejs
MIT License
Copyright (c) 2019-2021 Petrus Nguyễn Thái Học
-
- Permission is hereby granted, free of charge, to any person obtaining a copy
- of this software and associated documentation files (the "Software"), to deal
- in the Software without restriction, including without limitation the rights
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- copies of the Software, and to permit persons to whom the Software is
- furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in all
- copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- SOFTWARE.
diff --git a/app/release/app-release.apk b/app/release/app-release.apk
deleted file mode 100644
index a58048c1..00000000
Binary files a/app/release/app-release.apk and /dev/null differ
diff --git a/app/release/output-metadata.json b/app/release/output-metadata.json
deleted file mode 100644
index 9928998c..00000000
--- a/app/release/output-metadata.json
+++ /dev/null
@@ -1,18 +0,0 @@
-{
- "version": 2,
- "artifactType": {
- "type": "APK",
- "kind": "Directory"
- },
- "applicationId": "com.hoc.comicapp",
- "variantName": "processReleaseResources",
- "elements": [
- {
- "type": "SINGLE",
- "filters": [],
- "versionCode": 1,
- "versionName": "0.0.1 2021-01-01",
- "outputFile": "app-release.apk"
- }
- ]
-}
\ No newline at end of file
diff --git a/app/release/output.json b/app/release/output.json
deleted file mode 100644
index c429e316..00000000
--- a/app/release/output.json
+++ /dev/null
@@ -1 +0,0 @@
-[{"outputType":{"type":"APK"},"apkData":{"type":"MAIN","splits":[],"versionCode":1,"versionName":"1.0","enabled":true,"outputFile":"app-release.apk","fullName":"release","baseName":"release"},"path":"app-release.apk","properties":{}}]
\ No newline at end of file
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 20622ec7..9ff95692 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -20,6 +20,7 @@
@@ -60,14 +61,13 @@
android:name="com.hoc.comicapp.initializer.AnalyticsInitializer"
android:value="androidx.startup" />
+
+
-
-
diff --git a/app/src/main/java/com/hoc/comicapp/activity/main/MainActivity.kt b/app/src/main/java/com/hoc/comicapp/activity/main/MainActivity.kt
index 345f2d63..fe7249e9 100644
--- a/app/src/main/java/com/hoc/comicapp/activity/main/MainActivity.kt
+++ b/app/src/main/java/com/hoc/comicapp/activity/main/MainActivity.kt
@@ -174,7 +174,7 @@ class MainActivity : ScopeActivity(R.layout.activity_main) {
.height(size)
.endConfig()
.buildRect(
- firstLetter.toUpperCase().toString(),
+ firstLetter.uppercase(),
ColorGenerator.MATERIAL.getColor(user.email)
)
}
diff --git a/app/src/main/java/com/hoc/comicapp/activity/main/MainVM.kt b/app/src/main/java/com/hoc/comicapp/activity/main/MainVM.kt
index 32e9668f..64a11f08 100644
--- a/app/src/main/java/com/hoc/comicapp/activity/main/MainVM.kt
+++ b/app/src/main/java/com/hoc/comicapp/activity/main/MainVM.kt
@@ -13,6 +13,7 @@ import com.jakewharton.rxrelay3.PublishRelay
import io.reactivex.rxjava3.core.Observable
import io.reactivex.rxjava3.core.Observable.mergeArray
import io.reactivex.rxjava3.core.ObservableTransformer
+import io.reactivex.rxjava3.disposables.Disposable
import io.reactivex.rxjava3.kotlin.addTo
import io.reactivex.rxjava3.kotlin.ofType
import io.reactivex.rxjava3.kotlin.subscribeBy
@@ -23,7 +24,7 @@ class MainVM(
) : BaseViewModel(ViewState.initial()) {
private val intentS = PublishRelay.create()
- override fun processIntents(intents: Observable) = intents.subscribe(intentS)!!
+ override fun processIntents(intents: Observable): Disposable = intents.subscribe(intentS)
private val initialProcessor =
ObservableTransformer { intent ->
diff --git a/app/src/main/java/com/hoc/comicapp/data/analytics/AnalyticsServiceImpl.kt b/app/src/main/java/com/hoc/comicapp/data/analytics/AnalyticsServiceImpl.kt
index af0d7147..dd0cd77e 100644
--- a/app/src/main/java/com/hoc/comicapp/data/analytics/AnalyticsServiceImpl.kt
+++ b/app/src/main/java/com/hoc/comicapp/data/analytics/AnalyticsServiceImpl.kt
@@ -27,7 +27,7 @@ class AnalyticsServiceImpl : AnalyticsService {
class SnakeCaseFirebaseAnalyticsEventMapper {
fun nameFor(event: String): String =
- CAMEL_REGEX.replace(event) { "_" + it.value }.toLowerCase()
+ CAMEL_REGEX.replace(event) { "_" + it.value }.lowercase()
fun paramsFor(params: Map?): Bundle? {
return bundleOf(
diff --git a/app/src/main/java/com/hoc/comicapp/data/firebase/favorite_comics/FavoriteComicsDataSourceImpl.kt b/app/src/main/java/com/hoc/comicapp/data/firebase/favorite_comics/FavoriteComicsDataSourceImpl.kt
index 59c36610..056d59b3 100644
--- a/app/src/main/java/com/hoc/comicapp/data/firebase/favorite_comics/FavoriteComicsDataSourceImpl.kt
+++ b/app/src/main/java/com/hoc/comicapp/data/firebase/favorite_comics/FavoriteComicsDataSourceImpl.kt
@@ -14,6 +14,7 @@ import com.hoc.comicapp.domain.models.AuthError
import com.hoc.comicapp.domain.thread.CoroutinesDispatchersProvider
import com.hoc.comicapp.domain.thread.RxSchedulerProvider
import com.hoc.comicapp.utils.snapshots
+import com.hoc.comicapp.utils.unit
import io.reactivex.rxjava3.core.Observable
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.ObsoleteCoroutinesApi
@@ -138,9 +139,7 @@ class FavoriteComicsDataSourceImpl(
}
}
- override fun update(comics: List<_FavoriteComic>) {
- actor.offer(comics)
- }
+ override fun update(comics: List<_FavoriteComic>) = actor.trySend(comics).unit
private val favoriteCollectionForCurrentUserOrNull: CollectionReference?
get() = firebaseAuth.currentUser?.uid?.let {
diff --git a/app/src/main/java/com/hoc/comicapp/data/repository/ComicRepositoryImpl.kt b/app/src/main/java/com/hoc/comicapp/data/repository/ComicRepositoryImpl.kt
index 94ce179b..115e6917 100644
--- a/app/src/main/java/com/hoc/comicapp/data/repository/ComicRepositoryImpl.kt
+++ b/app/src/main/java/com/hoc/comicapp/data/repository/ComicRepositoryImpl.kt
@@ -29,9 +29,9 @@ import kotlinx.coroutines.channels.actor
import kotlinx.coroutines.delay
import kotlinx.coroutines.withContext
import timber.log.Timber
+import kotlin.time.Duration.Companion.seconds
import kotlin.time.ExperimentalTime
import kotlin.time.measureTime
-import kotlin.time.seconds
@OptIn(
ExperimentalTime::class,
@@ -259,7 +259,7 @@ class ComicRepositoryImpl(
favoriteComicsDataSource.update(listOf(entity))
// update downloaded
- actor.offer(Mappers.responseToLocalEntity(comicDetail))
+ actor.trySend(Mappers.responseToLocalEntity(comicDetail))
}
private companion object {
diff --git a/app/src/main/java/com/hoc/comicapp/data/repository/DownloadComicsRepositoryImpl.kt b/app/src/main/java/com/hoc/comicapp/data/repository/DownloadComicsRepositoryImpl.kt
index e6967559..92f72cc7 100644
--- a/app/src/main/java/com/hoc/comicapp/data/repository/DownloadComicsRepositoryImpl.kt
+++ b/app/src/main/java/com/hoc/comicapp/data/repository/DownloadComicsRepositoryImpl.kt
@@ -54,6 +54,7 @@ import kotlinx.coroutines.withContext
import timber.log.Timber
import java.io.File
import java.util.Date
+import kotlin.time.DurationUnit
import kotlin.time.ExperimentalTime
import kotlin.time.TimeSource
@@ -279,7 +280,7 @@ class DownloadComicsRepositoryImpl(
chapterName = chapterDetail.chapterName,
comicLink = chapterDetail.comicLink,
comicName = chapterDetail.comicName,
- elapsedInMilliseconds = elapsed.inMilliseconds,
+ elapsedInMilliseconds = elapsed.toDouble(DurationUnit.MILLISECONDS),
elapsedInString = elapsed.toString()
)
)
diff --git a/app/src/main/java/com/hoc/comicapp/ui/category/CategoryViewModel.kt b/app/src/main/java/com/hoc/comicapp/ui/category/CategoryViewModel.kt
index de2e0e63..04efe7b6 100644
--- a/app/src/main/java/com/hoc/comicapp/ui/category/CategoryViewModel.kt
+++ b/app/src/main/java/com/hoc/comicapp/ui/category/CategoryViewModel.kt
@@ -9,6 +9,7 @@ import com.hoc.comicapp.utils.notOfType
import com.jakewharton.rxrelay3.PublishRelay
import io.reactivex.rxjava3.core.Observable
import io.reactivex.rxjava3.core.ObservableTransformer
+import io.reactivex.rxjava3.disposables.Disposable
import io.reactivex.rxjava3.kotlin.addTo
import io.reactivex.rxjava3.kotlin.cast
import io.reactivex.rxjava3.kotlin.ofType
@@ -87,6 +88,7 @@ class CategoryViewModel(
when (it) {
is CategoryPartialChange.RefreshPartialChange.Error -> sendMessageEvent(message = "Refresh error occurred: ${it.error.getMessage()}")
is CategoryPartialChange.RefreshPartialChange.Data -> sendMessageEvent(message = "Refresh success")
+ CategoryPartialChange.RefreshPartialChange.Loading -> return@doOnNext
}
}
.cast()
@@ -109,8 +111,8 @@ class CategoryViewModel(
}
}
- override fun processIntents(intents: Observable) =
- intents.subscribe(intentS)!!
+ override fun processIntents(intents: Observable): Disposable =
+ intents.subscribe(intentS)
init {
intentS
diff --git a/app/src/main/java/com/hoc/comicapp/ui/category_detail/CategoryDetailAdapter.kt b/app/src/main/java/com/hoc/comicapp/ui/category_detail/CategoryDetailAdapter.kt
index 57e6a7f8..5fcbd31d 100644
--- a/app/src/main/java/com/hoc/comicapp/ui/category_detail/CategoryDetailAdapter.kt
+++ b/app/src/main/java/com/hoc/comicapp/ui/category_detail/CategoryDetailAdapter.kt
@@ -7,10 +7,8 @@ import android.view.View
import android.view.ViewGroup
import androidx.annotation.LayoutRes
import androidx.core.view.isVisible
-import androidx.lifecycle.Lifecycle
-import androidx.lifecycle.LifecycleObserver
+import androidx.lifecycle.DefaultLifecycleObserver
import androidx.lifecycle.LifecycleOwner
-import androidx.lifecycle.OnLifecycleEvent
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.LinearSmoothScroller
@@ -33,6 +31,7 @@ import com.hoc.comicapp.ui.category_detail.CategoryDetailContract.ViewState.Head
import com.hoc.comicapp.ui.category_detail.CategoryDetailContract.ViewState.Item
import com.hoc.comicapp.utils.asObservable
import com.hoc.comicapp.utils.inflater
+import com.hoc.comicapp.utils.unit
import com.jakewharton.rxbinding4.recyclerview.scrollStateChanges
import com.jakewharton.rxbinding4.view.clicks
import com.jakewharton.rxbinding4.view.detaches
@@ -186,11 +185,10 @@ class CategoryDetailAdapter(
lifecycleOwner
.lifecycle
.addObserver(
- object : LifecycleObserver {
+ object : DefaultLifecycleObserver {
var disposable: Disposable? = null
- @OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
- private fun onCreate() {
+ override fun onCreate(owner: LifecycleOwner) {
disposable = startStopAutoScrollS
.mergeWith(
binding.popularRecyclerHorizontal
@@ -229,14 +227,11 @@ class CategoryDetailAdapter(
)
}
- @OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
- private fun onResume() = startStopAutoScrollS.accept(true)
+ override fun onResume(owner: LifecycleOwner) = startStopAutoScrollS.accept(true)
- @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
- private fun onPause() = startStopAutoScrollS.accept(false)
+ override fun onPause(owner: LifecycleOwner) = startStopAutoScrollS.accept(false)
- @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
- private fun onDestroy() = disposable?.dispose()
+ override fun onDestroy(owner: LifecycleOwner) = disposable?.dispose().unit
}
)
}
diff --git a/app/src/main/java/com/hoc/comicapp/ui/category_detail/CategoryDetailVM.kt b/app/src/main/java/com/hoc/comicapp/ui/category_detail/CategoryDetailVM.kt
index 8ebb73b3..76666aa3 100644
--- a/app/src/main/java/com/hoc/comicapp/ui/category_detail/CategoryDetailVM.kt
+++ b/app/src/main/java/com/hoc/comicapp/ui/category_detail/CategoryDetailVM.kt
@@ -15,6 +15,7 @@ import com.jakewharton.rxrelay3.PublishRelay
import io.reactivex.rxjava3.core.Observable
import io.reactivex.rxjava3.core.Observable.mergeArray
import io.reactivex.rxjava3.core.ObservableTransformer
+import io.reactivex.rxjava3.disposables.Disposable
import io.reactivex.rxjava3.kotlin.addTo
import io.reactivex.rxjava3.kotlin.ofType
import io.reactivex.rxjava3.kotlin.subscribeBy
@@ -27,7 +28,7 @@ class CategoryDetailVM(
private val intentS = PublishRelay.create()
private val stateS = BehaviorRelay.createDefault(initialState)
- override fun processIntents(intents: Observable) = intents.subscribe(intentS)!!
+ override fun processIntents(intents: Observable): Disposable = intents.subscribe(intentS)
private val initialProcessor =
ObservableTransformer { intent ->
diff --git a/app/src/main/java/com/hoc/comicapp/ui/chapter_detail/ChapterDetailViewModel.kt b/app/src/main/java/com/hoc/comicapp/ui/chapter_detail/ChapterDetailViewModel.kt
index 5b3daea1..223bd54f 100644
--- a/app/src/main/java/com/hoc/comicapp/ui/chapter_detail/ChapterDetailViewModel.kt
+++ b/app/src/main/java/com/hoc/comicapp/ui/chapter_detail/ChapterDetailViewModel.kt
@@ -15,6 +15,7 @@ import com.hoc.comicapp.utils.notOfType
import com.jakewharton.rxrelay3.PublishRelay
import io.reactivex.rxjava3.core.Observable
import io.reactivex.rxjava3.core.ObservableTransformer
+import io.reactivex.rxjava3.disposables.Disposable
import io.reactivex.rxjava3.kotlin.addTo
import io.reactivex.rxjava3.kotlin.ofType
import io.reactivex.rxjava3.kotlin.subscribeBy
@@ -120,8 +121,8 @@ class ChapterDetailViewModel(
)
}
- override fun processIntents(intents: Observable) =
- intents.subscribe(intentS)!!
+ override fun processIntents(intents: Observable): Disposable =
+ intents.subscribe(intentS)
init {
intentS
diff --git a/app/src/main/java/com/hoc/comicapp/ui/detail/ComicDetailViewModel.kt b/app/src/main/java/com/hoc/comicapp/ui/detail/ComicDetailViewModel.kt
index 4009983e..4b352615 100644
--- a/app/src/main/java/com/hoc/comicapp/ui/detail/ComicDetailViewModel.kt
+++ b/app/src/main/java/com/hoc/comicapp/ui/detail/ComicDetailViewModel.kt
@@ -26,6 +26,7 @@ import com.jakewharton.rxrelay3.BehaviorRelay
import com.jakewharton.rxrelay3.PublishRelay
import io.reactivex.rxjava3.core.Observable
import io.reactivex.rxjava3.core.ObservableTransformer
+import io.reactivex.rxjava3.disposables.Disposable
import io.reactivex.rxjava3.kotlin.addTo
import io.reactivex.rxjava3.kotlin.ofType
import io.reactivex.rxjava3.kotlin.subscribeBy
@@ -52,8 +53,8 @@ class ComicDetailViewModel(
private val intentS = PublishRelay.create()
private val stateS = BehaviorRelay.createDefault(initialState)
- override fun processIntents(intents: Observable) =
- intents.subscribe(intentS)!!
+ override fun processIntents(intents: Observable): Disposable =
+ intents.subscribe(intentS)
private val initialProcessor =
ObservableTransformer { intent ->
@@ -225,6 +226,9 @@ class ComicDetailViewModel(
Timber.d("$operation error $it")
sendMessageEvent("$operation error: ${event.chapter.chapterName}")
}
+ is ComicDetailSingleEvent.EnqueuedDownloadFailure -> return@subscribeBy
+ is ComicDetailSingleEvent.EnqueuedDownloadSuccess -> return@subscribeBy
+ is ComicDetailSingleEvent.MessageEvent -> return@subscribeBy
}
}
.addTo(compositeDisposable)
diff --git a/app/src/main/java/com/hoc/comicapp/ui/downloaded_comics/DownloadedComicsAdapter.kt b/app/src/main/java/com/hoc/comicapp/ui/downloaded_comics/DownloadedComicsAdapter.kt
index 0f7b03df..a4a9692f 100644
--- a/app/src/main/java/com/hoc/comicapp/ui/downloaded_comics/DownloadedComicsAdapter.kt
+++ b/app/src/main/java/com/hoc/comicapp/ui/downloaded_comics/DownloadedComicsAdapter.kt
@@ -58,10 +58,10 @@ class DownloadedComicsAdapter(
)
}
- private fun Observable.getItemAtPosition(): Observable {
+ private fun Observable.getItemAtPosition(): Observable {
return map { bindingAdapterPosition }
.filter { it != NO_POSITION }
- .map { getItem(it) }
+ .map(::getItem)
}
init {
diff --git a/app/src/main/java/com/hoc/comicapp/ui/downloaded_comics/DownloadedComicsViewModel.kt b/app/src/main/java/com/hoc/comicapp/ui/downloaded_comics/DownloadedComicsViewModel.kt
index e5c7bd7e..9a8e759d 100644
--- a/app/src/main/java/com/hoc/comicapp/ui/downloaded_comics/DownloadedComicsViewModel.kt
+++ b/app/src/main/java/com/hoc/comicapp/ui/downloaded_comics/DownloadedComicsViewModel.kt
@@ -12,6 +12,7 @@ import com.hoc.comicapp.utils.notOfType
import com.jakewharton.rxrelay3.PublishRelay
import io.reactivex.rxjava3.core.Observable
import io.reactivex.rxjava3.core.ObservableTransformer
+import io.reactivex.rxjava3.disposables.Disposable
import io.reactivex.rxjava3.functions.BiFunction
import io.reactivex.rxjava3.kotlin.addTo
import io.reactivex.rxjava3.kotlin.ofType
@@ -25,7 +26,7 @@ class DownloadedComicsViewModel(
private val intentS = PublishRelay.create()
- override fun processIntents(intents: Observable) = intents.subscribe(intentS)!!
+ override fun processIntents(intents: Observable): Disposable = intents.subscribe(intentS)
private val intentToChanges = ObservableTransformer { intents ->
intents
diff --git a/app/src/main/java/com/hoc/comicapp/ui/downloading_chapters/DownloadingChaptersViewModel.kt b/app/src/main/java/com/hoc/comicapp/ui/downloading_chapters/DownloadingChaptersViewModel.kt
index 0215c537..a33b03ca 100644
--- a/app/src/main/java/com/hoc/comicapp/ui/downloading_chapters/DownloadingChaptersViewModel.kt
+++ b/app/src/main/java/com/hoc/comicapp/ui/downloading_chapters/DownloadingChaptersViewModel.kt
@@ -20,6 +20,7 @@ import com.hoc.comicapp.worker.DownloadComicWorker
import com.jakewharton.rxrelay3.PublishRelay
import io.reactivex.rxjava3.core.Observable
import io.reactivex.rxjava3.core.ObservableTransformer
+import io.reactivex.rxjava3.disposables.Disposable
import io.reactivex.rxjava3.functions.BiFunction
import io.reactivex.rxjava3.kotlin.addTo
import io.reactivex.rxjava3.kotlin.ofType
@@ -76,7 +77,8 @@ class DownloadingChaptersViewModel(
}
}
- override fun processIntents(intents: Observable) = intents.subscribe(intentS)!!
+ override fun processIntents(intents: Observable): Disposable =
+ intents.subscribe(intentS)
init {
Timber.d("DownloadingChaptersViewModel::init")
diff --git a/app/src/main/java/com/hoc/comicapp/ui/favorite_comics/FavoriteComicsAdapter.kt b/app/src/main/java/com/hoc/comicapp/ui/favorite_comics/FavoriteComicsAdapter.kt
index 64c439e5..4bc45788 100644
--- a/app/src/main/java/com/hoc/comicapp/ui/favorite_comics/FavoriteComicsAdapter.kt
+++ b/app/src/main/java/com/hoc/comicapp/ui/favorite_comics/FavoriteComicsAdapter.kt
@@ -49,10 +49,10 @@ class FavoriteComicsAdapter(
inner class VH(private val binding: ItemRecyclerFavoriteComicsBinding, parent: View) :
RecyclerView.ViewHolder(binding.root) {
- private fun Observable.getItemAtPosition(): Observable {
+ private fun Observable.getItemAtPosition(): Observable {
return map { bindingAdapterPosition }
.filter { it != NO_POSITION }
- .map { getItem(it) }
+ .map(::getItem)
}
init {
diff --git a/app/src/main/java/com/hoc/comicapp/ui/favorite_comics/FavoriteComicsVM.kt b/app/src/main/java/com/hoc/comicapp/ui/favorite_comics/FavoriteComicsVM.kt
index 80cd6214..c9f98fd4 100644
--- a/app/src/main/java/com/hoc/comicapp/ui/favorite_comics/FavoriteComicsVM.kt
+++ b/app/src/main/java/com/hoc/comicapp/ui/favorite_comics/FavoriteComicsVM.kt
@@ -13,6 +13,7 @@ import com.hoc.comicapp.utils.notOfType
import com.jakewharton.rxrelay3.PublishRelay
import io.reactivex.rxjava3.core.Observable
import io.reactivex.rxjava3.core.ObservableTransformer
+import io.reactivex.rxjava3.disposables.Disposable
import io.reactivex.rxjava3.functions.BiFunction
import io.reactivex.rxjava3.kotlin.addTo
import io.reactivex.rxjava3.kotlin.ofType
@@ -25,7 +26,8 @@ class FavoriteComicsVM(
private val intentS = PublishRelay.create()
- override fun processIntents(intents: Observable) = intents.subscribe(intentS)!!
+ override fun processIntents(intents: Observable): Disposable =
+ intents.subscribe(intentS)
private val initialProcessor =
ObservableTransformer { intent ->
diff --git a/app/src/main/java/com/hoc/comicapp/ui/home/HomeAdapter.kt b/app/src/main/java/com/hoc/comicapp/ui/home/HomeAdapter.kt
index 081cf082..1beab46d 100644
--- a/app/src/main/java/com/hoc/comicapp/ui/home/HomeAdapter.kt
+++ b/app/src/main/java/com/hoc/comicapp/ui/home/HomeAdapter.kt
@@ -6,10 +6,8 @@ import android.view.View
import android.view.ViewGroup
import androidx.annotation.IntDef
import androidx.core.view.isVisible
-import androidx.lifecycle.Lifecycle
-import androidx.lifecycle.LifecycleObserver
+import androidx.lifecycle.DefaultLifecycleObserver
import androidx.lifecycle.LifecycleOwner
-import androidx.lifecycle.OnLifecycleEvent
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.LinearSmoothScroller
import androidx.recyclerview.widget.LinearSnapHelper
@@ -30,6 +28,7 @@ import com.hoc.comicapp.ui.home.HomeListItem.HeaderType.MOST_VIEWED
import com.hoc.comicapp.ui.home.HomeListItem.HeaderType.NEWEST
import com.hoc.comicapp.ui.home.HomeListItem.HeaderType.UPDATED
import com.hoc.comicapp.utils.mapNotNull
+import com.hoc.comicapp.utils.unit
import com.hoc081098.viewbindingdelegate.inflateViewBinding
import com.jakewharton.rxbinding4.recyclerview.scrollStateChanges
import com.jakewharton.rxbinding4.view.clicks
@@ -89,18 +88,18 @@ class HomeAdapter(
private val clickComicS = PublishRelay.create<_HomeClickEvent>()
// Retry observables
- val newestRetryObservable = newestRetryS.throttleFirst(500, TimeUnit.MILLISECONDS)!!
- val mostViewedRetryObservable = mostViewedRetryS.throttleFirst(500, TimeUnit.MILLISECONDS)!!
- val updatedRetryObservable = updatedRetryS.throttleFirst(500, TimeUnit.MILLISECONDS)!!
+ val newestRetryObservable: Observable = newestRetryS.throttleFirst(500, TimeUnit.MILLISECONDS)
+ val mostViewedRetryObservable: Observable = mostViewedRetryS.throttleFirst(500, TimeUnit.MILLISECONDS)
+ val updatedRetryObservable: Observable = updatedRetryS.throttleFirst(500, TimeUnit.MILLISECONDS)
// Click observables
- val clickComicObservable = Observable.mergeArray(
+ val clickComicObservable: Observable = Observable.mergeArray(
newestAdapter.clickComicObservable,
mostViewedAdapter.clickComicObservable,
clickComicS,
)
.map(::toHomeClickEvent)
- .doOnNext { Timber.d("[*] Click comic $it") }!!
+ .doOnNext { Timber.d("[*] Click comic $it") }
override fun onCreateViewHolder(parent: ViewGroup, @ViewType viewType: Int): VH {
return when (viewType) {
@@ -207,11 +206,10 @@ class HomeAdapter(
}
lifecycleOwner.lifecycle.addObserver(
- object : LifecycleObserver {
+ object : DefaultLifecycleObserver {
var disposable: Disposable? = null
- @OnLifecycleEvent(Lifecycle.Event.ON_START)
- private fun onCreate() {
+ override fun onCreate(owner: LifecycleOwner) {
disposable = startStopAutoScrollS
.doOnNext { Timber.d("[###] [1] $it") }
.concatMap {
@@ -263,18 +261,16 @@ class HomeAdapter(
Timber.d("[>>>] ON_CREATE")
}
- @OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
- private fun onResume() = startStopAutoScrollS.accept(true)
+ override fun onResume(owner: LifecycleOwner) = startStopAutoScrollS.accept(true)
.also { Timber.d("[>>>] ON_RESUME -> start") }
- @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
- private fun onPause() = startStopAutoScrollS.accept(false)
+ override fun onPause(owner: LifecycleOwner) = startStopAutoScrollS.accept(false)
.also { Timber.d("[>>>] ON_PAUSE -> stop") }
- @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
- private fun onDestroy() = disposable?.dispose()
+ override fun onDestroy(owner: LifecycleOwner) = disposable?.dispose()
.also { lifecycleOwner.lifecycle.removeObserver(this) }
.also { Timber.d("[>>>] ON_DESTROY -> disposed") }
+ .unit
}
)
}
diff --git a/app/src/main/java/com/hoc/comicapp/ui/home/HomeViewModel.kt b/app/src/main/java/com/hoc/comicapp/ui/home/HomeViewModel.kt
index 971ea1bb..30c2d880 100644
--- a/app/src/main/java/com/hoc/comicapp/ui/home/HomeViewModel.kt
+++ b/app/src/main/java/com/hoc/comicapp/ui/home/HomeViewModel.kt
@@ -9,6 +9,7 @@ import com.jakewharton.rxrelay3.BehaviorRelay
import com.jakewharton.rxrelay3.PublishRelay
import io.reactivex.rxjava3.core.Observable
import io.reactivex.rxjava3.core.ObservableTransformer
+import io.reactivex.rxjava3.disposables.Disposable
import io.reactivex.rxjava3.kotlin.addTo
import io.reactivex.rxjava3.kotlin.ofType
import io.reactivex.rxjava3.kotlin.subscribeBy
@@ -198,8 +199,8 @@ class HomeViewModel(
.observeOn(rxSchedulerProvider.main)
}
- override fun processIntents(intents: Observable) =
- intents.subscribe(intentS)!!
+ override fun processIntents(intents: Observable): Disposable =
+ intents.subscribe(intentS)
init {
intentS
diff --git a/app/src/main/java/com/hoc/comicapp/ui/login/LoginVM.kt b/app/src/main/java/com/hoc/comicapp/ui/login/LoginVM.kt
index c4ce5f26..c0c4121d 100644
--- a/app/src/main/java/com/hoc/comicapp/ui/login/LoginVM.kt
+++ b/app/src/main/java/com/hoc/comicapp/ui/login/LoginVM.kt
@@ -11,6 +11,7 @@ import com.hoc.comicapp.ui.login.LoginContract.ViewState
import com.hoc.comicapp.utils.exhaustMap
import com.jakewharton.rxrelay3.PublishRelay
import io.reactivex.rxjava3.core.Observable
+import io.reactivex.rxjava3.disposables.Disposable
import io.reactivex.rxjava3.kotlin.addTo
import io.reactivex.rxjava3.kotlin.ofType
import io.reactivex.rxjava3.kotlin.subscribeBy
@@ -22,7 +23,7 @@ class LoginVM(
private val intentS = PublishRelay.create()
- override fun processIntents(intents: Observable) = intents.subscribe(intentS)!!
+ override fun processIntents(intents: Observable): Disposable = intents.subscribe(intentS)
init {
val emailObservable = intentS.ofType()
diff --git a/app/src/main/java/com/hoc/comicapp/ui/register/RegisterVM.kt b/app/src/main/java/com/hoc/comicapp/ui/register/RegisterVM.kt
index 85a4cfea..156f0ccb 100644
--- a/app/src/main/java/com/hoc/comicapp/ui/register/RegisterVM.kt
+++ b/app/src/main/java/com/hoc/comicapp/ui/register/RegisterVM.kt
@@ -17,6 +17,7 @@ import com.hoc.comicapp.utils.exhaustMap
import com.jakewharton.rxrelay3.BehaviorRelay
import com.jakewharton.rxrelay3.PublishRelay
import io.reactivex.rxjava3.core.Observable
+import io.reactivex.rxjava3.disposables.Disposable
import io.reactivex.rxjava3.kotlin.addTo
import io.reactivex.rxjava3.kotlin.ofType
import io.reactivex.rxjava3.kotlin.subscribeBy
@@ -28,7 +29,7 @@ class RegisterVM(
private val intentS = PublishRelay.create()
- override fun processIntents(intents: Observable) = intents.subscribe(intentS)!!
+ override fun processIntents(intents: Observable): Disposable = intents.subscribe(intentS)
init {
val avatarSubject = BehaviorRelay.createDefault