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

#239 복구 #250

Merged
merged 10 commits into from
Aug 19, 2024
3 changes: 3 additions & 0 deletions android/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@
android:supportsRtl="true"
android:theme="@style/Theme.PokeRogueHelper"
tools:targetApi="31">
<activity
android:name=".presentation.battle.selection.BattleSelectionActivity"
android:exported="false" />
<activity
android:name=".presentation.battle.BattleActivity"
android:exported="false" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import poke.rogue.helper.R
import poke.rogue.helper.databinding.ActivityBattleBinding
import poke.rogue.helper.presentation.base.toolbar.ToolbarActivity
import poke.rogue.helper.presentation.battle.model.WeatherUiModel
import poke.rogue.helper.presentation.battle.selection.BattleSelectionActivity
import poke.rogue.helper.presentation.util.context.startActivity
import poke.rogue.helper.presentation.util.repeatOnStarted

class BattleActivity : ToolbarActivity<ActivityBattleBinding>(R.layout.activity_battle) {
Expand All @@ -30,6 +32,10 @@ class BattleActivity : ToolbarActivity<ActivityBattleBinding>(R.layout.activity_
private fun initView() {
binding.vm = viewModel
binding.lifecycleOwner = this

binding.ivMinePokemon.setOnClickListener {
startActivity<BattleSelectionActivity> { }
}
}

private fun initSpinner() {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package poke.rogue.helper.presentation.battle

sealed interface BattleSelectionUiState<out T : Any> {
data class Selected<T : Any>(val selected: T) : BattleSelectionUiState<T>

data object Empty : BattleSelectionUiState<Nothing>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package poke.rogue.helper.presentation.battle.model

import poke.rogue.helper.presentation.type.model.TypeUiModel

data class PokemonSelectionUiModel(
val id: String,
val dexNumber: Long,
val name: String,
val frontImageUrl: String,
val backImageUrl: String,
val types: List<TypeUiModel>,
) {
companion object {
val DUMMY =
listOf(
PokemonSelectionUiModel(
id = "Bulbasaur",
dexNumber = 1,
name = "이상해씨",
frontImageUrl = "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/1.png",
backImageUrl = "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/back/1.png",
types =
listOf(
TypeUiModel.GRASS,
TypeUiModel.POISON,
),
),
PokemonSelectionUiModel(
id = "Charmander",
dexNumber = 4,
name = "파이리",
frontImageUrl = "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/4.png",
backImageUrl = "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/back/4.png",
types = listOf(TypeUiModel.FIRE),
),
PokemonSelectionUiModel(
id = "Squirtle",
dexNumber = 7,
name = "꼬북이",
frontImageUrl = "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/7.png",
backImageUrl = "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/back/7.png",
types = listOf(TypeUiModel.WATER),
),
PokemonSelectionUiModel(
id = "Pikachu",
dexNumber = 25,
name = "피카츄",
frontImageUrl = "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/25.png",
backImageUrl = "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/back/25.png",
types = listOf(TypeUiModel.ELECTRIC),
),
PokemonSelectionUiModel(
id = "Charizard",
dexNumber = 6,
name = "리자몽",
frontImageUrl = "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/6.png",
backImageUrl = "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/back/6.png",
types = listOf(TypeUiModel.FIRE, TypeUiModel.FLYING),
),
)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package poke.rogue.helper.presentation.battle.model

import poke.rogue.helper.presentation.type.model.TypeUiModel

data class SkillSelectionUiModel(
val id: String,
val name: String,
val type: TypeUiModel,
val category: String,
) {
companion object {
val DUMMY =
listOf(
SkillSelectionUiModel(
id = "1",
name = "몸통박치기",
type = TypeUiModel.NORMAL,
category = "Physical Attack",
),
SkillSelectionUiModel(
id = "2",
name = "울음소리",
type = TypeUiModel.NORMAL,
category = "Status Change",
),
SkillSelectionUiModel(
id = "3",
name = "덩굴채찍",
type = TypeUiModel.GRASS,
category = "Physical Attack",
),
SkillSelectionUiModel(
id = "4",
name = "성장",
type = TypeUiModel.NORMAL,
category = "Status Change",
),
SkillSelectionUiModel(
id = "5",
name = "씨뿌리기",
type = TypeUiModel.GRASS,
category = "Status Change",
),
)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package poke.rogue.helper.presentation.battle.selection

import android.os.Bundle
import androidx.activity.viewModels
import androidx.appcompat.widget.Toolbar
import poke.rogue.helper.R
import poke.rogue.helper.databinding.ActivityBattleSelectionBinding
import poke.rogue.helper.presentation.base.error.ErrorHandleActivity
import poke.rogue.helper.presentation.base.error.ErrorHandleViewModel
import poke.rogue.helper.presentation.battle.BattleSelectionUiState
import poke.rogue.helper.presentation.util.repeatOnStarted
import poke.rogue.helper.presentation.util.view.setImage

class BattleSelectionActivity :
ErrorHandleActivity<ActivityBattleSelectionBinding>(R.layout.activity_battle_selection) {
private val viewModel by viewModels<BattleSelectionViewModel>()
private val selectionPagerAdapter: BattleSelectionPagerAdapter by lazy {
BattleSelectionPagerAdapter(this)
}

override val errorViewModel: ErrorHandleViewModel
get() = viewModel

override val toolbar: Toolbar
get() = binding.toolbarBattleSelection

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
initViews()
initObserver()
}

private fun initViews() {
binding.lifecycleOwner = this
binding.vm = viewModel
binding.pagerBattleSelection.adapter = selectionPagerAdapter
binding.pagerBattleSelection.isUserInputEnabled = false
}

private fun initObserver() {
repeatOnStarted {
viewModel.selectedPokemon.collect { selectionState ->
if (selectionState is BattleSelectionUiState.Selected) {
val selected = selectionState.selected
binding.ivPokemon.setImage(selected.frontImageUrl)
binding.toolbarBattleSelection.title = selected.name
}
}
}

repeatOnStarted {
viewModel.currentStep.collect {
binding.pagerBattleSelection.currentItem = it.ordinal
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package poke.rogue.helper.presentation.battle.selection

import poke.rogue.helper.presentation.battle.model.PokemonSelectionUiModel
import poke.rogue.helper.presentation.battle.model.SkillSelectionUiModel

interface BattleSelectionHandler {
fun selectPokemon(pokemon: PokemonSelectionUiModel)

fun selectSkill(skill: SkillSelectionUiModel)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package poke.rogue.helper.presentation.battle.selection

import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentActivity
import androidx.viewpager2.adapter.FragmentStateAdapter
import poke.rogue.helper.presentation.battle.selection.pokemon.PokemonSelectionFragment
import poke.rogue.helper.presentation.battle.selection.skill.SkillSelectionFragment

class BattleSelectionPagerAdapter(fragmentActivity: FragmentActivity) :
FragmentStateAdapter(fragmentActivity) {
private val pages = SelectionStep.entries

override fun getItemCount(): Int = pages.size

override fun createFragment(position: Int): Fragment =
when (pages[position]) {
SelectionStep.POKEMON_SELECTION -> PokemonSelectionFragment()
SelectionStep.SKILL_SELECTION -> SkillSelectionFragment()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package poke.rogue.helper.presentation.battle.selection

import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import poke.rogue.helper.analytics.AnalyticsLogger
import poke.rogue.helper.analytics.analyticsLogger
import poke.rogue.helper.presentation.base.error.ErrorHandleViewModel
import poke.rogue.helper.presentation.battle.BattleSelectionUiState
import poke.rogue.helper.presentation.battle.model.PokemonSelectionUiModel
import poke.rogue.helper.presentation.battle.model.SkillSelectionUiModel

class BattleSelectionViewModel(
logger: AnalyticsLogger = analyticsLogger(),
) : ErrorHandleViewModel(logger), BattleSelectionHandler, NavigationHandler {
private val _pokemons = MutableStateFlow(PokemonSelectionUiModel.DUMMY)
val pokemons = _pokemons.asStateFlow()

private val _selectedPokemon =
MutableStateFlow<BattleSelectionUiState<PokemonSelectionUiModel>>(BattleSelectionUiState.Empty)
val selectedPokemon = _selectedPokemon.asStateFlow()

private val _skills = MutableStateFlow(SkillSelectionUiModel.DUMMY)
val skills = _skills.asStateFlow()

private val _selectedSkill =
MutableStateFlow<BattleSelectionUiState<SkillSelectionUiModel>>(BattleSelectionUiState.Empty)
val selectedSkill = _selectedSkill.asStateFlow()

private val _currentStep = MutableStateFlow(SelectionStep.POKEMON_SELECTION)
val currentStep: StateFlow<SelectionStep> = _currentStep.asStateFlow()

override fun selectPokemon(pokemon: PokemonSelectionUiModel) {
_selectedPokemon.value = BattleSelectionUiState.Selected(pokemon)
}

override fun selectSkill(skill: SkillSelectionUiModel) {
_selectedSkill.value = BattleSelectionUiState.Selected(skill)
}

override fun navigateToNextPage() {
val nextPage =
when (currentStep.value) {
SelectionStep.POKEMON_SELECTION -> SelectionStep.SKILL_SELECTION
SelectionStep.SKILL_SELECTION -> return // TODO : Complete Selection
}
_currentStep.value = nextPage
}

override fun navigateToPrevPage() {
val prevPage =
when (currentStep.value) {
SelectionStep.POKEMON_SELECTION -> return
SelectionStep.SKILL_SELECTION -> SelectionStep.POKEMON_SELECTION
}
_currentStep.value = prevPage
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package poke.rogue.helper.presentation.battle.selection

interface NavigationHandler {
fun navigateToNextPage()

fun navigateToPrevPage()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package poke.rogue.helper.presentation.battle.selection

import android.view.View
import androidx.databinding.BindingAdapter
import poke.rogue.helper.R

@BindingAdapter("invisible")
fun View.setInvisible(invisible: Boolean) {
visibility = if (invisible) View.INVISIBLE else View.VISIBLE
}

@BindingAdapter("selectedBackground")
fun View.setBackground(isSelected: Boolean) {
if (isSelected) {
setBackgroundResource(R.drawable.bg_battle_selected_border)
} else {
setBackgroundResource(R.drawable.bg_battle_default)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package poke.rogue.helper.presentation.battle.selection

enum class SelectionStep(val buttonText: String) {
POKEMON_SELECTION("다음"),
SKILL_SELECTION("선택 완료"),
;

fun isLastStep(hasSkillSelection: Boolean): Boolean {
return if (hasSkillSelection) {
this == SKILL_SELECTION
} else {
this == POKEMON_SELECTION
}
}
}
Loading
Loading