diff --git a/Habitica/res/layout/dialog_login_incentive.xml b/Habitica/res/layout/dialog_login_incentive.xml index 3a35b9597..425f6c5f4 100644 --- a/Habitica/res/layout/dialog_login_incentive.xml +++ b/Habitica/res/layout/dialog_login_incentive.xml @@ -32,5 +32,4 @@ android:textColor="@color/text_secondary" android:gravity="center_horizontal" style="@style/Body1"/> - \ No newline at end of file diff --git a/Habitica/res/layout/empty_item.xml b/Habitica/res/layout/empty_item.xml index 17f5e67d0..e439f0418 100644 --- a/Habitica/res/layout/empty_item.xml +++ b/Habitica/res/layout/empty_item.xml @@ -5,7 +5,8 @@ android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" - android:gravity="center"> + android:gravity="center" + android:padding="30dp"> You don\'t have any equipment of this type yet. You can purchase equipment from the market using the gold you earned. Todo Checkbox Open Shop - You aren\'t a member of any Challenges. Head over to the Discover tab to find some to join! - You aren\'t a member of any Guilds. Head over to the Discover tab to find some to join! + You aren\'t a member of any Challenges. + You aren\'t a member of any Guilds. + Head over to the Discover tab to find some to join! diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/ChallengeRepositoryImpl.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/ChallengeRepositoryImpl.kt index c6ff29711..29f505a27 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/ChallengeRepositoryImpl.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/ChallengeRepositoryImpl.kt @@ -123,7 +123,7 @@ class ChallengeRepositoryImpl(localRepository: ChallengeLocalRepository, apiClie override fun retrieveChallenges(page: Int, memberOnly: Boolean): Flowable> { return apiClient.getUserChallenges(page, memberOnly) - .doOnNext { localRepository.saveChallenges(it, page == 0, memberOnly) } + .doOnNext { localRepository.saveChallenges(it, page == 0, memberOnly, userID) } } override fun leaveChallenge(challenge: Challenge, keepTasks: String): Flowable { diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/ContentRepositoryImpl.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/ContentRepositoryImpl.kt index e636f35a1..5ace602b4 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/ContentRepositoryImpl.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/ContentRepositoryImpl.kt @@ -34,7 +34,7 @@ abstract class ContentRepositoryImpl(localRepository localRepository.saveContent(it) } } else { - Flowable.empty() + Flowable.just(ContentResult()) } } @@ -51,7 +51,7 @@ abstract class ContentRepositoryImpl(localRepository } } } else { - Flowable.empty() + Flowable.just(WorldState()) } } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/TaskRepositoryImpl.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/TaskRepositoryImpl.kt index ae7457124..0de3eea94 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/TaskRepositoryImpl.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/TaskRepositoryImpl.kt @@ -167,12 +167,11 @@ class TaskRepositoryImpl(localRepository: TaskLocalRepository, apiClient: ApiCli } } - val stats = it.copyFromRealm(bgUser.stats) - stats?.hp = res.hp - stats?.exp = res.exp - stats?.mp = res.mp - stats?.gp = res.gp - stats?.lvl = res.lvl + bgUser.stats?.hp = res.hp + bgUser.stats?.exp = res.exp + bgUser.stats?.mp = res.mp + bgUser.stats?.gp = res.gp + bgUser.stats?.lvl = res.lvl bgUser.party?.quest?.progress?.up = (bgUser.party?.quest?.progress?.up ?: 0F) + (res._tmp?.quest?.progressDelta?.toFloat() ?: 0F) } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/data/local/ChallengeLocalRepository.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/data/local/ChallengeLocalRepository.kt index 2840710a9..271dc6ec6 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/data/local/ChallengeLocalRepository.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/data/local/ChallengeLocalRepository.kt @@ -17,7 +17,7 @@ interface ChallengeLocalRepository : BaseLocalRepository { fun setParticipating(userID: String, challengeID: String, isParticipating: Boolean) - fun saveChallenges(challenges: List, clearChallenges: Boolean, memberOnly: Boolean) + fun saveChallenges(challenges: List, clearChallenges: Boolean, memberOnly: Boolean, userID: String) fun getChallengeMembership(userId: String, id: String): Flowable fun getChallengeMemberships(userId: String): Flowable> fun isChallengeMember(userID: String, challengeID: String): Flowable diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/data/local/implementation/RealmChallengeLocalRepository.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/data/local/implementation/RealmChallengeLocalRepository.kt index 46955b6ac..797b520de 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/data/local/implementation/RealmChallengeLocalRepository.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/data/local/implementation/RealmChallengeLocalRepository.kt @@ -94,12 +94,15 @@ class RealmChallengeLocalRepository(realm: Realm) : RealmBaseLocalRepository(rea } } - override fun saveChallenges(challenges: List, clearChallenges: Boolean, memberOnly: Boolean) { + override fun saveChallenges(challenges: List, clearChallenges: Boolean, memberOnly: Boolean, userID: String) { if (clearChallenges && !memberOnly) { val localChallenges = realm.where(Challenge::class.java).findAll().createSnapshot() + val memberships = realm.where(ChallengeMembership::class.java).findAll() val challengesToDelete = ArrayList() for (localTask in localChallenges) { - if (!challenges.contains(localTask)) { + if (!challenges.contains(localTask) + && memberships.find { it.challengeID == localTask.id } == null + && localTask.leaderId != userID) { challengesToDelete.add(localTask) } } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/models/shops/ShopItem.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/models/shops/ShopItem.kt index e3cf72a56..cbcd9a5fc 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/models/shops/ShopItem.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/models/shops/ShopItem.kt @@ -134,6 +134,8 @@ open class ShopItem : RealmObject(), BaseObject { item.value = 20 item.currency = "gold" item.purchaseType = "gems" + item.pinType = "gem" + item.path = "special.gems" return item } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/AvatarView.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/AvatarView.kt index 6a3a8ef48..a5af16eda 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/AvatarView.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/AvatarView.kt @@ -5,15 +5,10 @@ import android.graphics.* import android.graphics.drawable.Drawable import android.text.TextUtils import android.util.AttributeSet -import android.view.View import android.widget.FrameLayout import android.widget.ImageView import coil.clear -import coil.imageLoader import coil.load -import coil.request.ImageRequest -import coil.target.ViewTarget -import coil.transition.Transition import com.habitrpg.android.habitica.BuildConfig import com.habitrpg.android.habitica.R import com.habitrpg.android.habitica.helpers.AppConfigManager @@ -130,7 +125,9 @@ class AvatarView : FrameLayout { imageViewHolder[layerNumber] } - if (imageView.tag == layerName) continue + if (imageView.tag == layerName) { + continue + } imageView.tag = layerName imageView.clear() imageView.setImageResource(0) @@ -157,6 +154,7 @@ class AvatarView : FrameLayout { while (i < (imageViewHolder.size)) { imageViewHolder[i].clear() imageViewHolder[i].setImageResource(0) + imageViewHolder[i].tag = null i++ } } @@ -426,7 +424,7 @@ class AvatarView : FrameLayout { // compact hero box when only showBackground is enabled (114w * 114h) // hero only box when all show settings disabled (90w * 90h) avatarRectF = RectF(0f, 0f, width.toFloat(), height.toFloat()) - avatarMatrix.setRectToRect(RectF(srcRect), avatarRectF, Matrix.ScaleToFit.START) // TODO support other ScaleToFit + avatarMatrix.setRectToRect(RectF(srcRect), avatarRectF, Matrix.ScaleToFit.START) avatarRectF = RectF(srcRect) avatarMatrix.mapRect(avatarRectF) } @@ -475,11 +473,8 @@ class AvatarView : FrameLayout { } companion object { - private const val TAG = "AvatarView" private val FULL_HERO_RECT = Rect(0, 0, 140, 147) private val COMPACT_HERO_RECT = Rect(0, 0, 114, 114) private val HERO_ONLY_RECT = Rect(0, 0, 90, 90) - - //val postProcessors: MutableMap BasePostprocessor?)> = mutableMapOf() } } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/FullProfileActivity.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/FullProfileActivity.kt index 1682e96c0..c54a2cdce 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/FullProfileActivity.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/FullProfileActivity.kt @@ -35,6 +35,7 @@ import com.habitrpg.android.habitica.ui.views.HabiticaSnackbar.SnackbarDisplayTy import com.habitrpg.android.habitica.ui.views.dialogs.HabiticaAlertDialog import io.reactivex.rxjava3.core.Flowable import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.delay import kotlinx.coroutines.launch import java.text.SimpleDateFormat @@ -175,7 +176,7 @@ class FullProfileActivity : BaseActivity() { private fun showSendMessageToUserDialog() { finish() - lifecycleScope.launch(context = Dispatchers.Main) { + GlobalScope.launch(context = Dispatchers.Main) { delay(1000L) MainNavigationController.navigate(R.id.inboxMessageListFragment, bundleOf(Pair("username", username), Pair("userID", userID))) } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/MainActivity.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/MainActivity.kt index c7c00aca4..c28b22741 100755 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/MainActivity.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/MainActivity.kt @@ -45,7 +45,6 @@ import com.habitrpg.android.habitica.helpers.notifications.PushNotificationManag import com.habitrpg.android.habitica.interactors.CheckClassSelectionUseCase import com.habitrpg.android.habitica.interactors.DisplayItemDropUseCase import com.habitrpg.android.habitica.interactors.NotifyUserUseCase -import com.habitrpg.android.habitica.models.Notification import com.habitrpg.android.habitica.models.TutorialStep import com.habitrpg.android.habitica.models.inventory.Egg import com.habitrpg.android.habitica.models.inventory.HatchingPotion @@ -72,12 +71,12 @@ import com.habitrpg.android.habitica.widget.AvatarStatsWidgetProvider import com.habitrpg.android.habitica.widget.DailiesWidgetProvider import com.habitrpg.android.habitica.widget.HabitButtonWidgetProvider import com.habitrpg.android.habitica.widget.TodoListWidgetProvider -import io.reactivex.rxjava3.core.Completable import io.reactivex.rxjava3.core.Observable import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers import io.reactivex.rxjava3.functions.Consumer import io.reactivex.rxjava3.schedulers.Schedulers import io.realm.kotlin.isValid +import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import org.greenrobot.eventbus.EventBus import org.greenrobot.eventbus.Subscribe @@ -763,7 +762,7 @@ open class MainActivity : BaseActivity(), TutorialView.OnTutorialReaction { if (imageKey?.contains("armor") == true) { imageKey = "slim_$imageKey" } - DataBindingUtils.loadImage(imageView, "shop_$imageKey") + DataBindingUtils.loadImage(imageView, imageKey) val youEarnedMessage = this.getString(R.string.checkInRewardEarned, notificationData?.rewardText) val youEarnedTexView = view.findViewById(R.id.you_earned_message) as? TextView @@ -776,24 +775,22 @@ open class MainActivity : BaseActivity(), TutorialView.OnTutorialReaction { nextUnlockTextView?.visibility = View.GONE } - compositeSubscription.add(Completable.complete() - .observeOn(AndroidSchedulers.mainThread()) - .subscribe({ - val alert = HabiticaAlertDialog(this) - alert.setAdditionalContentView(view) - alert.setTitle(title) - alert.addButton(R.string.see_you_tomorrow, true) { _, _ -> - apiClient.readNotification(event.notification.id) - .subscribe({ }, RxErrorHandler.handleEmptyError()) - } - alert.show() - }, RxErrorHandler.handleEmptyError())) + lifecycleScope.launch(context = Dispatchers.Main) { + val alert = HabiticaAlertDialog(this@MainActivity) + alert.setAdditionalContentView(view) + alert.setTitle(title) + alert.addButton(R.string.see_you_tomorrow, true) { _, _ -> + apiClient.readNotification(event.notification.id) + .subscribe({ }, RxErrorHandler.handleEmptyError()) + } + alert.show() + } } @Subscribe fun showAchievementDialog(event: ShowAchievementDialog) { retrieveUser(true) - lifecycleScope.launch { + lifecycleScope.launch(context = Dispatchers.Main) { val dialog = AchievementDialog(this@MainActivity) dialog.isLastOnboardingAchievement = event.isLastOnboardingAchievement dialog.setType(event.type, event.message, event.text) @@ -806,7 +803,7 @@ open class MainActivity : BaseActivity(), TutorialView.OnTutorialReaction { @Subscribe fun showFirstDropDialog(event: ShowFirstDropDialog) { retrieveUser(true) - lifecycleScope.launch { + lifecycleScope.launch(context = Dispatchers.Main) { val dialog = FirstDropDialog(this@MainActivity) dialog.configure(event.egg, event.hatchingPotion) dialog.enqueue() @@ -818,7 +815,7 @@ open class MainActivity : BaseActivity(), TutorialView.OnTutorialReaction { @Subscribe fun showWonAchievementDialog(event: ShowWonChallengeDialog) { retrieveUser(true) - lifecycleScope.launch { + lifecycleScope.launch(context = Dispatchers.Main) { val dialog = WonChallengeDialog(this@MainActivity) dialog.configure(event.data) dialog.enqueue() diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/challenges/ChallengeListFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/challenges/ChallengeListFragment.kt index 175221acf..fa3914230 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/challenges/ChallengeListFragment.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/challenges/ChallengeListFragment.kt @@ -75,7 +75,8 @@ class ChallengeListFragment : BaseFragment() if (viewUserChallengesOnly) { binding?.recyclerView?.emptyItem = EmptyItem( - getString(R.string.empty_challenge_list) + getString(R.string.empty_challenge_list), + getString(R.string.empty_discover_description) ) } binding?.recyclerView?.layoutManager = androidx.recyclerview.widget.LinearLayoutManager(this.activity) diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/guilds/GuildListFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/guilds/GuildListFragment.kt index b33cda934..633c44773 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/guilds/GuildListFragment.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/guilds/GuildListFragment.kt @@ -41,7 +41,8 @@ class GuildListFragment : BaseFragment(), Se viewAdapter.socialRepository = socialRepository binding?.recyclerView?.adapter = viewAdapter binding?.recyclerView?.itemAnimator = SafeDefaultItemAnimator() - binding?.recyclerView?.emptyItem = EmptyItem(getString(R.string.empty_guilds_list)) + binding?.recyclerView?.emptyItem = EmptyItem(getString(R.string.empty_guilds_list), + getString(R.string.empty_discover_description)) binding?.refreshLayout?.setOnRefreshListener(this) diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewHolders/tasks/RewardViewHolder.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewHolders/tasks/RewardViewHolder.kt index 1651aa0fa..5b8b17937 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewHolders/tasks/RewardViewHolder.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewHolders/tasks/RewardViewHolder.kt @@ -58,6 +58,7 @@ class RewardViewHolder(itemView: View, scoreTaskFunc: ((Task, TaskDirection) -> fun bind(reward: Task, position: Int, canBuy: Boolean, displayMode: String) { this.task = reward + streakTextView.visibility = View.GONE super.bind(reward, position, displayMode) binding.priceLabel.text = NumberAbbreviator.abbreviate(itemView.context, this.task?.value ?: 0.0) @@ -79,6 +80,5 @@ class RewardViewHolder(itemView: View, scoreTaskFunc: ((Task, TaskDirection) -> binding.buyButton.setBackgroundColor(ColorUtils.setAlphaComponent(ContextCompat.getColor(context, R.color.offset_background), 127)) } } - streakTextView.visibility = View.GONE } } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/dialogs/AchievementDetailDialog.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/dialogs/AchievementDetailDialog.kt index fbd17d597..b7e9f7394 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/dialogs/AchievementDetailDialog.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/dialogs/AchievementDetailDialog.kt @@ -2,9 +2,11 @@ package com.habitrpg.android.habitica.ui.views.dialogs import android.content.Context import android.view.LayoutInflater +import android.view.View import android.widget.ImageView import android.widget.TextView import com.habitrpg.android.habitica.R +import com.habitrpg.android.habitica.databinding.DialogAchievementDetailBinding import com.habitrpg.android.habitica.extensions.addCloseButton import com.habitrpg.android.habitica.extensions.fromHtml import com.habitrpg.android.habitica.models.Achievement @@ -16,11 +18,12 @@ class AchievementDetailDialog(val achievement: Achievement, context: Context): H private var descriptionView: TextView? init { - val inflater = context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as? LayoutInflater - val view = inflater?.inflate(R.layout.dialog_achievement_detail, null) - iconView = view?.findViewById(R.id.icon_view) - descriptionView = view?.findViewById(R.id.description_view) - setAdditionalContentView(view) + val inflater = context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater + val binding = DialogAchievementDetailBinding.inflate(inflater) + binding.onboardingDoneIcon.visibility = View.GONE + iconView = binding.iconView + descriptionView = binding.descriptionView + setAdditionalContentView(binding.root) setTitle(achievement.title) descriptionView?.setText(achievement.text?.fromHtml(), TextView.BufferType.SPANNABLE) val iconName = if (achievement.earned) {