Finish up AG
|
|
@ -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"
|
||||
}
|
||||
|
||||
|
|
|
|||
BIN
Habitica/res/drawable-hdpi/task_broken_megaphone.png
Normal file
|
After Width: | Height: | Size: 648 B |
|
Before Width: | Height: | Size: 364 B |
BIN
Habitica/res/drawable-hdpi/task_megaphone.png
Normal file
|
After Width: | Height: | Size: 575 B |
BIN
Habitica/res/drawable-mdpi/task_broken_megaphone.png
Normal file
|
After Width: | Height: | Size: 443 B |
|
Before Width: | Height: | Size: 282 B |
BIN
Habitica/res/drawable-mdpi/task_megaphone.png
Normal file
|
After Width: | Height: | Size: 412 B |
BIN
Habitica/res/drawable-xhdpi/task_broken_megaphone.png
Normal file
|
After Width: | Height: | Size: 827 B |
|
Before Width: | Height: | Size: 442 B |
BIN
Habitica/res/drawable-xhdpi/task_megaphone.png
Normal file
|
After Width: | Height: | Size: 737 B |
BIN
Habitica/res/drawable-xxhdpi/task_broken_megaphone.png
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 578 B |
BIN
Habitica/res/drawable-xxhdpi/task_megaphone.png
Normal file
|
After Width: | Height: | Size: 1,012 B |
|
|
@ -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" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/iconviewReminder"
|
||||
|
|
@ -176,8 +176,7 @@
|
|||
android:layout_width="@dimen/checklist_wrapper_width"
|
||||
android:layout_height="match_parent"
|
||||
android:gravity="center"
|
||||
android:orientation="vertical"
|
||||
tools:background="@color/md_green_300">
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/checkListCompletedTextView"
|
||||
|
|
|
|||
|
|
@ -122,7 +122,7 @@
|
|||
android:layout_height="@dimen/task_icon_size"
|
||||
android:layout_marginStart="@dimen/task_icon_space"
|
||||
android:contentDescription="@string/belongs_to_challenge"
|
||||
app:srcCompat="@drawable/task_icon_challenge" />
|
||||
app:srcCompat="@drawable/task_megaphone" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/iconviewReminder"
|
||||
|
|
|
|||
|
|
@ -113,7 +113,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" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/iconviewReminder"
|
||||
|
|
@ -157,8 +157,7 @@
|
|||
android:layout_width="@dimen/checklist_wrapper_width"
|
||||
android:layout_height="match_parent"
|
||||
android:gravity="center"
|
||||
android:orientation="vertical"
|
||||
tools:background="@color/md_green_300">
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/checkListCompletedTextView"
|
||||
|
|
|
|||
|
|
@ -1056,4 +1056,5 @@
|
|||
<string name="excessItemsXLeft">You only need %d %s to hatch all possible pets. Are you sure you want to purchase %d?</string>
|
||||
<string name="purchaseX">Purchase %d</string>
|
||||
<string name="excessItemsNoneLeft">You\'ve already hatched all possible %s pets. Are you sure you want to purchase %d %s?</string>
|
||||
<string name="equip">Equip</string>
|
||||
</resources>
|
||||
|
|
|
|||
|
|
@ -84,5 +84,13 @@
|
|||
<key>reorderMenu</key>
|
||||
<value>false</value>
|
||||
</entry>
|
||||
<entry>
|
||||
<key>feedbackURL</key>
|
||||
<value></value>
|
||||
</entry>
|
||||
<entry>
|
||||
<key>enableAdventureGuide</key>
|
||||
<value>false</value>
|
||||
</entry>
|
||||
</defaultsMap>
|
||||
<!-- END xml_defaults -->
|
||||
|
|
@ -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")
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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<Tag>? = RealmList()
|
||||
|
|
|
|||
|
|
@ -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()))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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() {
|
||||
|
|
|
|||
|
|
@ -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 :"))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -73,6 +73,10 @@ class TaskListDeserializer : JsonDeserializer<TaskList> {
|
|||
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
|
||||
|
|
|
|||
20
Habitica/staff/release/output.json
Normal file
|
|
@ -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"
|
||||
}
|
||||
]
|
||||
}
|
||||