Skip to content

Commit

Permalink
Split domain (#65)
Browse files Browse the repository at this point in the history
* create module

* create module

* refactor: split :domain

* fix: add domain/AndroidManifest.xml

* gradle cache

* update ComicDetailViewModel.kt

* refactor(domain): use Uri multiplatform

* remove domain manifest
  • Loading branch information
hoc081098 authored Apr 26, 2022
1 parent 989abe0 commit 6dbef49
Show file tree
Hide file tree
Showing 39 changed files with 175 additions and 72 deletions.
10 changes: 10 additions & 0 deletions .github/workflows/build-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,16 @@ jobs:
distribution: 'zulu'
java-version: '11'

- name: Cache gradle, wrapper and buildSrc
uses: actions/cache@v2
with:
path: |
~/.gradle/caches
~/.gradle/wrapper
key: ${{ runner.os }}-${{ github.job }}-${{ hashFiles('**/*.gradle*') }}-${{ hashFiles('**/gradle/wrapper/gradle-wrapper.properties') }}-${{ hashFiles('**/buildSrc/**/*.kt') }}
restore-keys: |
${{ runner.os }}-${{ github.job }}-
- name: Make gradlew executable
run: chmod +x ./gradlew

Expand Down
48 changes: 29 additions & 19 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,22 +10,32 @@ jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3

- name: Set up JDK
uses: actions/setup-java@v3
with:
distribution: 'zulu'
java-version: '11'

- name: Make gradlew executable
run: chmod +x ./gradlew

- name: Build debug APK
run: ./gradlew assembleDebug --warning-mode all --stacktrace

- name: Upload APK
uses: actions/upload-artifact@v3
with:
name: app-debug
path: app/build/outputs/apk/debug/app-debug.apk
- uses: actions/checkout@v3

- name: Set up JDK
uses: actions/setup-java@v3
with:
distribution: 'zulu'
java-version: '11'

- name: Cache gradle, wrapper and buildSrc
uses: actions/cache@v2
with:
path: |
~/.gradle/caches
~/.gradle/wrapper
key: ${{ runner.os }}-${{ github.job }}-${{ hashFiles('**/*.gradle*') }}-${{ hashFiles('**/gradle/wrapper/gradle-wrapper.properties') }}-${{ hashFiles('**/buildSrc/**/*.kt') }}
restore-keys: |
${{ runner.os }}-${{ github.job }}-
- name: Make gradlew executable
run: chmod +x ./gradlew

- name: Build debug APK
run: ./gradlew assembleDebug --warning-mode all --stacktrace

- name: Upload APK
uses: actions/upload-artifact@v3
with:
name: app-debug
path: app/build/outputs/apk/debug/app-debug.apk
10 changes: 10 additions & 0 deletions .github/workflows/spotless.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,16 @@ jobs:
distribution: 'zulu'
java-version: '11'

- name: Cache gradle, wrapper and buildSrc
uses: actions/cache@v2
with:
path: |
~/.gradle/caches
~/.gradle/wrapper
key: ${{ runner.os }}-${{ github.job }}-${{ hashFiles('**/*.gradle*') }}-${{ hashFiles('**/gradle/wrapper/gradle-wrapper.properties') }}-${{ hashFiles('**/buildSrc/**/*.kt') }}
restore-keys: |
${{ runner.os }}-${{ github.job }}-
- name: Make gradlew executable
run: chmod +x ./gradlew

Expand Down
9 changes: 8 additions & 1 deletion .idea/compiler.xml

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

2 changes: 2 additions & 0 deletions .idea/gradle.xml

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

5 changes: 5 additions & 0 deletions .idea/jarRepositories.xml

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

2 changes: 1 addition & 1 deletion .idea/misc.xml

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

1 change: 1 addition & 0 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ dependencies {
implementation(project(deps.module.baseUi))
implementation(project(deps.module.utils))
implementation(project(deps.module.navigation))
implementation(project(deps.module.domain))

implementation(deps.kotlin.stdlib)
val coroutineDepConfig: (ExternalModuleDependency).() -> Unit = {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package com.hoc.comicapp.data.local.dao

import androidx.lifecycle.LiveData
import androidx.room.Dao
import androidx.room.Delete
import androidx.room.Insert
Expand All @@ -21,9 +20,6 @@ abstract class ChapterDao {
@Query("SELECT COUNT(*) FROM downloaded_chapters WHERE comic_link = :comicLink")
abstract suspend fun getCountByComicLink(comicLink: String): List<Int>

@Query("SELECT * FROM downloaded_chapters")
abstract fun getAllChaptersLiveData(): LiveData<List<ChapterEntity>>

@Query("SELECT * FROM downloaded_chapters")
abstract fun getAllChaptersFlow(): Flow<List<ChapterEntity>>

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package com.hoc.comicapp.data.repository

import android.app.Application
import androidx.lifecycle.LiveData
import androidx.lifecycle.map
import androidx.room.withTransaction
import androidx.work.Constraints
Expand Down Expand Up @@ -77,9 +76,9 @@ class DownloadComicsRepositoryImpl(
private val analyticsService: AnalyticsService,
) : DownloadComicsRepository {

override fun getDownloadedChapters(): LiveData<List<DownloadedChapter>> =
override fun getDownloadedChapters(): Flow<List<DownloadedChapter>> =
chapterDao
.getAllChaptersLiveData()
.getAllChaptersFlow()
.map { it.map(Mappers::entityToDomainModel) }

override fun getDownloadedComics(): Observable<DomainResult<List<DownloadedComic>>> =
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.hoc.comicapp.data.repository

import android.net.Uri
import androidx.core.net.toUri
import com.chrynan.uri.core.Uri
import com.hoc.comicapp.data.ErrorMapper
import com.hoc.comicapp.data.firebase.user.FirebaseAuthUserDataSource
import com.hoc.comicapp.domain.DomainResult
Expand Down Expand Up @@ -37,7 +38,7 @@ class UserRepositoryImpl(
email = email,
password = password,
fullName = fullName,
avatar = avatar
avatar = avatar?.uriString?.toUri()
)
.tapLeft {
Timber.e(it, "Failed to register user")
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package com.hoc.comicapp.ui.detail

import androidx.lifecycle.LiveData
import androidx.lifecycle.Observer
import androidx.lifecycle.asFlow
import androidx.lifecycle.viewModelScope
import androidx.work.WorkInfo
import androidx.work.WorkInfo.State.RUNNING
import androidx.work.WorkManager
Expand All @@ -16,8 +16,6 @@ import com.hoc.comicapp.ui.detail.ComicDetailViewState.DownloadState
import com.hoc.comicapp.ui.detail.ComicDetailViewState.DownloadState.Downloaded
import com.hoc.comicapp.ui.detail.ComicDetailViewState.DownloadState.Downloading
import com.hoc.comicapp.ui.detail.ComicDetailViewState.DownloadState.NotYetDownload
import com.hoc.comicapp.utils.NotNullMutableLiveData
import com.hoc.comicapp.utils.combineLatest
import com.hoc.comicapp.utils.exhaustMap
import com.hoc.comicapp.utils.mapNotNull
import com.hoc.comicapp.utils.notOfType
Expand All @@ -31,6 +29,12 @@ import io.reactivex.rxjava3.kotlin.addTo
import io.reactivex.rxjava3.kotlin.ofType
import io.reactivex.rxjava3.kotlin.subscribeBy
import io.reactivex.rxjava3.kotlin.withLatestFrom
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.rx3.asFlow
import timber.log.Timber

class ComicDetailViewModel(
Expand All @@ -41,15 +45,7 @@ class ComicDetailViewModel(
private val isDownloaded: Boolean,
) : BaseViewModel<ComicDetailIntent, ComicDetailViewState, ComicDetailSingleEvent>(
ComicDetailViewState.initialState()
),
Observer<ComicDetailViewState> {

override fun onChanged(t: ComicDetailViewState?) {
setNewState(t ?: return)
}

private val _stateD: LiveData<ComicDetailViewState>

) {
private val intentS = PublishRelay.create<ComicDetailIntent>()
private val stateS = BehaviorRelay.createDefault(initialState)

Expand Down Expand Up @@ -138,7 +134,10 @@ class ComicDetailViewModel(
.doOnNext { Timber.d("intent=$it") }
.share()

_stateD = initStateD(filteredIntent)
initViewState(filteredIntent)
.onEach(setNewState)
.launchIn(viewModelScope)

processDownloadChapterIntent(filteredIntent)
processDeleteAndCancelDownloadingChapterIntent(filteredIntent)
processToggleFavorite(filteredIntent)
Expand All @@ -158,32 +157,30 @@ class ComicDetailViewModel(
.addTo(compositeDisposable)
}

private fun initStateD(filteredIntent: Observable<ComicDetailIntent>): LiveData<ComicDetailViewState> {
// intent -> behavior subject
filteredIntent
private fun initViewState(intents: Observable<ComicDetailIntent>): Flow<ComicDetailViewState> {
val stateFlow = intents
.compose(intentToViewState)
.doOnNext { Timber.d("view_state=$it") }
.subscribeBy(onNext = stateS::accept)
.addTo(compositeDisposable)
.asFlow()
.distinctUntilChanged()

// behavior subject -> live data
val stateD = NotNullMutableLiveData(initialState)
stateS
.subscribeBy(onNext = stateD::setValue)
.addTo(compositeDisposable)
val workInfosFlow = workManager.getWorkInfosByTagLiveData(DownloadComicWorker.TAG)
.asFlow()
.distinctUntilChanged()

// combine live datas -> state live data
val workInfosD = workManager.getWorkInfosByTagLiveData(DownloadComicWorker.TAG)
val downloadedChaptersD = downloadComicsRepository.getDownloadedChapters()
val downloadedChaptersFlow = downloadComicsRepository
.getDownloadedChapters()
.distinctUntilChanged()

return stateD.combineLatest(
workInfosD,
downloadedChaptersD
return combine(
stateFlow,
workInfosFlow,
downloadedChaptersFlow
) { state, workInfos, downloadedChapters ->
Timber.d("[combine] ${workInfos.size} ${downloadedChapters.size}")

val comicDetail = state.comicDetail as? ComicDetailViewState.ComicDetail.Detail
?: return@combineLatest state
?: return@combine state

val newChapters = comicDetail.chapters.map { chapter ->
chapter.copy(
Expand All @@ -196,7 +193,7 @@ class ComicDetailViewModel(
}

state.copy(comicDetail = comicDetail.copy(chapters = newChapters))
}.apply { observeForever(this@ComicDetailViewModel) }
}
}

private fun processDeleteAndCancelDownloadingChapterIntent(filteredIntent: Observable<ComicDetailIntent>) {
Expand Down Expand Up @@ -234,11 +231,6 @@ class ComicDetailViewModel(
.addTo(compositeDisposable)
}

override fun onCleared() {
super.onCleared()
_stateD.removeObserver(this)
}

private fun processDownloadChapterIntent(filteredIntent: Observable<ComicDetailIntent>) {
filteredIntent
.ofType<ComicDetailIntent.DownloadChapter>()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package com.hoc.comicapp.ui.register

import com.chrynan.uri.core.Uri
import com.chrynan.uri.core.fromString
import com.hoc.comicapp.domain.repository.UserRepository
import com.hoc.comicapp.domain.thread.CoroutinesDispatchersProvider
import com.hoc.comicapp.ui.register.RegisterContract.Interactor
Expand All @@ -24,7 +26,12 @@ class RegisterInteractorImpl(
val (email, password, fullName, avatar) = user

userRepository
.register(email, password, fullName, avatar)
.register(
email = email,
password = password,
fullName = fullName,
avatar = avatar?.toString()?.let(Uri::fromString),
)
.fold(
ifLeft = { PartialChange.RegisterFailure(it) },
ifRight = { PartialChange.RegisterSuccess }
Expand Down
1 change: 1 addition & 0 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ allprojects {
maven(url = "https://oss.sonatype.org/content/repositories/snapshots")
maven(url = "https://s01.oss.sonatype.org/content/repositories/snapshots/")
maven(url = "https://jitpack.io")
maven(url = "https://repo.repsy.io/mvn/chrynan/public")
maven {
url = uri("http://dl.bintray.com/amulyakhare/maven")
isAllowInsecureProtocol = true
Expand Down
7 changes: 7 additions & 0 deletions buildSrc/src/main/kotlin/Configurations.kt
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ object versions {
}

const val arrow = "1.1.2"
const val uri = "0.3.3"
const val viewBindingDelegate = "1.3.1"
}

Expand All @@ -93,6 +94,8 @@ object deps {
const val baseUi = ":base-ui"
const val utils = ":utils"
const val navigation = ":navigation"
const val domain = ":domain"
const val featureHome = ":feature-home"
}

object kotlin {
Expand Down Expand Up @@ -203,6 +206,10 @@ object deps {
const val fxCoroutines = "io.arrow-kt:arrow-fx-coroutines:${versions.arrow}"
}

object uri {
const val core = "com.chrynan.uri:uri-core:${versions.uri}"
}

const val listenableFuture = "com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava"
const val viewBindingDelegate = "com.github.hoc081098:ViewBindingDelegate:${versions.viewBindingDelegate}"
}
Expand Down
1 change: 1 addition & 0 deletions domain/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/build
11 changes: 11 additions & 0 deletions domain/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
plugins {
`comic-app-plugin`
kotlin
}

dependencies {
implementation(deps.reactiveX.java)
implementation(deps.kotlin.coroutinesCore)
implementation(deps.arrow.core)
api(deps.uri.core)
}
Loading

0 comments on commit 6dbef49

Please sign in to comment.