This commit is contained in:
Phillip Thelen 2021-10-01 18:49:29 +02:00
parent bdb7fd46df
commit 5bbba6552d
2 changed files with 117 additions and 53 deletions

View file

@ -33,7 +33,11 @@ class NavigationDrawerAdapter(tintColor: Int, backgroundTintColor: Int) : Recycl
var backgroundTintColor: Int = backgroundTintColor
set(value) {
field = value
notifyDataSetChanged()
for (item in items) {
if (item.isHeader) {
notifyItemChanged(getVisibleItemPosition(item.identifier))
}
}
}
internal val items: MutableList<HabiticaDrawerItem> = ArrayList()
@ -56,11 +60,18 @@ class NavigationDrawerAdapter(tintColor: Int, backgroundTintColor: Int) : Recycl
private fun getItemPosition(identifier: String): Int =
items.indexOfFirst { it.identifier == identifier }
private fun getVisibleItemPosition(identifier: String): Int =
items.filter { it.isVisible }.indexOfFirst { it.identifier == identifier }
fun updateItem(item: HabiticaDrawerItem) {
val position = getItemPosition(item.identifier)
items[position] = item
notifyDataSetChanged()
if (position == -1) {
items.add(item)
notifyItemInserted(items.size - 1)
} else {
items[position] = item
notifyItemChanged(getVisibleItemPosition(item.identifier))
}
}
fun updateItems(newItems: List<HabiticaDrawerItem>) {
@ -83,14 +94,16 @@ class NavigationDrawerAdapter(tintColor: Int, backgroundTintColor: Int) : Recycl
if (teamHeaderIndex != -1 && nextHeaderIndex != -1) {
for (x in nextHeaderIndex - 1 downTo teamHeaderIndex + 1) {
items.removeAt(x)
notifyItemRemoved(x)
}
for ((index, team) in teams.withIndex()) {
val item = HabiticaDrawerItem(R.id.teamBoardFragment, team.id, team.summary)
item.bundle = bundleOf(Pair("teamID", team.id))
items.add(teamHeaderIndex + index + 1, item)
val newIndex = teamHeaderIndex + index + 1
items.add(newIndex, item)
notifyItemInserted(newIndex)
}
}
notifyDataSetChanged()
}
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
@ -99,7 +112,6 @@ class NavigationDrawerAdapter(tintColor: Int, backgroundTintColor: Int) : Recycl
getItemViewType(position) == 0 -> {
val itemHolder = holder as? DrawerItemViewHolder
itemHolder?.tintColor = tintColor
itemHolder?.backgroundTintColor = backgroundTintColor
itemHolder?.bind(drawerItem, drawerItem.transitionId == selectedItem)
itemHolder?.itemView?.setOnClickListener { itemSelectedEvents.onNext(drawerItem) }
}
@ -168,7 +180,6 @@ class NavigationDrawerAdapter(tintColor: Int, backgroundTintColor: Int) : Recycl
class DrawerItemViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
var tintColor: Int = 0
var backgroundTintColor: Int = 0
private val titleTextView: TextView? = itemView.findViewById(R.id.titleTextView)
private val pillView: TextView? = itemView.findViewById(R.id.pillView)

View file

@ -49,10 +49,8 @@ import java.util.*
import java.util.concurrent.TimeUnit
import javax.inject.Inject
import kotlin.collections.ArrayList
import kotlin.time.Duration
import kotlin.time.ExperimentalTime
import kotlin.time.hours
import kotlin.time.minutes
import kotlin.time.seconds
class NavigationDrawerFragment : DialogFragment() {
@ -110,22 +108,22 @@ class NavigationDrawerFragment : DialogFragment() {
adapter.backgroundTintColor = it.getThemeColor(R.attr.colorPrimary)
}
}
adapter.items.filter { it.identifier == SIDEBAR_TAVERN }.forEach {
it.subtitle = null
getItemWithIdentifier(SIDEBAR_TAVERN)?.let { tavern ->
tavern.subtitle = context?.getString(R.string.active_world_boss)
adapter.updateItem(tavern)
}
return
}
binding?.questMenuView?.visibility = View.VISIBLE
binding?.menuHeaderView?.setBackgroundColor(questContent.colors?.darkColor ?: 0)
binding?.questMenuView?.configure(quest)
binding?.questMenuView?.configure(questContent)
adapter.tintColor = questContent.colors?.extraLightColor ?: 0
adapter.backgroundTintColor = questContent.colors?.darkColor ?: 0
binding?.messagesBadge?.visibility = View.GONE
binding?.settingsBadge?.visibility = View.GONE
binding?.notificationsBadge?.visibility = View.GONE
questContent.colors?.let { colors ->
binding?.menuHeaderView?.setBackgroundColor(colors.darkColor)
adapter.tintColor = colors.extraLightColor
adapter.backgroundTintColor = colors.darkColor
}
binding?.questMenuView?.setBackgroundColor(context?.getThemeColor(R.attr.colorPrimaryDark) ?: 0)
/* Reenable this once the boss art can be displayed correctly.
@ -135,18 +133,18 @@ class NavigationDrawerFragment : DialogFragment() {
} else {
questMenuView.showBossArt()
}*/
binding?.questMenuView?.hideBossArt()
adapter.items.filter { it.identifier == SIDEBAR_TAVERN }.forEach {
it.subtitle = context?.getString(R.string.active_world_boss)
}
adapter.notifyDataSetChanged()
//binding?.questMenuView?.hideBossArt()
/*getItemWithIdentifier(SIDEBAR_TAVERN)?.let { tavern ->
tavern.subtitle = context?.getString(R.string.active_world_boss)
adapter.updateItem(tavern)
}*/
binding?.questMenuView?.setOnClickListener {
val context = this.context
setSelection(R.id.partyFragment)
/*val context = this.context
if (context != null) {
TavernDetailFragment.showWorldBossInfoDialog(context, questContent)
}
}*/
}
}
@ -174,7 +172,7 @@ class NavigationDrawerFragment : DialogFragment() {
savedInstanceState: Bundle?
): View? = inflater.inflate(R.layout.drawer_main, container, false) as? ViewGroup
private var seasonalShopJob: Job? = null
private var updatingJobs = mutableMapOf<String, Job>()
@OptIn(ExperimentalTime::class)
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
@ -200,7 +198,6 @@ class NavigationDrawerFragment : DialogFragment() {
putBoolean("hide$it", true)
}
updatePromo()
adapter.notifyDataSetChanged()
},
RxErrorHandler.handleEmptyError()
)
@ -211,14 +208,25 @@ class NavigationDrawerFragment : DialogFragment() {
.doOnNext { quest = it.quest }
.filter { it.hasActiveQuest }
.flatMapMaybe { inventoryRepository.getQuestContent(it.quest?.key ?: "").firstElement() }
.subscribe(
{
.subscribe({
questContent = it
},
RxErrorHandler.handleEmptyError()
)
)
subscriptions?.add(
socialRepository.getGroup(Group.TAVERN_ID)
.doOnNext { quest = it.quest }
.filter { it.hasActiveQuest }
.flatMapMaybe { inventoryRepository.getQuestContent(it.quest?.key ?: "").firstElement() }
.subscribe({
questContent = it
},
RxErrorHandler.handleEmptyError()
)
)
subscriptions?.add(
Flowable.combineLatest(
contentRepository.getWorldState(), inventoryRepository.getAvailableLimitedItems(),
@ -227,15 +235,14 @@ class NavigationDrawerFragment : DialogFragment() {
}
).subscribe(
{ pair ->
updateSeasonalMenuEntries(pair.first, pair.second)
seasonalShopJob?.cancel()
seasonalShopJob = lifecycleScope.launch(Dispatchers.Main) {
val gearEvent = pair.first.events.firstOrNull { it.gear }
while (gearEvent?.end?.after(Date()) == true || pair.second.isNotEmpty()) {
updateSeasonalMenuEntries(pair.first, pair.second)
val diff = (gearEvent?.end?.time ?: 0) - Date().time
delay(if (diff < (1.hours.inMilliseconds)) 1.seconds else 1.minutes)
}
val gearEvent = pair.first.events.firstOrNull { it.gear }
createUpdatingJob("seasonal", {
gearEvent?.end?.after(Date()) == true || pair.second.isNotEmpty()
}, {
val diff = (gearEvent?.end?.time ?: 0) - Date().time
if (diff < (Duration.hours(1).inWholeMilliseconds)) Duration.seconds(1) else Duration.minutes(1)
}) {
updateSeasonalMenuEntries(pair.first, pair.second)
}
},
RxErrorHandler.handleEmptyError()
@ -259,9 +266,20 @@ class NavigationDrawerFragment : DialogFragment() {
}
subscriptions?.add(
userRepository.getUser().subscribe(
{
userRepository.getUser()
.doOnNext {
updateUser(it)
}
.flatMap { socialRepository.getGroup(it.party?.id ?: "") }
.filter { it.quest?.key != null }
.map {
quest = it.quest
it.quest?.key ?: ""
}
.flatMapMaybe { inventoryRepository.getQuestContent(it).firstElement() }
.subscribe(
{
questContent = it
},
RxErrorHandler.handleEmptyError()
)
@ -272,6 +290,25 @@ class NavigationDrawerFragment : DialogFragment() {
binding?.notificationsButtonWrapper?.setOnClickListener { startNotificationsActivity() }
}
@OptIn(ExperimentalTime::class)
private fun createUpdatingJob(
key: String,
endingCondition: () -> Boolean,
delayFunc: () -> Duration,
function: () -> Unit
) {
function()
if (updatingJobs[key]?.isActive == true) {
updatingJobs[key]?.cancel()
}
updatingJobs[key] = lifecycleScope.launch(Dispatchers.Main) {
while (endingCondition()) {
function()
delay(delayFunc())
}
}
}
private fun updateSeasonalMenuEntries(worldState: WorldState, items: List<Item>) {
val market = getItemWithIdentifier(SIDEBAR_SHOPS_MARKET) ?: return
if (items.isNotEmpty() && items.firstOrNull()?.event?.end?.after(Date()) == true) {
@ -281,6 +318,7 @@ class NavigationDrawerFragment : DialogFragment() {
market.pillText = null
market.subtitle = null
}
adapter.updateItem(market)
val shop = getItemWithIdentifier(SIDEBAR_SHOPS_SEASONAL) ?: return
shop.pillText = context?.getString(R.string.open)
@ -291,7 +329,7 @@ class NavigationDrawerFragment : DialogFragment() {
} else {
shop.isVisible = false
}
adapter.notifyDataSetChanged()
adapter.updateItem(shop)
}
private fun updateUser(user: User) {
@ -399,6 +437,8 @@ class NavigationDrawerFragment : DialogFragment() {
socialRepository.close()
inventoryRepository.close()
userRepository.close()
updatingJobs.forEach { it.value.cancel() }
updatingJobs.clear()
super.onDestroy()
}
@ -606,24 +646,38 @@ class NavigationDrawerFragment : DialogFragment() {
}
}
@OptIn(ExperimentalTime::class)
fun updatePromo() {
activePromo = configManager.activePromo()
val promoItem = getItemWithIdentifier(SIDEBAR_PROMO) ?: return
if (activePromo != null && !sharedPreferences.getBoolean("hide${activePromo?.identifier}", false)) {
promoItem.isVisible = true
adapter.activePromo = activePromo
activePromo?.let { activePromo ->
if (sharedPreferences.getBoolean("hide${activePromo.identifier}", false)) {
promoItem.isVisible = true
adapter.activePromo = activePromo
} else {
promoItem.isVisible = false
}
var promotedItem: HabiticaDrawerItem? = null
if (activePromo?.promoType == PromoType.GEMS_AMOUNT || activePromo?.promoType == PromoType.GEMS_PRICE) {
if (activePromo.promoType == PromoType.GEMS_AMOUNT || activePromo.promoType == PromoType.GEMS_PRICE) {
promotedItem = getItemWithIdentifier(SIDEBAR_GEMS)
}
if (activePromo?.promoType == PromoType.SUBSCRIPTION) {
if (activePromo.promoType == PromoType.SUBSCRIPTION) {
promotedItem = getItemWithIdentifier(SIDEBAR_SUBSCRIPTION)
}
promotedItem?.pillText = context?.getString(R.string.sale)
promotedItem?.pillBackground = context?.let { activePromo?.pillBackgroundDrawable(it) }
promotedItem?.let { updateItem(it) }
} else {
if (promotedItem == null) return@let
promotedItem.pillText = context?.getString(R.string.sale)
promotedItem.pillBackground = context?.let { activePromo.pillBackgroundDrawable(it) }
createUpdatingJob(activePromo.promoType.name, {
activePromo.endDate.after(Date())
}, {
val diff = activePromo.endDate.time - Date().time
if (diff < (Duration.hours(1).inWholeMilliseconds)) Duration.seconds(1) else Duration.minutes(1)
}) {
promotedItem.subtitle = context?.getString(R.string.open_for, activePromo.endDate.getShortRemainingString())
updateItem(promotedItem)
}
} ?: run {
promoItem.isVisible = false
}
updateItem(promoItem)
@ -653,7 +707,6 @@ class NavigationDrawerFragment : DialogFragment() {
const val SIDEBAR_GEMS = "gems"
const val SIDEBAR_SUBSCRIPTION = "subscription"
const val SIDEBAR_SUBSCRIPTION_PROMO = "subscriptionpromo"
const val SIDEBAR_G1G1_PROMO = "g1g1promo"
const val SIDEBAR_PROMO = "promo"
const val SIDEBAR_ADVENTURE_GUIDE = "adventureguide"
const val SIDEBAR_ABOUT_HEADER = "about_header"