diff --git a/Habitica/build.gradle b/Habitica/build.gradle index 468adc64f..ea8cbc658 100644 --- a/Habitica/build.gradle +++ b/Habitica/build.gradle @@ -162,7 +162,7 @@ android { multiDexEnabled true resConfigs "en", "bg", "de", "en-rGB", "es", "fr", "hr-rHR", "in", "it", "iw", "ja", "ko", "lt", "nl", "pl", "pt-rBR", "pt-rPT", "ru", "tr", "zh", "zh-rTW" - versionCode 2437 + versionCode 2441 versionName "2.7" } diff --git a/Habitica/res/drawable-hdpi/task_broken_megaphone.png b/Habitica/res/drawable-hdpi/task_broken_megaphone.png new file mode 100644 index 000000000..fff129368 Binary files /dev/null and b/Habitica/res/drawable-hdpi/task_broken_megaphone.png differ diff --git a/Habitica/res/drawable-hdpi/task_icon_challenge.webp b/Habitica/res/drawable-hdpi/task_icon_challenge.webp deleted file mode 100644 index c812710fc..000000000 Binary files a/Habitica/res/drawable-hdpi/task_icon_challenge.webp and /dev/null differ diff --git a/Habitica/res/drawable-hdpi/task_megaphone.png b/Habitica/res/drawable-hdpi/task_megaphone.png new file mode 100644 index 000000000..aacc986d1 Binary files /dev/null and b/Habitica/res/drawable-hdpi/task_megaphone.png differ diff --git a/Habitica/res/drawable-mdpi/task_broken_megaphone.png b/Habitica/res/drawable-mdpi/task_broken_megaphone.png new file mode 100644 index 000000000..72faf39ce Binary files /dev/null and b/Habitica/res/drawable-mdpi/task_broken_megaphone.png differ diff --git a/Habitica/res/drawable-mdpi/task_icon_challenge.webp b/Habitica/res/drawable-mdpi/task_icon_challenge.webp deleted file mode 100644 index c8b6cb4a2..000000000 Binary files a/Habitica/res/drawable-mdpi/task_icon_challenge.webp and /dev/null differ diff --git a/Habitica/res/drawable-mdpi/task_megaphone.png b/Habitica/res/drawable-mdpi/task_megaphone.png new file mode 100644 index 000000000..08582956f Binary files /dev/null and b/Habitica/res/drawable-mdpi/task_megaphone.png differ diff --git a/Habitica/res/drawable-xhdpi/task_broken_megaphone.png b/Habitica/res/drawable-xhdpi/task_broken_megaphone.png new file mode 100644 index 000000000..3b4250dcf Binary files /dev/null and b/Habitica/res/drawable-xhdpi/task_broken_megaphone.png differ diff --git a/Habitica/res/drawable-xhdpi/task_icon_challenge.webp b/Habitica/res/drawable-xhdpi/task_icon_challenge.webp deleted file mode 100644 index c83b2daf4..000000000 Binary files a/Habitica/res/drawable-xhdpi/task_icon_challenge.webp and /dev/null differ diff --git a/Habitica/res/drawable-xhdpi/task_megaphone.png b/Habitica/res/drawable-xhdpi/task_megaphone.png new file mode 100644 index 000000000..60df85d01 Binary files /dev/null and b/Habitica/res/drawable-xhdpi/task_megaphone.png differ diff --git a/Habitica/res/drawable-xxhdpi/task_broken_megaphone.png b/Habitica/res/drawable-xxhdpi/task_broken_megaphone.png new file mode 100644 index 000000000..9f5d7cac3 Binary files /dev/null and b/Habitica/res/drawable-xxhdpi/task_broken_megaphone.png differ diff --git a/Habitica/res/drawable-xxhdpi/task_icon_challenge.webp b/Habitica/res/drawable-xxhdpi/task_icon_challenge.webp deleted file mode 100644 index 885461b2a..000000000 Binary files a/Habitica/res/drawable-xxhdpi/task_icon_challenge.webp and /dev/null differ diff --git a/Habitica/res/drawable-xxhdpi/task_megaphone.png b/Habitica/res/drawable-xxhdpi/task_megaphone.png new file mode 100644 index 000000000..cfdf2d825 Binary files /dev/null and b/Habitica/res/drawable-xxhdpi/task_megaphone.png differ diff --git a/Habitica/res/layout/daily_item_card.xml b/Habitica/res/layout/daily_item_card.xml index 56101009b..87105fc43 100644 --- a/Habitica/res/layout/daily_item_card.xml +++ b/Habitica/res/layout/daily_item_card.xml @@ -126,7 +126,7 @@ android:layout_marginStart="@dimen/task_icon_space" android:layout_marginLeft="@dimen/task_icon_space" android:contentDescription="@string/belongs_to_challenge" - app:srcCompat="@drawable/task_icon_challenge" /> + app:srcCompat="@drawable/task_megaphone" /> + android:orientation="vertical"> + app:srcCompat="@drawable/task_megaphone" /> + app:srcCompat="@drawable/task_megaphone" /> + android:orientation="vertical"> You only need %d %s to hatch all possible pets. Are you sure you want to purchase %d? Purchase %d You\'ve already hatched all possible %s pets. Are you sure you want to purchase %d %s? + Equip diff --git a/Habitica/res/xml/remote_config_defaults.xml b/Habitica/res/xml/remote_config_defaults.xml index 8944e9c24..47ecea4e3 100644 --- a/Habitica/res/xml/remote_config_defaults.xml +++ b/Habitica/res/xml/remote_config_defaults.xml @@ -84,5 +84,13 @@ reorderMenu false + + feedbackURL + + + + enableAdventureGuide + false + \ No newline at end of file diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/AppConfigManager.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/AppConfigManager.kt index 84d4fe20f..6a18d7bb3 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/AppConfigManager.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/AppConfigManager.kt @@ -85,6 +85,10 @@ class AppConfigManager { return remoteConfig.getBoolean("enableTaskDisplayMode") } + fun feedbackURL(): String { + return remoteConfig.getString("feedbackURL") + } + fun taskDisplayMode(context: Context): String { return if (remoteConfig.getBoolean("enableTaskDisplayMode")) { val preferences = PreferenceManager.getDefaultSharedPreferences(context) @@ -97,4 +101,8 @@ class AppConfigManager { fun reorderMenu(): Boolean { return remoteConfig.getBoolean("reorderMenu") } + + fun enableAdventureGuide(): Boolean { + return remoteConfig.getBoolean("enableAdventureGuide") + } } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/models/tasks/Task.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/models/tasks/Task.kt index 166ba9578..60af9bf85 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/models/tasks/Task.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/models/tasks/Task.kt @@ -33,6 +33,7 @@ open class Task : RealmObject, Parcelable { @TaskTypes var type: String = "" var challengeID: String? = null + var challengeBroken: String? = null var attribute: String? = Stats.STRENGTH var value: Double = 0.0 var tags: RealmList? = RealmList() 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 be6cc0e4c..05dccbb33 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 @@ -42,6 +42,7 @@ 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 @@ -690,6 +691,13 @@ open class MainActivity : BaseActivity(), TutorialView.OnTutorialReaction { @Subscribe fun showAchievementDialog(event: ShowAchievementDialog) { + if (User.ONBOARDING_ACHIEVEMENT_KEYS.contains(event.type) || event.type == Notification.Type.ACHIEVEMENT_ONBOARDING_COMPLETE.type) { + if (!appConfigManager.enableAdventureGuide()) { + apiClient.readNotification(event.id) + .subscribe(Consumer { }, RxErrorHandler.handleEmptyError()) + return + } + } compositeSubscription.add(Completable.complete() .observeOn(AndroidSchedulers.mainThread()) .subscribe(Action { @@ -704,6 +712,11 @@ open class MainActivity : BaseActivity(), TutorialView.OnTutorialReaction { @Subscribe fun showFirstDropDialog(event: ShowFirstDropDialog) { + if (!appConfigManager.enableAdventureGuide()) { + apiClient.readNotification(event.id) + .subscribe(Consumer { }, RxErrorHandler.handleEmptyError()) + return + } compositeSubscription.add(Completable.complete() .observeOn(AndroidSchedulers.mainThread()) .subscribe(Action { @@ -741,7 +754,10 @@ open class MainActivity : BaseActivity(), TutorialView.OnTutorialReaction { val dialog = HabiticaAlertDialog(this) dialog.setTitle(getString(R.string.hatched_pet_title, potionName, eggName)) dialog.setAdditionalContentView(petWrapper) - dialog.addButton(R.string.onwards, true) { hatchingDialog, _ -> hatchingDialog.dismiss() } + dialog.addButton(R.string.equip, true) { _, _ -> + inventoryRepository.equip(user, "pet", "Pet-" + egg.key + "-" + potion.key) + .subscribe(Consumer {}, RxErrorHandler.handleEmptyError()) + } dialog.addButton(R.string.share, false) { hatchingDialog, _ -> val event1 = ShareEvent() event1.sharedMessage = getString(R.string.share_hatched, potionName, eggName) @@ -754,6 +770,7 @@ open class MainActivity : BaseActivity(), TutorialView.OnTutorialReaction { EventBus.getDefault().post(event1) hatchingDialog.dismiss() } + dialog.setExtraCloseButtonVisibility(View.VISIBLE) dialog.enqueue() }.subscribe(Consumer { }, RxErrorHandler.handleEmptyError())) } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/NavigationDrawerFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/NavigationDrawerFragment.kt index 7c26029c3..50c0cabe0 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/NavigationDrawerFragment.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/NavigationDrawerFragment.kt @@ -284,8 +284,12 @@ class NavigationDrawerFragment : DialogFragment() { } val adventureGuideItem = getItemWithIdentifier(SIDEBAR_ADVENTURE_GUIDE) - adventureGuideItem?.isVisible = !user.hasCompletedOnboarding - adventureGuideItem?.user = user + if (configManager.enableAdventureGuide()) { + adventureGuideItem?.isVisible = !user.hasCompletedOnboarding + adventureGuideItem?.user = user + } else { + adventureGuideItem?.isVisible = false + } } override fun onDestroy() { diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/support/SupportMainFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/support/SupportMainFragment.kt index 5605177de..871286c21 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/support/SupportMainFragment.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/support/SupportMainFragment.kt @@ -8,6 +8,7 @@ import android.os.Bundle import android.view.LayoutInflater import android.view.View import android.view.ViewGroup +import androidx.core.net.toUri import com.habitrpg.android.habitica.R import com.habitrpg.android.habitica.components.UserComponent import com.habitrpg.android.habitica.data.FAQRepository @@ -51,7 +52,9 @@ class SupportMainFragment : BaseMainFragment() { MainNavigationController.navigate(R.id.bugFixFragment) } binding.suggestionsFeedbackWrapper.setOnClickListener { - sendEmail("[Android] Feedback") + val uriUrl = appConfigManager.feedbackURL().toUri() + val launchBrowser = Intent(Intent.ACTION_VIEW, uriUrl) + startActivity(launchBrowser) } compositeSubscription.add(Completable.fromAction { @@ -71,58 +74,4 @@ class SupportMainFragment : BaseMainFragment() { override fun injectFragment(component: UserComponent) { component.inject(this) } - - private val versionName: String by lazy { - try { - @Suppress("DEPRECATION") - activity?.packageManager?.getPackageInfo(activity?.packageName ?: "", 0)?.versionName ?: "" - } catch (e: PackageManager.NameNotFoundException) { - "" - } - } - - private val versionCode: Int by lazy { - try { - @Suppress("DEPRECATION") - activity?.packageManager?.getPackageInfo(activity?.packageName ?: "", 0)?.versionCode ?: 0 - } catch (e: PackageManager.NameNotFoundException) { - 0 - } - } - - private fun sendEmail(subject: String) { - val version = Build.VERSION.SDK_INT - val deviceName = deviceInfo?.name ?: DeviceName.getDeviceName() - val manufacturer = deviceInfo?.manufacturer ?: Build.MANUFACTURER - var bodyOfEmail = "Device: $manufacturer $deviceName" + - " \nAndroid Version: $version"+ - " \nAppVersion: " + getString(R.string.version_info, versionName, versionCode) - - if (appConfigManager.testingLevel().name != AppTestingLevel.PRODUCTION.name) { - bodyOfEmail += " ${appConfigManager.testingLevel().name}" - } - bodyOfEmail += " \nUser ID: $userId" - - val user = this.user - if (user != null) { - bodyOfEmail += " \nLevel: " + (user.stats?.lvl ?: 0) + - " \nClass: " + (if (user.preferences?.disableClasses == true) "Disabled" else (user.stats?.habitClass ?: "None")) + - " \nIs in Inn: " + (user.preferences?.sleep ?: false) + - " \nUses Costume: " + (user.preferences?.costume ?: false) + - " \nCustom Day Start: " + (user.preferences?.dayStart ?: 0) + - " \nTimezone Offset: " + (user.preferences?.timezoneOffset ?: 0) - } - - bodyOfEmail += " \nDetails:\n" - - activity?.let { - val emailIntent = Intent(Intent.ACTION_SENDTO) - val mailto = "mailto:" + appConfigManager.supportEmail() + - "?subject=" + Uri.encode(subject) + - "&body=" + Uri.encode(bodyOfEmail) - emailIntent.data = Uri.parse(mailto); - - startActivity(Intent.createChooser(emailIntent, "Choose an Email client :")) - } - } } \ No newline at end of file diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewHolders/tasks/BaseTaskViewHolder.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewHolders/tasks/BaseTaskViewHolder.kt index 3bfc591af..e1d560367 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewHolders/tasks/BaseTaskViewHolder.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewHolders/tasks/BaseTaskViewHolder.kt @@ -173,7 +173,9 @@ abstract class BaseTaskViewHolder constructor(itemView: View, var scoreTaskFunc: iconViewTag?.visibility = if (data.tags?.size ?: 0 > 0) View.VISIBLE else View.GONE iconViewChallenge?.visibility = if (task?.challengeID != null) View.VISIBLE else View.GONE - + if (task?.challengeID != null) { + iconViewChallenge?.setImageResource(if (task?.challengeBroken?.isNotBlank() == true) R.drawable.task_broken_megaphone else R.drawable.task_megaphone) + } configureSpecialTaskTextView(data) taskIconWrapper?.visibility = if (taskIconWrapperIsVisible) View.VISIBLE else View.GONE diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/dialogs/HabiticaAlertDialog.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/dialogs/HabiticaAlertDialog.kt index 9a626c6d7..17ffb9a41 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/dialogs/HabiticaAlertDialog.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/dialogs/HabiticaAlertDialog.kt @@ -31,6 +31,7 @@ open class HabiticaAlertDialog(context: Context) : AlertDialog(context, R.style. private var scrollingSeparator: View private var buttonsWrapper: LinearLayout private var noticeTextView: TextView + private var closeButton: Button internal var additionalContentView: View? = null @@ -58,6 +59,8 @@ open class HabiticaAlertDialog(context: Context) : AlertDialog(context, R.style. scrollingSeparator = view.findViewById(R.id.scrolling_separator) buttonsWrapper = view.findViewById(R.id.buttons_wrapper) noticeTextView = view.findViewById(R.id.notice_text_view) + closeButton = view.findViewById(R.id.close_button) + closeButton.setOnClickListener { dismiss() } dialogContainer.clipChildren = true dialogContainer.clipToOutline = true } @@ -128,6 +131,10 @@ open class HabiticaAlertDialog(context: Context) : AlertDialog(context, R.style. messageTextView.setPadding(padding, messageTextView.paddingTop, padding, messageTextView.paddingBottom) } + fun setExtraCloseButtonVisibility(visibility: Int) { + closeButton.visibility = visibility + } + private fun updateButtonLayout() { if (isScrollingLayout) { scrollingSeparator.visibility = View.VISIBLE diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/shops/PurchaseDialog.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/shops/PurchaseDialog.kt index b0e438c68..d087d95c5 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/shops/PurchaseDialog.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/shops/PurchaseDialog.kt @@ -365,6 +365,7 @@ class PurchaseDialog(context: Context, component: UserComponent?, val item: Shop alert.addButton(context.getString(R.string.purchaseX, quantity), false, false) { _, _ -> buyItem(quantity) } + alert.setExtraCloseButtonVisibility(View.VISIBLE) alert.show() } @@ -396,6 +397,12 @@ class PurchaseDialog(context: Context, component: UserComponent?, val item: Shop ownedCount += if (mount.owned) 1 else 0 } } + }.flatMap { inventoryRepository.getOwnedItems("eggs") }.doOnNext { + for (egg in it) { + if (egg.key == item.key) { + ownedCount += egg.numberOwned + } + } }.firstElement().subscribe { val remaining = 20 - ownedCount onResult(remaining) @@ -415,12 +422,19 @@ class PurchaseDialog(context: Context, component: UserComponent?, val item: Shop ownedCount += if (mount.owned) 1 else 0 } } + }.flatMap { inventoryRepository.getOwnedItems("hatchingPotions") }.doOnNext { + for (potion in it) { + if (potion.key == item.key) { + ownedCount += potion.numberOwned + } + } }.firstElement().subscribe { val remaining = 18 - ownedCount onResult(remaining) } + } else { + onResult(-1) } - onResult(-1) } } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/utils/TaskListDeserializer.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/utils/TaskListDeserializer.kt index 08276f405..7a89a3d58 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/utils/TaskListDeserializer.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/utils/TaskListDeserializer.kt @@ -73,6 +73,10 @@ class TaskListDeserializer : JsonDeserializer { task.streak = obj.get("streak")?.asInt if (obj.getAsJsonObject("challenge").has("id")) { task.challengeID = obj.getAsJsonObject("challenge").get("id").asString + + if (obj.getAsJsonObject("challenge").has("broken")) { + task.challengeBroken = obj.getAsJsonObject("challenge").get("broken").asString + } } try { task.counterUp = obj.get("counterUp")?.asInt diff --git a/Habitica/staff/release/output.json b/Habitica/staff/release/output.json new file mode 100644 index 000000000..047acfe0b --- /dev/null +++ b/Habitica/staff/release/output.json @@ -0,0 +1,20 @@ +{ + "version": 1, + "artifactType": { + "type": "APK", + "kind": "Directory" + }, + "applicationId": "com.habitrpg.android.habitica", + "variantName": "staffRelease", + "elements": [ + { + "type": "SINGLE", + "filters": [], + "properties": [], + "versionCode": 2439, + "versionName": "2439", + "enabled": true, + "outputFile": "Habitica-staff-release.apk" + } + ] +} \ No newline at end of file