Remove obsolete code

This commit is contained in:
Phillip Thelen 2023-08-08 16:40:00 +02:00
parent a9bc1e08df
commit 4cefbd4d8a
25 changed files with 24 additions and 1005 deletions

View file

@ -95,7 +95,7 @@ dependencies {
implementation 'com.google.firebase:firebase-messaging-ktx'
implementation 'com.google.firebase:firebase-config-ktx'
implementation 'com.google.firebase:firebase-perf-ktx'
implementation 'com.google.android.gms:play-services-ads:22.0.0'
implementation 'com.google.android.gms:play-services-ads:22.2.0'
implementation "com.google.android.gms:play-services-auth:$play_auth_version"
implementation 'com.google.android.flexbox:flexbox:3.0.0'
implementation "com.google.android.gms:play-services-wearable:$play_wearables_version"
@ -106,7 +106,7 @@ dependencies {
implementation "androidx.lifecycle:lifecycle-common-java8:$lifecycle_version"
implementation "androidx.navigation:navigation-fragment-ktx:$navigation_version"
implementation "androidx.navigation:navigation-ui-ktx:$navigation_version"
implementation "androidx.fragment:fragment-ktx:1.5.7"
implementation "androidx.fragment:fragment-ktx:1.6.1"
implementation "androidx.paging:paging-runtime-ktx:3.1.1"
implementation "androidx.paging:paging-compose:1.0.0-alpha19"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutines_version"
@ -168,7 +168,7 @@ android {
}
composeOptions {
kotlinCompilerExtensionVersion = "1.4.6"
kotlinCompilerExtensionVersion = "1.4.7"
}
signingConfigs {

View file

@ -1,113 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.core.widget.NestedScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorContentBackground">
<include layout="@layout/shop_header"
android:id="@+id/shop_header"
android:layout_marginBottom="@dimen/spacing_large"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:background="@color/window_background"/>
<com.habitrpg.android.habitica.ui.views.CollapsibleSectionView
android:id="@+id/worldBossSection"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:title="@string/world_boss"
app:identifier="tavernWorldBoss"
app:hasAdditionalInfo="true"
android:visibility="gone">
<com.habitrpg.android.habitica.ui.views.social.QuestProgressView
android:id="@+id/questProgressView"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</com.habitrpg.android.habitica.ui.views.CollapsibleSectionView>
<com.habitrpg.android.habitica.ui.views.CollapsibleSectionView
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:title="@string/check_into_inn"
app:identifier="tavernInn">
<Button
android:id="@+id/innButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="@string/tavern_inn_rest"
style="@style/HabiticaButton.Yellow"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/inn_description"
android:layout_marginTop="@dimen/spacing_large"
android:background="@drawable/layout_rounded_bg_window"
android:padding="@dimen/spacing_large"/>
</com.habitrpg.android.habitica.ui.views.CollapsibleSectionView>
<com.habitrpg.android.habitica.ui.views.CollapsibleSectionView
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:title="@string/community_guidelines"
app:identifier="tavernGuidelines">
<com.google.android.material.button.MaterialButton
android:id="@+id/guidelinesButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="@string/view_community_guidelines"
style="@style/HabiticaButton.Gray"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/guidelines_description"
android:layout_marginTop="@dimen/spacing_large"
android:background="@drawable/layout_rounded_bg_window"
android:padding="@dimen/spacing_large"/>
</com.habitrpg.android.habitica.ui.views.CollapsibleSectionView>
<com.habitrpg.android.habitica.ui.views.CollapsibleSectionView
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:title="@string/helpful_links"
app:identifier="tavernLinks">
<Button
android:id="@+id/faqButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="@string/view_faq"
style="@style/HabiticaButton.Gray"/>
<Button
android:id="@+id/reportButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="@string/report_bug"
style="@style/HabiticaButton.Gray"
android:layout_marginTop="@dimen/spacing_large"/>
</com.habitrpg.android.habitica.ui.views.CollapsibleSectionView>
<com.habitrpg.android.habitica.ui.views.CollapsibleSectionView
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:title="@string/staff_moderators"
app:identifier="tavernModerators"
android:visibility="gone">
</com.habitrpg.android.habitica.ui.views.CollapsibleSectionView>
<com.habitrpg.android.habitica.ui.views.CollapsibleSectionView
android:id="@+id/playerTiersView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:title="@string/player_tiers"
app:identifier="tavernTiers">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/tiers_descriptions"
android:background="@drawable/layout_rounded_bg_window"
android:padding="@dimen/spacing_large"/>
</com.habitrpg.android.habitica.ui.views.CollapsibleSectionView>
</LinearLayout>
</androidx.core.widget.NestedScrollView>

View file

@ -89,24 +89,6 @@
android:label="@string/stats">
<deepLink app:uri="habitica.com/user/stats" />
</fragment>
<fragment
android:id="@+id/tavernFragment"
android:name="com.habitrpg.android.habitica.ui.fragments.social.TavernFragment"
android:label="@string/sidebar_tavern">
<deepLink app:uri="habitica.com/tavern" />
</fragment>
<fragment
android:id="@+id/guildOverviewFragment"
android:name="com.habitrpg.android.habitica.ui.fragments.social.guilds.GuildOverviewFragment"
android:label="@string/sidebar_guilds" >
<deepLink app:uri="habitica.com/groups/myGuilds" />
<action
android:id="@+id/openGuildDetail"
app:destination="@id/guildFragment" />
<action
android:id="@+id/openPublicGuilds"
app:destination="@id/publicGuildsFragment" />
</fragment>
<fragment
android:id="@+id/challengesOverviewFragment"
android:name="com.habitrpg.android.habitica.ui.fragments.social.challenges.ChallengesOverviewFragment"
@ -315,14 +297,6 @@
app:argType="integer"
android:defaultValue="0"/>
</fragment>
<fragment
android:id="@+id/publicGuildsFragment"
android:name="com.habitrpg.android.habitica.ui.fragments.social.guilds.GuildListFragment"
android:label="@string/public_guilds" >
<action
android:id="@+id/openGuildDetail"
app:destination="@id/guildFragment" />
</fragment>
<fragment
android:id="@+id/avatarCustomizationFragment"
android:name="com.habitrpg.android.habitica.ui.fragments.inventory.customization.AvatarCustomizationFragment"

View file

@ -121,11 +121,6 @@
<key>enableSpellAds</key>
<value>false</value>
</entry>
<entry>
<key>hideTavern</key>
<value>false</value>
</entry>
<entry>
<key>hideGuilds</key>
<value>false</value>
@ -135,4 +130,4 @@
<value>false</value>
</entry>
</defaultsMap>
<!-- END xml_defaults -->
<!-- END xml_defaults -->

View file

@ -56,7 +56,6 @@ internal class NavigationDrawerFragmentTest : FragmentTestCase<NavigationDrawerF
childWith<MainItem> { withDescendant { withText("Purchase Gems") } }.isVisible()
childWith<MainItem> { withDescendant { withText("Subscription") } }.isVisible()
childWith<MainItem> { withDescendant { withText("Party") } }.isVisible()
childWith<MainItem> { withDescendant { withText("Tavern") } }.isVisible()
childWith<MainItem> { withDescendant { withText("Support") } }.isVisible()
}
}

View file

@ -15,8 +15,6 @@ import io.realm.RealmResults
import kotlinx.coroutines.flow.Flow
interface SocialRepository : BaseRepository {
fun getPublicGuilds(): Flow<List<Group>>
fun getUserGroups(type: String?): Flow<List<Group>>
suspend fun retrieveGroupChat(groupId: String): List<ChatMessage>?
fun getGroupChat(groupId: String): Flow<List<ChatMessage>>
@ -64,9 +62,6 @@ interface SocialRepository : BaseRepository {
leaderCreateChallenge: Boolean?
): Group?
suspend fun retrieveGroups(type: String): List<Group>?
fun getGroups(type: String): Flow<List<Group>>
fun getInboxMessages(replyToUserID: String?): Flow<RealmResults<ChatMessage>>
suspend fun retrieveInboxMessages(uuid: String, page: Int): List<ChatMessage>?
suspend fun retrieveInboxConversations(): List<InboxConversation>?

View file

@ -201,22 +201,6 @@ class SocialRepositoryImpl(
return apiClient.updateGroup(copiedGroup.id, copiedGroup)
}
override suspend fun retrieveGroups(type: String): List<Group>? {
val groups = apiClient.listGroups(type) ?: return null
if ("guilds" == type) {
val memberships = groups.map {
GroupMembership(currentUserID, it.id)
}
localRepository.saveGroupMemberships(currentUserID, memberships)
}
localRepository.save(groups)
return groups
}
override fun getGroups(type: String) = localRepository.getGroups(type)
override fun getPublicGuilds() = localRepository.getPublicGuilds()
override fun getInboxConversations() = authenticationHandler.userIDFlow.flatMapLatest { localRepository.getInboxConversation(it) }
override fun getInboxMessages(replyToUserID: String?) = authenticationHandler.userIDFlow.flatMapLatest { localRepository.getInboxMessages(it, replyToUserID) }

View file

@ -10,10 +10,7 @@ import io.realm.RealmResults
import kotlinx.coroutines.flow.Flow
interface SocialLocalRepository : BaseLocalRepository {
fun getPublicGuilds(): Flow<List<Group>>
fun getUserGroups(userID: String, type: String?): Flow<List<Group>>
fun getGroups(type: String): Flow<List<Group>>
fun getGroup(id: String): Flow<Group?>
fun saveGroup(group: Group)

View file

@ -47,21 +47,6 @@ open class RealmContentLocalRepository(realm: Realm) : RealmBaseLocalRepository(
}
override fun saveWorldState(worldState: WorldState) {
val tavern = getUnmanagedCopy(
realm.where(Group::class.java)
.equalTo("id", Group.TAVERN_ID)
.findFirst() ?: Group()
)
if (!tavern.isManaged) {
tavern.id = Group.TAVERN_ID
}
if (tavern.quest == null) {
tavern.quest = Quest()
}
tavern.quest?.active = worldState.worldBossActive
tavern.quest?.key = worldState.worldBossKey
tavern.quest?.progress = worldState.progress
save(tavern)
save(worldState)
}
}

View file

@ -128,15 +128,6 @@ class RealmSocialLocalRepository(realm: Realm) : RealmBaseLocalRepository(realm)
}
}
override fun getPublicGuilds() = realm.where(Group::class.java)
.equalTo("type", "guild")
.equalTo("privacy", "public")
.notEqualTo("id", Group.TAVERN_ID)
.sort("memberCount", Sort.DESCENDING)
.findAll()
.toFlow()
.filter { it.isLoaded }
@OptIn(ExperimentalCoroutinesApi::class)
override fun getUserGroups(userID: String, type: String?) = realm.where(GroupMembership::class.java)
.equalTo("userID", userID)
@ -146,7 +137,6 @@ class RealmSocialLocalRepository(realm: Realm) : RealmBaseLocalRepository(realm)
.flatMapLatest { memberships ->
realm.where(Group::class.java)
.equalTo("type", type ?: "guild")
.notEqualTo("id", Group.TAVERN_ID)
.`in`(
"id",
memberships.map {
@ -158,14 +148,6 @@ class RealmSocialLocalRepository(realm: Realm) : RealmBaseLocalRepository(realm)
.toFlow()
}
override fun getGroups(type: String): Flow<List<Group>> {
return realm.where(Group::class.java)
.equalTo("type", type)
.findAll()
.toFlow()
.filter { it.isLoaded }
}
override fun getGroup(id: String): Flow<Group?> {
return realm.where(Group::class.java)
.equalTo("id", id)

View file

@ -159,12 +159,6 @@ class AppConfigManager(contentRepository: ContentRepository?) : com.habitrpg.com
return remoteConfig.getBoolean("enableNewArmoire")
}
fun hideTavern(): Boolean {
return remoteConfig.getBoolean("hideTavern")
}
fun hideGuilds(): Boolean {
return remoteConfig.getBoolean("hideGuilds")
}
fun hideChallenges(): Boolean {
return remoteConfig.getBoolean("hideChallenges")
}

View file

@ -64,11 +64,7 @@ class NotificationOpenHandler {
}
private fun openGuildDetailScreen(groupID: String?) {
if (groupID?.isNotEmpty() != true) {
MainNavigationController.navigate(R.id.guildOverviewFragment)
} else {
MainNavigationController.navigate(R.id.guildFragment, bundleOf("groupID" to groupID))
}
MainNavigationController.navigate(R.id.guildFragment, bundleOf("groupID" to groupID))
}
private fun openSettingsScreen() {
@ -77,8 +73,7 @@ class NotificationOpenHandler {
private fun handleChatMessage(type: String?, groupID: String?) {
when (type) {
"party" -> openPartyScreen(true)
"tavern" -> MainNavigationController.navigate(R.id.tavernFragment)
"party" -> openPartyScreen()
"guild" -> openGuildDetailScreen(groupID)
}
}

View file

@ -14,7 +14,6 @@ open class QuestBossRage : RealmObject(), BaseObject {
var description: String? = null
var value: Double = 0.toDouble()
var tavern: String? = null
var stables: String? = null
var market: String? = null
}

View file

@ -1,155 +0,0 @@
package com.habitrpg.android.habitica.ui.adapter.social
import android.view.View
import android.view.ViewGroup
import android.widget.Filter
import android.widget.Filterable
import androidx.core.content.ContextCompat
import androidx.core.os.bundleOf
import androidx.recyclerview.widget.RecyclerView
import com.habitrpg.android.habitica.R
import com.habitrpg.android.habitica.data.SocialRepository
import com.habitrpg.android.habitica.databinding.ItemPublicGuildBinding
import com.habitrpg.android.habitica.databinding.ItemUserGuildBinding
import com.habitrpg.android.habitica.databinding.PillTextviewBinding
import com.habitrpg.android.habitica.extensions.inflate
import com.habitrpg.android.habitica.helpers.MainNavigationController
import com.habitrpg.android.habitica.models.social.Group
import com.habitrpg.android.habitica.ui.adapter.BaseRecyclerViewAdapter
import com.habitrpg.android.habitica.ui.views.HabiticaIconsHelper
import com.habitrpg.common.habitica.extensions.dpToPx
import com.habitrpg.common.habitica.extensions.layoutInflater
import com.habitrpg.common.habitica.helpers.EmojiParser
import com.habitrpg.common.habitica.helpers.NumberAbbreviator
import io.realm.Case
import io.realm.OrderedRealmCollection
import java.util.Locale
class GuildListAdapter : BaseRecyclerViewAdapter<Group, RecyclerView.ViewHolder>(), Filterable {
var socialRepository: SocialRepository? = null
var onlyShowUsersGuilds = false
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
return if (onlyShowUsersGuilds) {
UserGuildViewHolder(parent.inflate(R.layout.item_user_guild))
} else {
GuildViewHolder(parent.inflate(R.layout.item_public_guild))
}
}
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
val guild = data[position]
if (onlyShowUsersGuilds && holder is UserGuildViewHolder) {
holder.bind(guild)
} else if (holder is GuildViewHolder) {
holder.bind(guild)
holder.itemView.tag = guild
}
holder.itemView.setOnClickListener {
MainNavigationController.navigate(R.id.guildFragment, bundleOf(Pair("groupID", guild.id)))
}
}
private var unfilteredData: List<Group>? = null
fun setUnfilteredData(data: List<Group>?) {
this.data = data ?: emptyList()
unfilteredData = data
}
override fun getFilter(): Filter {
return object : Filter() {
override fun performFiltering(constraint: CharSequence): FilterResults {
val results = FilterResults()
results.values = constraint
return FilterResults()
}
override fun publishResults(constraint: CharSequence, results: FilterResults) {
unfilteredData?.let {
if (constraint.isNotEmpty() && it is OrderedRealmCollection) {
data = it.where()
.beginGroup()
.contains("name", constraint.toString(), Case.INSENSITIVE)
.or()
.contains("summary", constraint.toString(), Case.INSENSITIVE)
.endGroup()
.findAll()
} else {
data = it
}
}
}
}
}
class UserGuildViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
val binding = ItemUserGuildBinding.bind(itemView)
fun bind(guild: Group) {
binding.titleTextView.text = guild.name
val number = when {
guild.memberCount < 1000 -> 2
guild.memberCount < 10000 -> 1
else -> 0
}
val formattedNumber = NumberAbbreviator.abbreviate(itemView.context, guild.memberCount.toDouble(), number)
binding.guildBadgeView.setImageBitmap(
HabiticaIconsHelper.imageOfGuildCrest(
false,
false,
guild.memberCount.toFloat(),
formattedNumber
)
)
}
}
class GuildViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
val binding = ItemPublicGuildBinding.bind(itemView)
fun bind(guild: Group) {
binding.nameTextView.text = guild.name
val number = when {
guild.memberCount < 1000 -> 2
guild.memberCount < 10000 -> 1
else -> 0
}
binding.memberCountTextView.text = NumberAbbreviator.abbreviate(itemView.context, guild.memberCount.toDouble(), number)
binding.descriptionTextView.text = EmojiParser.parseEmojis(guild.summary)
binding.descriptionTextView.setOnClickListener {
itemView.callOnClick()
}
binding.guildBadgeView.setImageBitmap(HabiticaIconsHelper.imageOfGuildCrestSmall(guild.memberCount.toFloat()))
binding.tagWrapper.removeAllViews()
guild.categories?.forEach { category ->
val textView = PillTextviewBinding.inflate(itemView.context.layoutInflater, binding.tagWrapper, true)
textView.root.text = category.name?.split("_")?.joinToString(" ") {
it.replaceFirstChar {
if (it.isLowerCase()) {
it.titlecase(
Locale.getDefault()
)
} else {
it.toString()
}
}
}
textView.root.background = if (category.slug == "habitica_official") {
textView.root.setTextColor(ContextCompat.getColor(itemView.context, R.color.white))
ContextCompat.getDrawable(itemView.context, R.drawable.pill_bg_purple_400)
} else {
textView.root.setTextColor(ContextCompat.getColor(itemView.context, R.color.text_secondary))
ContextCompat.getDrawable(itemView.context, R.drawable.pill_bg_gray)
}
val hPadding = 10.dpToPx(itemView.context)
val vPadding = 3.dpToPx(itemView.context)
textView.root.setPadding(hPadding, vPadding, hPadding, vPadding)
}
}
}
}

View file

@ -272,13 +272,6 @@ class NavigationDrawerFragment : DialogFragment() {
binding?.avatarView?.setAvatar(user)
binding?.questMenuView?.configure(user)
val tavernItem = getItemWithIdentifier(SIDEBAR_TAVERN)
if (user.preferences?.sleep == true) {
tavernItem?.subtitle = context?.getString(R.string.damage_paused)
} else {
tavernItem?.subtitle = null
}
val userItems = user.items
var hasSpecialItems = false
if (userItems != null) {
@ -504,24 +497,6 @@ class NavigationDrawerFragment : DialogFragment() {
context.getString(R.string.sidebar_party)
)
)
if (!configManager.hideTavern()) {
items.add(
HabiticaDrawerItem(
R.id.tavernFragment,
SIDEBAR_TAVERN,
context.getString(R.string.sidebar_tavern)
)
)
}
if (!configManager.hideGuilds()) {
items.add(
HabiticaDrawerItem(
R.id.guildOverviewFragment,
SIDEBAR_GUILDS,
context.getString(R.string.sidebar_guilds)
)
)
}
if (!configManager.hideChallenges()) {
items.add(
HabiticaDrawerItem(
@ -813,9 +788,7 @@ class NavigationDrawerFragment : DialogFragment() {
const val SIDEBAR_STATS = "stats"
const val SIDEBAR_ACHIEVEMENTS = "achievements"
const val SIDEBAR_SOCIAL = "social"
const val SIDEBAR_TAVERN = "tavern"
const val SIDEBAR_PARTY = "party"
const val SIDEBAR_GUILDS = "guilds"
const val SIDEBAR_CHALLENGES = "challenges"
const val SIDEBAR_INVENTORY = "inventory"
const val SIDEBAR_SHOPS_MARKET = "market"

View file

@ -1,202 +0,0 @@
package com.habitrpg.android.habitica.ui.fragments.social
import android.content.Context
import android.graphics.PorterDuff
import android.os.Bundle
import android.view.Gravity
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.FrameLayout
import android.widget.TextView
import androidx.appcompat.app.AlertDialog
import androidx.core.content.ContextCompat
import androidx.lifecycle.lifecycleScope
import com.habitrpg.android.habitica.R
import com.habitrpg.android.habitica.data.InventoryRepository
import com.habitrpg.android.habitica.data.SocialRepository
import com.habitrpg.android.habitica.data.UserRepository
import com.habitrpg.android.habitica.databinding.FragmentTavernDetailBinding
import com.habitrpg.android.habitica.extensions.setTintWith
import com.habitrpg.android.habitica.helpers.AppConfigManager
import com.habitrpg.android.habitica.helpers.MainNavigationController
import com.habitrpg.android.habitica.models.inventory.QuestContent
import com.habitrpg.android.habitica.models.social.Group
import com.habitrpg.android.habitica.models.user.User
import com.habitrpg.android.habitica.ui.fragments.BaseFragment
import com.habitrpg.android.habitica.ui.viewmodels.MainUserViewModel
import com.habitrpg.android.habitica.ui.views.UsernameLabel
import com.habitrpg.android.habitica.ui.views.dialogs.HabiticaAlertDialog
import com.habitrpg.common.habitica.helpers.ExceptionHandler
import com.habitrpg.common.habitica.models.PlayerTier
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.firstOrNull
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.launch
import javax.inject.Inject
@AndroidEntryPoint
class TavernDetailFragment : BaseFragment<FragmentTavernDetailBinding>() {
@Inject
lateinit var userRepository: UserRepository
@Inject
lateinit var socialRepository: SocialRepository
@Inject
lateinit var inventoryRepository: InventoryRepository
@Inject
lateinit var userViewModel: MainUserViewModel
@Inject
lateinit var configManager: AppConfigManager
private var shopSpriteSuffix = ""
override var binding: FragmentTavernDetailBinding? = null
override fun createBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentTavernDetailBinding {
return FragmentTavernDetailBinding.inflate(inflater, container, false)
}
private var user: User? = null
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
shopSpriteSuffix = configManager.shopSpriteSuffix()
userViewModel.user.observe(viewLifecycleOwner) {
user = it
updatePausedState()
}
binding?.shopHeader?.descriptionView?.setText(R.string.tavern_description)
binding?.shopHeader?.namePlate?.setText(R.string.tavern_owner)
binding?.shopHeader?.npcBannerView?.shopSpriteSuffix = configManager.shopSpriteSuffix()
binding?.shopHeader?.npcBannerView?.identifier = "tavern"
addPlayerTiers()
bindButtons()
lifecycleScope.launch(ExceptionHandler.coroutine()) {
socialRepository.getGroup(Group.TAVERN_ID)
.onEach { if (it?.hasActiveQuest == false) binding?.worldBossSection?.visibility = View.GONE }
.filter { it != null && it.hasActiveQuest }
.onEach {
binding?.questProgressView?.progress = it?.quest
binding?.shopHeader?.descriptionView?.setText(R.string.tavern_description_world_boss)
val filtered = it?.quest?.rageStrikes?.filter { strike -> strike.key == "tavern" }
if ((filtered?.size ?: 0) > 0 && filtered?.get(0)?.wasHit == true) {
val key = it.quest?.key
if (key != null) {
shopSpriteSuffix = key
}
}
}
.map { inventoryRepository.getQuestContent(it?.quest?.key ?: "").firstOrNull() }
.collect {
binding?.questProgressView?.quest = it
binding?.worldBossSection?.visibility = View.VISIBLE
}
}
lifecycleScope.launch(ExceptionHandler.coroutine()) { socialRepository.retrieveGroup(Group.TAVERN_ID) }
user?.let { binding?.questProgressView?.configure(it) }
}
override fun onDestroy() {
userRepository.close()
socialRepository.close()
inventoryRepository.close()
super.onDestroy()
}
private fun bindButtons() {
binding?.innButton?.setOnClickListener {
lifecycleScope.launch(ExceptionHandler.coroutine()) {
user?.let { user -> userRepository.sleep(user) }
}
}
binding?.guidelinesButton?.setOnClickListener {
MainNavigationController.navigate(R.id.guidelinesActivity)
}
binding?.faqButton?.setOnClickListener {
MainNavigationController.navigate(R.id.FAQOverviewFragment)
}
binding?.reportButton?.setOnClickListener {
MainNavigationController.navigate(R.id.aboutFragment)
}
binding?.worldBossSection?.infoIconView?.setOnClickListener {
val context = this.context
val quest = binding?.questProgressView?.quest
if (context != null && quest != null) {
showWorldBossInfoDialog(context, quest)
}
}
}
private fun updatePausedState() {
if (binding?.innButton == null) {
return
}
if (user?.preferences?.sleep == true) {
binding?.innButton?.setText(R.string.tavern_inn_checkOut)
} else {
binding?.innButton?.setText(R.string.tavern_inn_rest)
}
}
private fun addPlayerTiers() {
for (tier in PlayerTier.getTiers()) {
context?.let {
val container = FrameLayout(it)
container.background = ContextCompat.getDrawable(it, R.drawable.layout_rounded_bg_window)
val label = UsernameLabel(it, null)
label.tier = tier.id
label.username = tier.title
val params = FrameLayout.LayoutParams(
FrameLayout.LayoutParams.WRAP_CONTENT,
FrameLayout.LayoutParams.WRAP_CONTENT,
Gravity.CENTER
)
container.addView(label, params)
binding?.playerTiersView?.addView(container)
val padding = context?.resources?.getDimension(R.dimen.spacing_medium)?.toInt() ?: 0
container.setPadding(0, padding, 0, padding)
}
}
(binding?.playerTiersView?.parent as? ViewGroup)?.invalidate()
}
companion object {
fun showWorldBossInfoDialog(context: Context, quest: QuestContent) {
val alert = HabiticaAlertDialog(context)
val bossName = quest.boss?.name ?: ""
alert.setTitle(R.string.world_boss_description_title)
// alert.setSubtitle(context.getString(R.string.world_boss_description_subtitle, bossName))
alert.setAdditionalContentView(R.layout.world_boss_description_view)
val descriptionView = alert.getContentView()
val promptView: TextView? = descriptionView?.findViewById(R.id.worldBossActionPromptView)
promptView?.text = context.getString(R.string.world_boss_action_prompt, bossName)
promptView?.setTextColor(quest.colors?.lightColor ?: 0)
val background = ContextCompat.getDrawable(context, R.drawable.rounded_border)
background?.setTintWith(quest.colors?.extraLightColor ?: 0, PorterDuff.Mode.MULTIPLY)
promptView?.background = background
alert.setButton(AlertDialog.BUTTON_POSITIVE, context.getString(R.string.close)) { dialog, _ ->
dialog.dismiss()
}
alert.show()
}
}
}

View file

@ -1,116 +0,0 @@
package com.habitrpg.android.habitica.ui.fragments.social
import android.os.Bundle
import android.view.LayoutInflater
import android.view.Menu
import android.view.MenuInflater
import android.view.MenuItem
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.fragment.app.viewModels
import androidx.viewpager2.adapter.FragmentStateAdapter
import com.google.android.material.tabs.TabLayoutMediator
import com.habitrpg.android.habitica.R
import com.habitrpg.android.habitica.data.SocialRepository
import com.habitrpg.android.habitica.databinding.FragmentViewpagerBinding
import com.habitrpg.android.habitica.models.social.Group
import com.habitrpg.android.habitica.ui.fragments.BaseMainFragment
import com.habitrpg.android.habitica.ui.viewmodels.GroupViewModel
import com.habitrpg.android.habitica.ui.viewmodels.GroupViewType
import dagger.hilt.android.AndroidEntryPoint
import javax.inject.Inject
@AndroidEntryPoint
class TavernFragment : BaseMainFragment<FragmentViewpagerBinding>() {
@Inject
lateinit var socialRepository: SocialRepository
override var binding: FragmentViewpagerBinding? = null
override fun createBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentViewpagerBinding {
return FragmentViewpagerBinding.inflate(inflater, container, false)
}
internal val viewModel: GroupViewModel by viewModels()
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
this.usesTabLayout = true
this.hidesToolbar = true
return super.onCreateView(inflater, container, savedInstanceState)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
viewModel.groupViewType = GroupViewType.GUILD
viewModel.setGroupID(Group.TAVERN_ID)
setViewPagerAdapter()
binding?.viewPager?.currentItem = 0
}
override fun onDestroy() {
socialRepository.close()
super.onDestroy()
}
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
inflater.inflate(R.menu.menu_tavern, menu)
super.onCreateOptionsMenu(menu, inflater)
}
@Suppress("ReturnCount")
override fun onOptionsItemSelected(item: MenuItem): Boolean {
when (item.itemId) {
R.id.menu_guild_refresh -> {
viewModel.retrieveGroup { }
return true
}
}
return super.onOptionsItemSelected(item)
}
private fun setViewPagerAdapter() {
val fragmentManager = childFragmentManager
binding?.viewPager?.adapter = object : FragmentStateAdapter(fragmentManager, lifecycle) {
override fun createFragment(position: Int): Fragment {
return when (position) {
0 -> {
TavernDetailFragment()
}
1 -> {
ChatFragment()
}
else -> Fragment()
}
}
override fun getItemCount(): Int {
return if (viewModel.getGroupData().value?.quest?.active == true) {
3
} else {
2
}
}
}
tabLayout?.let {
binding?.viewPager?.let { it1 ->
TabLayoutMediator(it, it1) { tab, position ->
tab.text = when (position) {
0 -> context?.getString(R.string.inn)
1 -> context?.getString(R.string.chat)
2 -> context?.getString(R.string.world_quest)
else -> ""
}
}.attach()
}
}
}
}

View file

@ -1,112 +0,0 @@
package com.habitrpg.android.habitica.ui.fragments.social.guilds
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.appcompat.widget.SearchView
import androidx.lifecycle.lifecycleScope
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
import com.habitrpg.android.habitica.R
import com.habitrpg.android.habitica.data.SocialRepository
import com.habitrpg.android.habitica.databinding.FragmentRefreshRecyclerviewBinding
import com.habitrpg.android.habitica.ui.adapter.social.GuildListAdapter
import com.habitrpg.android.habitica.ui.fragments.BaseFragment
import com.habitrpg.android.habitica.ui.helpers.KeyboardUtil
import com.habitrpg.android.habitica.ui.helpers.SafeDefaultItemAnimator
import com.habitrpg.common.habitica.helpers.EmptyItem
import com.habitrpg.common.habitica.helpers.ExceptionHandler
import com.habitrpg.common.habitica.helpers.launchCatching
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.launch
import javax.inject.Inject
@AndroidEntryPoint
class GuildListFragment :
BaseFragment<FragmentRefreshRecyclerviewBinding>(),
SearchView.OnQueryTextListener,
SearchView.OnCloseListener,
SwipeRefreshLayout.OnRefreshListener {
@Inject
lateinit var socialRepository: SocialRepository
override var binding: FragmentRefreshRecyclerviewBinding? = null
var onlyShowUsersGuilds: Boolean = false
override fun createBinding(
inflater: LayoutInflater,
container: ViewGroup?
): FragmentRefreshRecyclerviewBinding {
return FragmentRefreshRecyclerviewBinding.inflate(inflater, container, false)
}
private var viewAdapter = GuildListAdapter()
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding?.recyclerView?.layoutManager =
androidx.recyclerview.widget.LinearLayoutManager(activity)
viewAdapter.socialRepository = socialRepository
binding?.recyclerView?.adapter = viewAdapter
binding?.recyclerView?.itemAnimator = SafeDefaultItemAnimator()
binding?.recyclerView?.emptyItem = EmptyItem(
getString(R.string.empty_guilds_list),
getString(R.string.empty_discover_description)
)
binding?.refreshLayout?.setOnRefreshListener(this)
viewAdapter.onlyShowUsersGuilds = onlyShowUsersGuilds
if (onlyShowUsersGuilds) {
lifecycleScope.launch(ExceptionHandler.coroutine()) {
socialRepository.getUserGroups("guild")
.collect {
viewAdapter.setUnfilteredData(it)
}
}
} else {
lifecycleScope.launchCatching {
socialRepository.getPublicGuilds().collect { groups ->
this@GuildListFragment.viewAdapter.setUnfilteredData(groups)
}
}
}
this.fetchGuilds()
}
override fun onDestroy() {
socialRepository.close()
super.onDestroy()
}
internal fun fetchGuilds() {
lifecycleScope.launchCatching {
socialRepository.retrieveGroups(if (onlyShowUsersGuilds) "guilds" else "publicGuilds")
binding?.refreshLayout?.isRefreshing = false
}
}
override fun onQueryTextSubmit(s: String?): Boolean {
viewAdapter.filter.filter(s)
activity?.let {
KeyboardUtil.dismissKeyboard(it)
}
return true
}
override fun onQueryTextChange(s: String?): Boolean {
viewAdapter.filter.filter(s)
return true
}
override fun onRefresh() {
fetchGuilds()
}
override fun onClose(): Boolean {
viewAdapter.filter.filter("")
return false
}
}

View file

@ -1,156 +0,0 @@
package com.habitrpg.android.habitica.ui.fragments.social.guilds
import android.content.Intent
import android.content.pm.PackageManager
import android.os.Bundle
import android.view.LayoutInflater
import android.view.Menu
import android.view.MenuInflater
import android.view.MenuItem
import android.view.View
import android.view.ViewGroup
import androidx.appcompat.widget.SearchView
import androidx.core.content.ContextCompat
import androidx.core.net.toUri
import androidx.fragment.app.Fragment
import androidx.viewpager2.adapter.FragmentStateAdapter
import com.google.android.material.tabs.TabLayoutMediator
import com.habitrpg.android.habitica.R
import com.habitrpg.android.habitica.data.SocialRepository
import com.habitrpg.android.habitica.databinding.FragmentViewpagerBinding
import com.habitrpg.android.habitica.extensions.addCloseButton
import com.habitrpg.android.habitica.ui.fragments.BaseMainFragment
import com.habitrpg.android.habitica.ui.views.dialogs.HabiticaAlertDialog
import dagger.hilt.android.AndroidEntryPoint
import javax.inject.Inject
@AndroidEntryPoint
class GuildOverviewFragment : BaseMainFragment<FragmentViewpagerBinding>(), SearchView.OnQueryTextListener {
@Inject
internal lateinit var socialRepository: SocialRepository
override var binding: FragmentViewpagerBinding? = null
override fun createBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentViewpagerBinding {
return FragmentViewpagerBinding.inflate(inflater, container, false)
}
private var statePagerAdapter: FragmentStateAdapter? = null
private var userGuildsFragment: GuildListFragment? = GuildListFragment()
private var publicGuildsFragment: GuildListFragment? = GuildListFragment()
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
this.usesTabLayout = true
this.hidesToolbar = true
return super.onCreateView(inflater, container, savedInstanceState)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
setViewPagerAdapter()
}
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
super.onCreateOptionsMenu(menu, inflater)
inflater.inflate(R.menu.menu_public_guild, menu)
val searchItem = menu.findItem(R.id.action_search)
val guildSearchView = searchItem?.actionView as? SearchView
val theTextArea = guildSearchView?.findViewById<SearchView.SearchAutoComplete>(R.id.search_src_text)
context?.let { theTextArea?.setHintTextColor(ContextCompat.getColor(it, R.color.white)) }
guildSearchView?.queryHint = getString(R.string.guild_search_hint)
guildSearchView?.setOnQueryTextListener(this)
guildSearchView?.setOnCloseListener {
getActiveFragment()?.onClose() ?: true
}
}
@Suppress("ReturnCount")
override fun onOptionsItemSelected(item: MenuItem): Boolean {
when (item.itemId) {
R.id.menu_create_item -> {
showCreationDialog()
return true
}
R.id.action_reload -> {
getActiveFragment()?.fetchGuilds()
return true
}
}
return super.onOptionsItemSelected(item)
}
private fun showCreationDialog() {
val context = context ?: return
val dialog = HabiticaAlertDialog(context)
dialog.setTitle(R.string.create_guild)
dialog.setMessage(R.string.create_guild_description)
dialog.addButton(R.string.open_website, isPrimary = true, isDestructive = false) { _, _ ->
val uriUrl = "https://habitica.com/groups/myGuilds".toUri()
val launchBrowser = Intent(Intent.ACTION_VIEW, uriUrl)
val l = context.packageManager.queryIntentActivities(launchBrowser, PackageManager.MATCH_DEFAULT_ONLY)
val notHabitica = l.firstOrNull() { !it.activityInfo.processName.contains("habitica") }
launchBrowser.setPackage(notHabitica?.activityInfo?.processName)
startActivity(launchBrowser)
}
dialog.addCloseButton()
dialog.show()
}
private fun getActiveFragment(): GuildListFragment? {
return if (binding?.viewPager?.currentItem == 0) {
userGuildsFragment
} else {
publicGuildsFragment
}
}
private fun setViewPagerAdapter() {
val fragmentManager = childFragmentManager
statePagerAdapter = object : FragmentStateAdapter(fragmentManager, lifecycle) {
override fun createFragment(position: Int): Fragment {
val fragment = GuildListFragment()
fragment.onlyShowUsersGuilds = position == 0
if (position == 0) {
userGuildsFragment = fragment
} else {
publicGuildsFragment = fragment
}
return fragment
}
override fun getItemCount(): Int {
return 2
}
}
binding?.viewPager?.adapter = statePagerAdapter
tabLayout?.let {
binding?.viewPager?.let { it1 ->
TabLayoutMediator(it, it1) { tab, position ->
tab.text = when (position) {
0 -> getString(R.string.my_guilds)
1 -> getString(R.string.discover)
else -> ""
}
}.attach()
}
}
statePagerAdapter?.notifyDataSetChanged()
}
override fun onQueryTextSubmit(query: String?): Boolean {
return getActiveFragment()?.onQueryTextSubmit(query) ?: false
}
override fun onQueryTextChange(newText: String?): Boolean {
return getActiveFragment()?.onQueryTextChange(newText) ?: false
}
}

View file

@ -39,7 +39,6 @@ import kotlin.time.toDuration
enum class GroupViewType(internal val order: String) {
PARTY("party"),
GUILD("guild"),
TAVERN("tavern")
}
@OptIn(ExperimentalCoroutinesApi::class)
@ -209,7 +208,7 @@ open class GroupViewModel @Inject constructor(
fun markMessagesSeen() {
groupID?.let {
if (groupViewType != GroupViewType.TAVERN && it.isNotEmpty() && gotNewMessages) {
if (it.isNotEmpty() && gotNewMessages) {
viewModelScope.launchCatching {
socialRepository.markMessagesSeen(it)
}

View file

@ -1,3 +1,5 @@
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
@ -10,27 +12,27 @@ buildscript {
accompanist_version = '0.28.0'
amplitude_version = '1.6.1'
appcompat_version = '1.6.1'
coil_version = '2.2.2'
coil_version = '2.4.0'
compose_version = '1.4.3'
core_ktx_version = '1.10.0'
core_ktx_version = '1.10.1'
coroutines_version = '1.6.4'
daggerhilt_version = '2.44.2'
daggerhilt_version = '2.47'
firebase_bom = '31.3.0'
kotest_version = '5.5.5'
kotlin_version = '1.8.20'
ktlint_version = '0.48.2'
kotest_version = '5.6.2'
kotlin_version = '1.8.21'
ktlint_version = '0.50.0'
lifecycle_version = '2.6.1'
markwon_version = '4.6.2'
mockk_version = '1.13.4'
moshi_version = '1.14.0'
navigation_version = '2.5.3'
okhttp_version = '4.10.0'
okhttp_version = '4.11.0'
play_wearables_version = '18.0.0'
play_auth_version = '20.5.0'
play_auth_version = '20.6.0'
preferences_version = '1.2.0'
realm_version = '1.0.2'
retrofit_version = '2.9.0'
recyclerview_version = '1.3.0'
recyclerview_version = '1.3.1'
}
repositories {
@ -115,7 +117,7 @@ tasks.named("detekt").configure {
}
task allUnitTests(type: GradleBuild) {
tasks = [':Habitica:testProdDebugUnitTest', ':wearos:testProdDebugUnitTest', ':common:testProdDebugUnitTest', ':shared:testDebugUnitTest']
tasks = [':Habitica:testProdDebugUnitTest', ':wearos:testProdDebugUnitTest', ':common:testProdDebugUnitTest']
}
subprojects {

View file

@ -8,8 +8,8 @@ fun <T> LiveData<T>.observeOnce(lifecycleOwner: LifecycleOwner, observer: Observ
observe(
lifecycleOwner,
object : Observer<T> {
override fun onChanged(t: T?) {
observer.onChanged(t)
override fun onChanged(value: T) {
observer.onChanged(value)
removeObserver(this)
}
}

View file

@ -1,6 +1,6 @@
#Sun May 08 23:57:52 EDT 2022
distributionBase=GRADLE_USER_HOME
distributionUrl=https\://services.gradle.org/distributions/gradle-8.0-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.2.1-bin.zip
distributionPath=wrapper/dists
zipStorePath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME

View file

@ -1,5 +1,5 @@
plugins {
id 'org.gradle.toolchains.foojay-resolver-convention' version '0.4.0'
id 'org.gradle.toolchains.foojay-resolver-convention' version '0.6.0'
}
include 'Habitica', ':Habitica'

View file

@ -3,7 +3,7 @@ plugins {
id("com.android.library")
id("kotlin-parcelize")
id("kotlin-kapt")
id("io.kotest.multiplatform") version "5.5.5"
id("io.kotest.multiplatform") version "5.6.2"
}
allprojects {