Skip to content

Commit

Permalink
Implement delete clone monster feature (#228)
Browse files Browse the repository at this point in the history
  • Loading branch information
alexandregpereira authored Jan 13, 2024
1 parent ee858a8 commit ab4239d
Show file tree
Hide file tree
Showing 19 changed files with 102 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,10 @@ internal class MonsterDaoImpl(
}
}

override suspend fun deleteMonster(index: String) = withContext(dispatcher) {
monsterQueries.deleteByIndex(index)
}

private fun deleteAllEntries(monsters: List<MonsterCompleteEntity>) {
val monsterIndexes = monsters.map { it.monster.index }
val actionsIds = monsters.mapAndReduce { actions.map { it.action.id } }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ INSERT OR REPLACE INTO MonsterEntity VALUES ?;
deleteAll:
DELETE FROM MonsterEntity WHERE isClone == 0;

deleteByIndex:
DELETE FROM MonsterEntity WHERE `index` == ?;

getMonstersThatIsNotCloned:
SELECT * FROM MonsterEntity WHERE isClone == 0;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,5 @@ interface MonsterLocalRepository {
fun getMonsters(indexes: List<String>): Flow<List<Monster>>
fun getMonster(index: String): Flow<Monster>
fun getMonstersByQuery(query: String): Flow<List<Monster>>
fun deleteMonster(index: String): Flow<Unit>
}
Original file line number Diff line number Diff line change
Expand Up @@ -52,4 +52,8 @@ internal class DefaultMonsterLocalRepository(
override fun getMonstersByQuery(query: String): Flow<List<Monster>> {
return localDataSource.getMonstersByQuery(query).map { it.toDomainMonsterEntity() }
}

override fun deleteMonster(index: String): Flow<Unit> {
return localDataSource.deleteMonster(index)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -71,4 +71,8 @@ internal class DefaultMonsterLocalDataSource(
}
emit(Unit)
}

override fun deleteMonster(index: String): Flow<Unit> = flow {
emit(monsterDao.deleteMonster(index))
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,5 @@ internal interface MonsterLocalDataSource {
fun getMonstersByQuery(query: String): Flow<List<MonsterEntity>>
fun saveMonsters(monsters: List<MonsterCompleteEntity>, isSync: Boolean): Flow<Unit>
fun getMonster(index: String): Flow<MonsterCompleteEntity>
fun deleteMonster(index: String): Flow<Unit>
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,6 @@ interface MonsterDao {
suspend fun getMonstersByQuery(query: String): List<MonsterEntity>

suspend fun insert(monsters: List<MonsterCompleteEntity>, deleteAll: Boolean)

suspend fun deleteMonster(index: String)
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ enum class MonsterDetailOptionState(val stringRes: Int) {
ADD_TO_FOLDER(R.string.monster_detail_options_add_to_folder),
CLONE(R.string.monster_detail_clone),
EDIT(R.string.monster_detail_edit),
DELETE(R.string.monster_detail_delete),
CHANGE_TO_FEET(R.string.monster_detail_options_change_to_feet),
CHANGE_TO_METERS(R.string.monster_detail_options_change_to_meters)
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import br.alexandregpereira.hunter.monster.detail.MonsterDetailAnalytics
import br.alexandregpereira.hunter.monster.detail.MonsterDetailState
import br.alexandregpereira.hunter.monster.detail.MonsterDetailStateHolder
import br.alexandregpereira.hunter.monster.detail.domain.CloneMonsterUseCase
import br.alexandregpereira.hunter.monster.detail.domain.DeleteMonsterUseCase
import br.alexandregpereira.hunter.monster.detail.domain.GetMonsterDetailUseCase
import br.alexandregpereira.hunter.monster.registration.event.MonsterRegistrationEvent
import br.alexandregpereira.hunter.monster.registration.event.MonsterRegistrationResult
Expand All @@ -46,6 +47,7 @@ internal class MonsterDetailViewModel(
getMonsterDetailUseCase: GetMonsterDetailUseCase,
cloneMonster: CloneMonsterUseCase,
changeMonstersMeasurementUnitUseCase: ChangeMonstersMeasurementUnitUseCase,
deleteMonsterUseCase: DeleteMonsterUseCase,
spellDetailEventDispatcher: SpellDetailEventDispatcher,
monsterDetailEventListener: MonsterDetailEventListener,
monsterDetailEventDispatcher: MonsterDetailEventDispatcher,
Expand All @@ -61,6 +63,7 @@ internal class MonsterDetailViewModel(
getMonsterDetailUseCase,
cloneMonster,
changeMonstersMeasurementUnitUseCase,
deleteMonsterUseCase,
spellDetailEventDispatcher,
monsterDetailEventListener,
monsterDetailEventDispatcher,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ val monsterDetailModule = monsterDetailStateModule.apply {
getMonsterDetailUseCase = get(),
cloneMonster = get(),
changeMonstersMeasurementUnitUseCase = get(),
deleteMonsterUseCase = get(),
spellDetailEventDispatcher = get(),
monsterDetailEventListener = get(),
monsterDetailEventDispatcher = get(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,4 +49,5 @@
<string name="monster_detail_clone">Clonar</string>
<string name="monster_detail_clone_monster_name">Nome</string>
<string name="monster_detail_edit">Editar</string>
<string name="monster_detail_delete">Remover</string>
</resources>
Original file line number Diff line number Diff line change
Expand Up @@ -50,4 +50,5 @@
<string name="monster_detail_clone">Clone</string>
<string name="monster_detail_clone_monster_name">Name</string>
<string name="monster_detail_edit">Edit</string>
<string name="monster_detail_delete">Delete</string>
</resources>
Original file line number Diff line number Diff line change
Expand Up @@ -97,4 +97,22 @@ class MonsterDetailAnalytics(
)
)
}

fun trackMonsterDetailDeleteClicked(monsterIndex: String) {
analytics.track(
eventName = "MonsterDetail - delete clicked",
params = mapOf(
"monsterIndex" to monsterIndex,
)
)
}

fun trackMonsterDetailEditClicked(monsterIndex: String) {
analytics.track(
eventName = "MonsterDetail - edit clicked",
params = mapOf(
"monsterIndex" to monsterIndex,
)
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ enum class MonsterDetailOptionState {
ADD_TO_FOLDER,
CLONE,
EDIT,
DELETE,
CHANGE_TO_FEET,
CHANGE_TO_METERS
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,10 @@ import br.alexandregpereira.hunter.monster.detail.MonsterDetailOptionState.ADD_T
import br.alexandregpereira.hunter.monster.detail.MonsterDetailOptionState.CHANGE_TO_FEET
import br.alexandregpereira.hunter.monster.detail.MonsterDetailOptionState.CHANGE_TO_METERS
import br.alexandregpereira.hunter.monster.detail.MonsterDetailOptionState.CLONE
import br.alexandregpereira.hunter.monster.detail.MonsterDetailOptionState.DELETE
import br.alexandregpereira.hunter.monster.detail.MonsterDetailOptionState.EDIT
import br.alexandregpereira.hunter.monster.detail.domain.CloneMonsterUseCase
import br.alexandregpereira.hunter.monster.detail.domain.DeleteMonsterUseCase
import br.alexandregpereira.hunter.monster.detail.domain.GetMonsterDetailUseCase
import br.alexandregpereira.hunter.monster.detail.domain.model.MonsterDetail
import br.alexandregpereira.hunter.monster.registration.event.MonsterRegistrationEvent
Expand Down Expand Up @@ -67,6 +69,7 @@ class MonsterDetailStateHolder(
private val getMonsterDetailUseCase: GetMonsterDetailUseCase,
private val cloneMonster: CloneMonsterUseCase,
private val changeMonstersMeasurementUnitUseCase: ChangeMonstersMeasurementUnitUseCase,
private val deleteMonster: DeleteMonsterUseCase,
private val spellDetailEventDispatcher: SpellDetailEventDispatcher,
private val monsterDetailEventListener: MonsterDetailEventListener,
private val monsterDetailEventDispatcher: MonsterDetailEventDispatcher,
Expand Down Expand Up @@ -163,12 +166,17 @@ class MonsterDetailStateHolder(
CLONE -> showCloneForm()

EDIT -> {
analytics.trackMonsterDetailEditClicked(monsterIndex)
setState { HideOptions }
monsterRegistrationEventDispatcher.dispatchEvent(
MonsterRegistrationEvent.ShowEdit(monsterIndex)
)
}

DELETE -> {
deleteMonster()
}

CHANGE_TO_FEET -> {
changeMeasurementUnit(MeasurementUnit.FEET)
}
Expand Down Expand Up @@ -272,7 +280,7 @@ class MonsterDetailStateHolder(
private fun MonsterDetailState.changeOptions(): MonsterDetailState {
val monster = monsters.find { monster -> monster.index == monsterIndex } ?: return this
val editOption = if (monster.isClone) {
listOf(EDIT)
listOf(EDIT, DELETE)
} else emptyList()

return copy(
Expand Down Expand Up @@ -313,4 +321,15 @@ class MonsterDetailStateHolder(
.emitState()
.launchIn(scope)
}

private fun deleteMonster() {
analytics.trackMonsterDetailDeleteClicked(monsterIndex)
deleteMonster(monsterIndex)
.flowOn(dispatcher)
.onEach {
monsterDetailEventDispatcher.dispatchEvent(OnCompendiumChanges)
monsterDetailEventDispatcher.dispatchEvent(Hide)
}
.launchIn(scope)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import br.alexandregpereira.hunter.event.monster.detail.MonsterDetailEventListen
import br.alexandregpereira.hunter.monster.detail.MonsterDetailAnalytics
import br.alexandregpereira.hunter.monster.detail.MonsterDetailStateHolder
import br.alexandregpereira.hunter.monster.detail.domain.CloneMonsterUseCase
import br.alexandregpereira.hunter.monster.detail.domain.DeleteMonsterUseCase
import br.alexandregpereira.hunter.monster.registration.event.MonsterRegistrationEventDispatcher
import br.alexandregpereira.hunter.monster.registration.event.MonsterRegistrationEventListener
import org.koin.dsl.module
Expand All @@ -44,11 +45,13 @@ val monsterDetailStateModule = module {
get(),
get(),
get(),
get(),
monsterRegistrationEventDispatcher = get<MonsterRegistrationEventDispatcher>(),
monsterRegistrationEventListener = get<MonsterRegistrationEventListener>(),
get(),
analytics = MonsterDetailAnalytics(get()),
)
}
factory { CloneMonsterUseCase(get(), get(), get(), get()) }
factory { DeleteMonsterUseCase(repository = get()) }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*
* Copyright 2022 Alexandre Gomes Pereira
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package br.alexandregpereira.hunter.monster.detail.domain

import br.alexandregpereira.hunter.domain.repository.MonsterLocalRepository
import kotlinx.coroutines.flow.Flow

fun interface DeleteMonsterUseCase {
operator fun invoke(id: String): Flow<Unit>
}

internal fun DeleteMonsterUseCase(
repository: MonsterLocalRepository,
): DeleteMonsterUseCase = DeleteMonsterUseCase { id ->
repository.deleteMonster(id)
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@ import kotlinx.coroutines.Dispatchers
import org.koin.core.qualifier.Qualifier
import org.koin.core.qualifier.qualifier
import org.koin.dsl.module
import kotlin.native.HiddenFromObjC

@HiddenFromObjC
val monsterRegistrationStateModule = module {
single<StateHolderParams<MonsterRegistrationParams>>(qualifier = paramsQualifier) {
StateHolderParams(MonsterRegistrationParams())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,11 @@ import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.map

fun interface NormalizeMonsterUseCase {
internal fun interface NormalizeMonsterUseCase {
operator fun invoke(monster: Monster): Flow<Monster>
}

fun NormalizeMonsterUseCase(): NormalizeMonsterUseCase = NormalizeMonsterUseCase { monster ->
internal fun NormalizeMonsterUseCase(): NormalizeMonsterUseCase = NormalizeMonsterUseCase { monster ->
flowOf(monster)
.map { it.changeAbilityScoresModifier() }
}
Expand Down

0 comments on commit ab4239d

Please sign in to comment.