Skip to content

Commit e7c3e54

Browse files
committed
Merge branch 'feat/party-removal' into 'master'
Mazání Party Closes #30 See merge request fmasa/pv239-project!87
2 parents cbd5f13 + 84922e6 commit e7c3e54

File tree

23 files changed

+279
-66
lines changed

23 files changed

+279
-66
lines changed

app/src/main/java/cz/muni/fi/rpg/di/container.kt

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -103,24 +103,26 @@ val appModule = module {
103103
viewModel { (characterId: CharacterId) -> ArmorViewModel(characterId, get()) }
104104
viewModel { (characterId: CharacterId) -> CharacterStatsViewModel(characterId, get()) }
105105
viewModel { (characterId: CharacterId) -> CharacterMiscViewModel(characterId, get(), get()) }
106-
viewModel { (characterId: CharacterId) -> CharacterViewModel(characterId, get(), get())}
106+
viewModel { (characterId: CharacterId) -> CharacterViewModel(characterId, get())}
107107
viewModel { (partyId: UUID) -> GameMasterViewModel(partyId, get(), get()) }
108108
viewModel { (partyId: UUID) -> EncountersViewModel(partyId, get()) }
109-
viewModel { (encounterId: EncounterId) -> EncounterDetailViewModel(encounterId, get(), get(), get()) }
109+
viewModel { (partyId: UUID) -> PartyViewModel(partyId, get()) }
110+
viewModel { (encounterId: EncounterId) -> EncounterDetailViewModel(encounterId, get(), get()) }
110111
viewModel { (characterId: CharacterId) -> InventoryViewModel(characterId, get(), get(), get()) }
111112
viewModel { (characterId: CharacterId) -> SkillsViewModel(characterId, get()) }
112113
viewModel { (characterId: CharacterId) -> SpellsViewModel(characterId, get()) }
113114
viewModel { (characterId: CharacterId) -> TalentsViewModel(characterId, get()) }
114115
viewModel { AuthenticationViewModel(get()) }
115116
viewModel { JoinPartyViewModel(get()) }
117+
viewModel { PartyListViewModel(get()) }
116118

117119
/**
118120
* Fragments
119121
*/
120122
fragment { CharacterFragment(get()) }
121123
fragment { GameMasterFragment(get()) }
122124
fragment { NavHostFragment() }
123-
fragment { PartyListFragment(get()) }
125+
fragment { PartyListFragment() }
124126
fragment { CharacterEditFragment(get()) }
125127
fragment { CharacterMiscFragment() }
126128
fragment { CharacterStatsFragment() }

app/src/main/java/cz/muni/fi/rpg/model/domain/party/Party.kt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ data class Party(
1111
private var name: String,
1212
val gameMasterId: String?,
1313
val users: Set<String>,
14+
private var archived: Boolean = false,
1415
private var ambitions: Ambitions = Ambitions("", "")
1516
) : Parcelable {
1617
companion object {
@@ -55,6 +56,12 @@ data class Party(
5556
return name;
5657
}
5758

59+
fun archive() {
60+
archived = true
61+
}
62+
63+
fun isArchived() = archived
64+
5865
fun getAmbitions() = ambitions
5966

6067
fun getInvitation() = Invitation(id, name, accessCode)

app/src/main/java/cz/muni/fi/rpg/model/firestore/QueryLiveData.kt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@ import kotlinx.coroutines.withContext
1010

1111
internal class QueryLiveData<T: Any>(
1212
private val query: Query,
13-
private val snapshotParser: AggregateMapper<T>
13+
private val snapshotParser: AggregateMapper<T>,
14+
private val filter: (item: T) -> Boolean = { true }
1415
) : MutableLiveData<List<T>>(), CoroutineScope by CoroutineScope(Dispatchers.IO) {
1516
private var listener: ListenerRegistration? = null
1617

@@ -24,6 +25,7 @@ internal class QueryLiveData<T: Any>(
2425
val items = snapshot
2526
.asIterable()
2627
.map(snapshotParser::fromDocumentSnapshot)
28+
.filter(filter)
2729

2830
withContext(Dispatchers.Main) { value = items }
2931
}

app/src/main/java/cz/muni/fi/rpg/model/firestore/repositories/FirestorePartyRepository.kt

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -63,9 +63,7 @@ internal class FirestorePartyRepository(
6363

6464
override fun forUser(userId: String): LiveData<List<Party>> =
6565
QueryLiveData(
66-
parties.whereArrayContains(
67-
"users",
68-
userId
69-
), mapper
70-
)
66+
parties.whereArrayContains("users", userId),
67+
mapper
68+
) { ! it.isArchived() }
7169
}

app/src/main/java/cz/muni/fi/rpg/ui/character/CharacterFragment.kt

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,21 +11,21 @@ import androidx.navigation.fragment.navArgs
1111
import com.google.android.material.tabs.TabLayoutMediator
1212
import cz.muni.fi.rpg.R
1313
import cz.muni.fi.rpg.model.domain.character.CharacterNotFound
14-
import cz.muni.fi.rpg.model.right
1514
import cz.muni.fi.rpg.ui.character.skills.CharacterSkillsFragment
1615
import cz.muni.fi.rpg.ui.common.AdManager
17-
import cz.muni.fi.rpg.ui.common.BaseFragment
16+
import cz.muni.fi.rpg.ui.common.PartyScopedFragment
1817
import cz.muni.fi.rpg.ui.common.StaticFragmentsViewPagerAdapter
1918
import cz.muni.fi.rpg.viewModels.CharacterViewModel
2019
import kotlinx.android.synthetic.main.fragment_character.*
2120
import org.koin.android.viewmodel.ext.android.viewModel
2221
import org.koin.core.parameter.parametersOf
2322
import timber.log.Timber
23+
import java.util.*
2424

2525

2626
class CharacterFragment(
2727
private val adManager: AdManager
28-
) : BaseFragment(R.layout.fragment_character) {
28+
) : PartyScopedFragment(R.layout.fragment_character) {
2929

3030
private val args: CharacterFragmentArgs by navArgs()
3131
private val viewModel: CharacterViewModel by viewModel { parametersOf(args.characterId) }
@@ -45,8 +45,7 @@ class CharacterFragment(
4545
}
4646
}
4747

48-
viewModel.party.right()
49-
.observe(viewLifecycleOwner) { setSubtitle(it.getName()) }
48+
party.observe(viewLifecycleOwner) { setSubtitle(it.getName()) }
5049

5150
pager.adapter = StaticFragmentsViewPagerAdapter(
5251
this,
@@ -82,6 +81,8 @@ class CharacterFragment(
8281
adManager.initializeUnit(characterAdView)
8382
}
8483

84+
override fun getPartyId(): UUID = args.characterId.partyId
85+
8586
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
8687
super.onCreateOptionsMenu(menu, inflater)
8788

app/src/main/java/cz/muni/fi/rpg/ui/character/edit/CharacterEditFragment.kt

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,18 +11,19 @@ import cz.muni.fi.rpg.R
1111
import cz.muni.fi.rpg.model.domain.character.CharacterRepository
1212
import cz.muni.fi.rpg.ui.characterCreation.CharacterInfoFormFragment
1313
import cz.muni.fi.rpg.ui.characterCreation.CharacterStatsFormFragment
14-
import cz.muni.fi.rpg.ui.common.BaseFragment
14+
import cz.muni.fi.rpg.ui.common.PartyScopedFragment
1515
import cz.muni.fi.rpg.ui.common.forms.Form
1616
import kotlinx.android.synthetic.main.fragment_character_edit.*
1717
import kotlinx.android.synthetic.main.fragment_character_edit.maxWoundsInput
1818
import kotlinx.coroutines.CoroutineScope
1919
import kotlinx.coroutines.Dispatchers
2020
import kotlinx.coroutines.launch
2121
import kotlinx.coroutines.withContext
22+
import java.util.*
2223

2324
class CharacterEditFragment(
2425
private val characters: CharacterRepository
25-
) : BaseFragment(R.layout.fragment_character_edit),
26+
) : PartyScopedFragment(R.layout.fragment_character_edit),
2627
CoroutineScope by CoroutineScope(Dispatchers.Default) {
2728

2829
private val args: CharacterEditFragmentArgs by navArgs()
@@ -69,6 +70,8 @@ class CharacterEditFragment(
6970
}
7071
}
7172

73+
override fun getPartyId(): UUID = args.characterId.partyId
74+
7275
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
7376
super.onCreateOptionsMenu(menu, inflater)
7477

app/src/main/java/cz/muni/fi/rpg/ui/characterCreation/CharacterCreationFragment.kt

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
package cz.muni.fi.rpg.ui.characterCreation
22

3-
import android.content.Context
43
import android.os.Bundle
54
import android.view.View
65
import android.widget.Toast
@@ -12,7 +11,7 @@ import com.google.firebase.analytics.ktx.logEvent
1211
import com.google.firebase.ktx.Firebase
1312
import cz.muni.fi.rpg.R
1413
import cz.muni.fi.rpg.model.domain.character.*
15-
import cz.muni.fi.rpg.ui.common.BaseFragment
14+
import cz.muni.fi.rpg.ui.common.PartyScopedFragment
1615
import cz.muni.fi.rpg.ui.common.StaticFragmentsViewPagerAdapter
1716
import cz.muni.fi.rpg.viewModels.AuthenticationViewModel
1817
import kotlinx.android.synthetic.main.fragment_character_creation.*
@@ -22,10 +21,11 @@ import kotlinx.coroutines.launch
2221
import kotlinx.coroutines.withContext
2322
import org.koin.android.viewmodel.ext.android.sharedViewModel
2423
import timber.log.Timber
24+
import java.util.*
2525

2626
class CharacterCreationFragment(
2727
private val characters: CharacterRepository
28-
) : BaseFragment(R.layout.fragment_character_creation),
28+
) : PartyScopedFragment(R.layout.fragment_character_creation),
2929
CoroutineScope by CoroutineScope(Dispatchers.Default) {
3030

3131
private val args: CharacterCreationFragmentArgs by navArgs()
@@ -131,6 +131,8 @@ class CharacterCreationFragment(
131131
}
132132
}
133133

134+
override fun getPartyId(): UUID = args.partyId
135+
134136
private fun currentStep(): Fragment? {
135137
return childFragmentManager.findFragmentByTag("f$currentFragmentIndex")
136138
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
package cz.muni.fi.rpg.ui.common
2+
3+
import android.os.Bundle
4+
import android.view.View
5+
import android.widget.Toast
6+
import androidx.annotation.LayoutRes
7+
import androidx.lifecycle.LiveData
8+
import androidx.lifecycle.observe
9+
import androidx.navigation.fragment.findNavController
10+
import arrow.core.Either
11+
import cz.muni.fi.rpg.R
12+
import cz.muni.fi.rpg.model.domain.party.Party
13+
import cz.muni.fi.rpg.model.domain.party.PartyNotFound
14+
import cz.muni.fi.rpg.model.right
15+
import cz.muni.fi.rpg.viewModels.PartyViewModel
16+
import org.koin.android.viewmodel.ext.android.viewModel
17+
import org.koin.core.parameter.parametersOf
18+
import timber.log.Timber
19+
import java.util.*
20+
21+
abstract class PartyScopedFragment(@LayoutRes contentLayoutId: Int) :
22+
BaseFragment(contentLayoutId) {
23+
24+
private val viewModel: PartyViewModel by viewModel { parametersOf(getPartyId()) }
25+
26+
protected val party: LiveData<Party> by lazy { viewModel.party.right() }
27+
28+
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
29+
super.onCreate(savedInstanceState)
30+
31+
viewModel.party.observe(viewLifecycleOwner) {
32+
if (!isAvailable(it)) {
33+
Timber.d("Party does not exist or is archived: $it")
34+
Toast.makeText(requireContext(), R.string.error_party_not_found, Toast.LENGTH_LONG)
35+
.show()
36+
findNavController().popBackStack(R.id.nav_party_list, false)
37+
}
38+
}
39+
}
40+
41+
protected abstract fun getPartyId(): UUID
42+
43+
private fun isAvailable(partyOrError: Either<PartyNotFound, Party>): Boolean {
44+
return partyOrError.fold({ false }, { !it.isArchived() })
45+
}
46+
}

app/src/main/java/cz/muni/fi/rpg/ui/gameMaster/GameMasterFragment.kt

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,37 +9,33 @@ import androidx.lifecycle.observe
99
import androidx.navigation.fragment.navArgs
1010
import com.google.android.material.tabs.TabLayoutMediator
1111
import cz.muni.fi.rpg.R
12-
import cz.muni.fi.rpg.model.right
1312
import cz.muni.fi.rpg.ui.common.AdManager
14-
import cz.muni.fi.rpg.ui.common.BaseFragment
13+
import cz.muni.fi.rpg.ui.common.PartyScopedFragment
1514
import cz.muni.fi.rpg.ui.common.StaticFragmentsViewPagerAdapter
1615
import cz.muni.fi.rpg.ui.gameMaster.encounters.EncountersFragment
17-
import cz.muni.fi.rpg.viewModels.GameMasterViewModel
18-
import kotlinx.android.synthetic.main.fragment_character.*
1916
import kotlinx.android.synthetic.main.fragment_character.pager
2017
import kotlinx.android.synthetic.main.fragment_character.tabLayout
2118
import kotlinx.android.synthetic.main.fragment_game_master.*
2219
import kotlinx.android.synthetic.main.fragment_game_master.mainView
2320
import kotlinx.android.synthetic.main.fragment_game_master.progress
24-
import org.koin.core.parameter.parametersOf
25-
import org.koin.android.viewmodel.ext.android.viewModel
2621
import timber.log.Timber
22+
import java.util.*
2723

2824
class GameMasterFragment(
2925
private val adManager: AdManager
30-
) : BaseFragment(R.layout.fragment_game_master) {
26+
) : PartyScopedFragment(R.layout.fragment_game_master) {
3127

3228
private val args: GameMasterFragmentArgs by navArgs()
3329

34-
private val viewModel: GameMasterViewModel by viewModel { parametersOf(args.partyId) }
35-
3630
private lateinit var partyName: String
3731

32+
override fun getPartyId(): UUID = args.partyId
33+
3834
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
3935
super.onViewCreated(view, savedInstanceState)
4036
Timber.d("Created view for GameMasterFragment (partyId = ${args.partyId}")
4137

42-
viewModel.party.right().observe(viewLifecycleOwner) { party ->
38+
party.observe(viewLifecycleOwner) { party ->
4339
mainView.visibility = View.VISIBLE
4440
progress.visibility = View.GONE
4541
setTitle(party.getName())

app/src/main/java/cz/muni/fi/rpg/ui/gameMaster/encounters/CombatantFragment.kt

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import cz.muni.fi.rpg.model.domain.character.Stats
1414
import cz.muni.fi.rpg.model.domain.encounter.Combatant
1515
import cz.muni.fi.rpg.model.domain.encounter.CombatantNotFound
1616
import cz.muni.fi.rpg.model.domain.encounter.Wounds
17-
import cz.muni.fi.rpg.ui.common.BaseFragment
17+
import cz.muni.fi.rpg.ui.common.PartyScopedFragment
1818
import cz.muni.fi.rpg.ui.common.forms.Form
1919
import cz.muni.fi.rpg.ui.common.toggleVisibility
2020
import cz.muni.fi.rpg.viewModels.EncounterDetailViewModel
@@ -25,8 +25,9 @@ import kotlinx.coroutines.launch
2525
import kotlinx.coroutines.withContext
2626
import org.koin.android.viewmodel.ext.android.viewModel
2727
import org.koin.core.parameter.parametersOf
28+
import java.util.*
2829

29-
class CombatantFragment : BaseFragment(R.layout.fragment_combatant),
30+
class CombatantFragment : PartyScopedFragment(R.layout.fragment_combatant),
3031
CoroutineScope by CoroutineScope(Dispatchers.Default) {
3132

3233
private val args: CombatantFragmentArgs by navArgs()
@@ -35,6 +36,8 @@ class CombatantFragment : BaseFragment(R.layout.fragment_combatant),
3536

3637
private lateinit var form: Form
3738

39+
override fun getPartyId(): UUID = args.encounterId.partyId
40+
3841
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
3942
super.onViewCreated(view, savedInstanceState)
4043

0 commit comments

Comments
 (0)