multiple fixes

This commit is contained in:
Phillip Thelen 2022-12-19 14:40:02 +01:00
parent c263d27e7c
commit bc685cdc82
64 changed files with 192 additions and 304 deletions

View file

@ -2,8 +2,6 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.habitrpg.android.habitica"
android:versionCode="104"
android:versionName="0.0.32"
android:screenOrientation="portrait"
android:installLocation="auto" >

View file

@ -21,7 +21,6 @@
-keepattributes Signature
-keepattributes *Annotation*
-keepattributes Exceptions
-keep class sun.misc.Unsafe { *; }
#retrolambda
-dontwarn java.lang.invoke.*
@ -33,18 +32,10 @@
long consumerIndex;
}
-keepclassmembers class rx.internal.util.unsafe.BaseLinkedQueueProducerNodeRef {
rx.internal.util.atomic.LinkedQueueNode producerNode;
}
-keepclassmembers class rx.internal.util.unsafe.BaseLinkedQueueConsumerNodeRef {
rx.internal.util.atomic.LinkedQueueNode consumerNode;
}
#OkHttp
-keep class okhttp3.** { *; }
-keep,includedescriptorclasses class okio.Source
-keep,includedescriptorclasses class okio.okio.Buffer
-keep interface okhttp3.** { *; }
-dontwarn okhttp3.**
@ -82,17 +73,6 @@
-keep class com.crashlytics.** { *; }
-dontwarn com.crashlytics.**
#fresko
# Keep our interfaces so they can be used by other ProGuard rules.
# See http://sourceforge.net/p/proguard/bugs/466/
-keep,allowobfuscation @interface com.facebook.common.internal.DoNotStrip
# Do not strip any method/class that is annotated with @DoNotStrip
-keep @com.facebook.common.internal.DoNotStrip class *
-keepclassmembers class * {
@com.facebook.common.internal.DoNotStrip *;
}
# Keep native methods
-keepclassmembers class * {
native <methods>;
@ -102,10 +82,6 @@
-keep class com.google.android.gms.ads.** { *; }
#end amplitude
#playservices
-keep class * extends java.util.ListResourceBundle {
protected Object[][] getContents();
}
-keep public class com.google.android.gms.common.internal.safeparcel.SafeParcelable {
public static final *** NULL;
@ -138,9 +114,6 @@
#keep all enums
-keepclassmembers enum * { *; }
-keep class Type {
public *;
}
-keepclassmembers class * extends java.lang.Enum {
<fields>;
public static **[] values();

Binary file not shown.

Before

Width:  |  Height:  |  Size: 127 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 381 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 209 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 90 B

View file

@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="@color/disabled_background" />
<corners android:radius="@dimen/bar_radius"/>
<padding android:left="0dip" android:top="0dip" android:right="0dip" android:bottom="0dip" />
</shape>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 299 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 153 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 111 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 421 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 248 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 672 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 344 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 475 B

View file

@ -1,19 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list
xmlns:android="http://schemas.android.com/apk/res/android" >
<item>
<shape android:shape="rectangle">
<solid android:color="@color/brand_200" />
</shape>
</item>
<item>
<bitmap
android:gravity="start|top"
android:src="@drawable/gold_coins_left" />
</item>
<item>
<bitmap
android:gravity="end|bottom"
android:src="@drawable/gold_coins_right" />
</item>
</layer-list>

View file

@ -1,6 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
<size android:width="24dp" android:height="80dp" />
<solid android:color="?attr/colorWindowBackground" />
<corners android:topRightRadius="8dp" android:bottomRightRadius="8dp" />
</shape>

View file

@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="@color/blue_100" />
<corners android:radius="@dimen/rounded_button_radius"/>
<padding android:left="0dip" android:top="0dip" android:right="0dip" android:bottom="0dip" />
</shape>

View file

@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="@color/gray_1" />
<corners android:radius="@dimen/rounded_button_radius"/>
<padding android:left="0dip" android:top="0dip" android:right="0dip" android:bottom="0dip" />
</shape>

View file

@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="?attr/colorContentBackgroundOffset" />
<corners android:radius="@dimen/bar_radius"/>
<padding android:left="0dip" android:top="0dip" android:right="0dip" android:bottom="0dip" />
</shape>

View file

@ -1,7 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#f9f9f9" />
<corners android:radius="3dp"/>
<stroke android:color="#1a000000" android:width="1dp"/>
<padding android:left="0dip" android:top="0dip" android:right="0dip" android:bottom="0dip" />
</shape>

View file

@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="@color/offset_background" />
<corners android:radius="@dimen/rounded_button_radius"/>
<padding android:left="0dip" android:top="0dip" android:right="0dip" android:bottom="0dip" />
</shape>

View file

@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="?colorPrimaryDark" />
<corners android:radius="@dimen/bar_radius"/>
<padding android:left="0dip" android:top="0dip" android:right="0dip" android:bottom="0dip" />
</shape>

View file

@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="@color/teal_50" />
<corners android:radius="@dimen/rounded_button_radius"/>
<padding android:left="0dip" android:top="0dip" android:right="0dip" android:bottom="0dip" />
</shape>

View file

@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="?attr/colorContentBackground" />
<corners android:radius="@dimen/rounded_button_radius"/>
<padding android:left="0dip" android:top="0dip" android:right="0dip" android:bottom="0dip" />
</shape>

View file

@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="@color/yellow_100" />
<corners android:radius="@dimen/rounded_button_radius"/>
<padding android:left="0dip" android:top="0dip" android:right="0dip" android:bottom="0dip" />
</shape>

View file

@ -1,5 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<size android:height="1dip" />
<solid android:color="@color/separator" />
</shape>

View file

@ -3,8 +3,7 @@
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="?colorContentBackground">
android:orientation="vertical">
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"

View file

@ -3,8 +3,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:background="?attr/colorContentBackground">
xmlns:tools="http://schemas.android.com/tools">
<FrameLayout
android:id="@+id/confetti_anchor"
android:layout_width="match_parent"

View file

@ -4,8 +4,7 @@
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="?attr/colorContentBackground">
android:orientation="vertical">
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"

View file

@ -2,9 +2,7 @@
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:background="?attr/colorContentBackground">
xmlns:app="http://schemas.android.com/apk/res-auto">
<FrameLayout
android:id="@+id/confetti_container"
android:layout_width="match_parent"

View file

@ -3,8 +3,7 @@
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?attr/colorContentBackground">
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"

View file

@ -5,5 +5,4 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="8dp"
android:background="?attr/colorContentBackground"/>
android:padding="8dp"/>

View file

@ -3,18 +3,19 @@
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?colorPrimaryOffset"
android:orientation="vertical"
tools:context="com.habitrpg.android.habitica.ui.fragments.NavigationDrawerFragment">
<LinearLayout
android:id="@+id/menuHeaderView"
android:layout_width="match_parent"
android:layout_height="64dp"
android:layout_height="wrap_content"
android:minHeight="64dp"
android:paddingStart="16dp"
android:paddingEnd="1dp"
android:gravity="center_vertical"
android:orientation="horizontal"
android:background="?colorPrimaryOffset"
android:baselineAligned="false">
<com.habitrpg.android.habitica.ui.views.RoundedCornerLayout
@ -154,7 +155,6 @@
tools:text="1"
tools:visibility="visible" />
</RelativeLayout>
</LinearLayout>
<com.habitrpg.android.habitica.ui.views.social.QuestMenuView
android:id="@+id/questMenuView"

View file

@ -4,8 +4,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/refreshLayout"
android:background="?attr/colorContentBackground">
android:id="@+id/refreshLayout">
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">

View file

@ -4,8 +4,7 @@
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:parentTag="android.widget.RelativeLayout"
android:background="?attr/colorWindowBackground">
tools:parentTag="android.widget.RelativeLayout">
<LinearLayout
android:id="@+id/contentWrapper"
android:layout_width="wrap_content"

View file

@ -4,8 +4,7 @@
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:parentTag="android.widget.RelativeLayout"
android:background="?attr/colorWindowBackground">
tools:parentTag="android.widget.RelativeLayout">
<LinearLayout
android:id="@+id/contentWrapper"
android:layout_width="wrap_content"

View file

@ -2,8 +2,7 @@
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?attr/colorContentBackground">
android:layout_height="match_parent">
<com.habitrpg.common.habitica.views.AvatarView
android:id="@+id/avatar_view"

View file

@ -3,8 +3,7 @@
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/transparent">
android:layout_height="wrap_content">
<ImageView
android:id="@+id/npc_image_view"
android:layout_width="wrap_content"

View file

@ -132,7 +132,7 @@
android:layout_gravity="center_vertical" />
</LinearLayout>
<RelativeLayout
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
@ -141,106 +141,71 @@
android:id="@+id/divider"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_centerHorizontal="true"
android:visibility="invisible" />
<RelativeLayout
android:id="@+id/months_subscribed_layout"
style="@style/subscriptionBox"
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginEnd="5dp"
android:layout_marginBottom="6dp"
android:layout_toStartOf="@id/divider">
<View
android:id="@+id/months_divider"
android:orientation="horizontal">
<LinearLayout
android:id="@+id/months_subscribed_layout"
style="@style/subscriptionBox"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_centerHorizontal="true" />
<ImageView
android:id="@+id/calendar_icon"
android:layout_width="25dp"
android:layout_height="25dp"
android:layout_marginTop="8dp"
android:layout_toStartOf="@id/months_divider"
android:src="@drawable/calendar_ic" />
<TextView
style="@style/subscriptionBoxCompactText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/calendar_icon"
android:layout_centerHorizontal="true"
android:layout_marginTop="8dp"
android:text="@string/months_subscribed"
android:gravity="center"
android:fontFamily="sans-serif-medium"/>
android:layout_weight="1"
android:layout_height="fill_parent"
android:orientation="vertical"
android:layout_marginEnd="@dimen/spacing_medium"
android:gravity="center">
<TextView
android:id="@+id/monthsSubscribedTextView"
style="@style/subscriptionBoxCompactNumber"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="4dp"
android:layout_marginTop="8dp"
android:layout_toEndOf="@id/calendar_icon"
app:drawableStartCompat="@drawable/calendar_ic"
android:drawablePadding="@dimen/spacing_small"
android:gravity="center"
tools:text="2" />
</RelativeLayout>
<RelativeLayout
style="@style/subscriptionBox"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="5dp"
android:layout_marginBottom="6dp"
android:layout_toEndOf="@id/divider">
<View
android:id="@+id/gem_divider"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_centerInParent="true" />
<ImageView
android:id="@+id/gem_icon"
android:layout_width="25dp"
android:layout_height="25dp"
android:layout_marginTop="10dp"
android:layout_toStartOf="@id/gem_divider"
android:src="@drawable/gem_ic" />
<TextView
style="@style/subscriptionBoxCompactText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/gem_icon"
android:layout_centerHorizontal="true"
android:layout_marginTop="5dp"
android:text="@string/monthly_gem_cap"
android:text="@string/months_subscribed"
android:gravity="center"
android:fontFamily="sans-serif-medium" />
android:fontFamily="sans-serif-medium"/>
</LinearLayout>
<LinearLayout
style="@style/subscriptionBox"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="fill_parent"
android:orientation="vertical"
android:gravity="center">
<TextView
android:id="@+id/gemCapTextView"
style="@style/subscriptionBoxCompactNumber"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="4dp"
android:layout_marginTop="10dp"
android:layout_toEndOf="@id/gem_icon"
tools:text="50" />
</RelativeLayout>
app:drawableStartCompat="@drawable/gem_ic"
android:drawablePadding="@dimen/spacing_small"
android:gravity="center"
tools:text="2" />
<TextView
style="@style/subscriptionBoxCompactText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/months_subscribed"
android:gravity="center"
android:fontFamily="sans-serif-medium"/>
</LinearLayout>
</LinearLayout>
<RelativeLayout
android:id="@+id/next_hourglass_container"
style="@style/subscriptionBox"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/months_subscribed_layout">
android:layout_height="wrap_content">
<ImageView
android:layout_width="60dp"
@ -276,7 +241,7 @@
android:textColor="@color/text_secondary"/>
</RelativeLayout>
</RelativeLayout>
</LinearLayout>
<TextView
android:layout_width="match_parent"

View file

@ -740,8 +740,8 @@
<string name="server">Server</string>
<string name="gift_confirmation_title">Your gift was sent!</string>
<string name="gift_confirmation_text_sub_g1g1">You sent %s a %s-month Habitica subscription and the same subscription was applied to your account for our Gift One Get One promotion!</string>
<string name="gift_confirmation_text_sub">You sent %s a %s-month Habitica subscription.</string>
<string name="gift_confirmation_text_gems_new">You sent %s %s gems.</string>
<string name="gift_confirmation_text_sub">You sent @%s a %s-month Habitica subscription.</string>
<string name="gift_confirmation_text_gems_new">You sent @%s %s gems.</string>
<string name="subscription_confirmation">You are now subscribed for 1 month</string>
<string name="subscription_confirmation_multiple">You are now subscribed for %s months</string>
<string name="gem_purchase_confirmation">You gained %s gems.</string>

View file

@ -1,15 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools">
<style name="ChallengeName">
<item name="android:fontFamily" tools:targetApi="jelly_bean">@string/font_family_condensed
</item>
<item name="android:fontFamily" >@string/font_family_condensed</item>
<item name="android:textSize">16sp</item>
<item name="android:textColor">@color/text_primary</item>
</style>
<style name="ChallengeTaskDetails">
<item name="android:fontFamily" tools:targetApi="jelly_bean">@string/font_family_regular
</item>
<item name="android:fontFamily" >@string/font_family_regular</item>
<item name="android:textSize">12sp</item>
<item name="android:height">20dp</item>
<item name="android:textColor">#8a000000</item>

View file

@ -494,7 +494,7 @@
<style name="SubscriptionListTitle" parent="GemPurchaseListItem">
<item name="android:layout_gravity">left|center_vertical</item>
<item name="android:fontFamily" tools:targetApi="jelly_bean">@string/font_family_medium</item>
<item name="android:fontFamily" >@string/font_family_medium</item>
<item name="android:textSize">14sp</item>
<item name="paddingEnd">32dp</item>
</style>
@ -571,7 +571,7 @@
<style name="subscriptionBoxText.Title">
<item name="android:textSize">14sp</item>
<item name="android:fontFamily" tools:targetApi="jelly_bean">
<item name="android:fontFamily" >
@string/font_family_medium
</item>
<item name="android:textColor">@color/text_primary</item>
@ -580,7 +580,7 @@
<style name="subscriptionBoxText.Subtitle">
<item name="android:textSize">14sp</item>
<item name="android:fontFamily" tools:targetApi="jelly_bean">
<item name="android:fontFamily" >
@string/font_family_regular
</item>
<item name="android:textColor">@color/text_primary</item>
@ -588,7 +588,7 @@
<style name="SubscriptionListDescription" parent="GemPurchaseListItemDescription">
<item name="android:layout_marginBottom">24dp</item>
<item name="android:fontFamily" tools:targetApi="jelly_bean">
<item name="android:fontFamily" >
@string/font_family_condensed
</item>
<item name="android:textSize">14sp</item>

View file

@ -26,4 +26,4 @@
"text": "test. todo",
"userId": "MOCK",
"id": "66cb66bb-f04a-4219-bc60-664d1ec48f75"
},]
}]

View file

@ -192,11 +192,12 @@ class PurchaseHandler(
activity: Activity,
skuDetails: SkuDetails,
recipient: String? = null,
recipientUsername: String? = null,
isSaleGemPurchase: Boolean = false
) {
this.isSaleGemPurchase = isSaleGemPurchase
recipient?.let {
addGift(skuDetails.sku, it)
addGift(skuDetails.sku, it, recipientUsername ?: it)
}
val flowParams = BillingFlowParams.newBuilder()
.setSkuDetails(skuDetails)
@ -234,7 +235,7 @@ class PurchaseHandler(
CoroutineScope(Dispatchers.IO).launch(ExceptionHandler.coroutine()) {
consume(purchase)
}
displayConfirmationDialog(purchase, gift?.second)
displayConfirmationDialog(purchase, gift?.third)
} catch (throwable: Throwable) {
handleError(throwable, purchase)
}
@ -250,7 +251,7 @@ class PurchaseHandler(
CoroutineScope(Dispatchers.IO).launch(ExceptionHandler.coroutine()) {
consume(purchase)
}
displayConfirmationDialog(purchase, gift?.second)
displayConfirmationDialog(purchase, gift?.third)
} catch (throwable: Throwable) {
handleError(throwable, purchase)
}
@ -331,7 +332,7 @@ class PurchaseHandler(
val result = withContext(Dispatchers.IO) {
billingClient.queryPurchasesAsync(BillingClient.SkuType.SUBS)
}
var fallback: Purchase? = null
val fallback: Purchase? = null
if (result.billingResult.responseCode == BillingClient.BillingResponseCode.OK) {
return findMostRecentSubscription(result.purchasesList)
}
@ -446,15 +447,15 @@ class PurchaseHandler(
companion object {
private const val PENDING_GIFTS_KEY = "PENDING_GIFTS_DATED"
private var pendingGifts: MutableMap<String, Pair<Date, String>> = HashMap()
private var pendingGifts: MutableMap<String, Triple<Date, String, String>> = HashMap()
private var preferences: SharedPreferences? = null
fun addGift(sku: String, userID: String) {
pendingGifts[sku] = Pair(Date(), userID)
fun addGift(sku: String, userID: String, username: String) {
pendingGifts[sku] = Triple(Date(), userID, username)
savePendingGifts()
}
private fun removeGift(sku: String?): Pair<Date, String>? {
private fun removeGift(sku: String?): Triple<Date, String, String>? {
val gift = pendingGifts.remove(sku)
savePendingGifts()
return gift

View file

@ -72,7 +72,7 @@ class GiftSubscriptionActivity : PurchaseActivity() {
selectedSubscriptionSku?.let { sku -> purchaseSubscription(sku) }
}
lifecycleScope.launch(ExceptionHandler.coroutine()) {
val member = socialRepository.retrieveMember(giftedUsername ?: giftedUserID, true) ?: return@launch
val member = socialRepository.retrieveMember(giftedUsername ?: giftedUserID) ?: return@launch
binding.avatarView.setAvatar(member)
binding.displayNameTextView.username = member.profile?.name
binding.displayNameTextView.tier = member.contributor?.level ?: 0
@ -139,7 +139,7 @@ class GiftSubscriptionActivity : PurchaseActivity() {
if (id.isEmpty()) {
return
}
PurchaseHandler.addGift(sku.sku, id)
PurchaseHandler.addGift(sku.sku, id, giftedUsername ?: id)
purchaseHandler.purchase(this, sku)
}
}

View file

@ -99,6 +99,7 @@ class ReportMessageActivity : BaseActivity() {
lifecycleScope.launch(ExceptionHandler.coroutine {
isReporting = false
}) {
socialRepository.flagMessage(messageID ?: "", binding.additionalInfoEdittext.text.toString(), groupID)
finish()
}
}

View file

@ -21,6 +21,8 @@ import com.habitrpg.android.habitica.ui.viewHolders.ShopItemViewHolder
class ShopRecyclerAdapter : androidx.recyclerview.widget.RecyclerView.Adapter<androidx.recyclerview.widget.RecyclerView.ViewHolder>() {
var onNeedsRefresh: (() -> Unit)? = null
private val items: MutableList<Any> = ArrayList()
private var shopIdentifier: String? = null
private var ownedItems: Map<String, OwnedItem> = HashMap()
@ -94,6 +96,7 @@ class ShopRecyclerAdapter : androidx.recyclerview.widget.RecyclerView.Adapter<an
val viewHolder = ShopItemViewHolder(view)
viewHolder.shopIdentifier = shopIdentifier
viewHolder
viewHolder
}
}

View file

@ -604,9 +604,6 @@ class NavigationDrawerFragment : DialogFragment() {
) {
fragmentContainerView = activity?.findViewById(fragmentId)
this.drawerLayout = drawerLayout
// set a custom shadow that overlays the main content when the drawer opens
this.drawerLayout?.setDrawerShadow(R.drawable.drawer_shadow, GravityCompat.START)
// set UP the drawer's list view with items and click listener
lifecycleScope.launchCatching {

View file

@ -4,6 +4,11 @@ import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Row
import androidx.compose.runtime.mutableStateOf
import androidx.compose.ui.platform.ComposeView
import androidx.compose.ui.unit.dp
import androidx.core.os.bundleOf
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.GridLayoutManager
@ -19,12 +24,11 @@ import com.habitrpg.android.habitica.models.shops.Shop
import com.habitrpg.android.habitica.models.shops.ShopCategory
import com.habitrpg.android.habitica.models.shops.ShopItem
import com.habitrpg.android.habitica.models.social.Group
import com.habitrpg.android.habitica.models.user.User
import com.habitrpg.android.habitica.ui.adapter.inventory.ShopRecyclerAdapter
import com.habitrpg.android.habitica.ui.fragments.BaseMainFragment
import com.habitrpg.android.habitica.ui.helpers.SafeDefaultItemAnimator
import com.habitrpg.android.habitica.ui.viewmodels.MainUserViewModel
import com.habitrpg.android.habitica.ui.views.CurrencyViews
import com.habitrpg.android.habitica.ui.views.CurrencyText
import com.habitrpg.android.habitica.ui.views.dialogs.HabiticaAlertDialog
import com.habitrpg.common.habitica.helpers.RecyclerViewState
import kotlinx.coroutines.flow.filter
@ -34,14 +38,16 @@ import javax.inject.Inject
open class ShopFragment : BaseMainFragment<FragmentRefreshRecyclerviewBinding>() {
internal val currencyView: CurrencyViews by lazy {
val view = CurrencyViews(context)
view
internal val currencyView: ComposeView by lazy {
return@lazy ComposeView(requireContext())
}
var adapter: ShopRecyclerAdapter? = null
var shopIdentifier: String? = null
var shop: Shop? = null
internal val hourglasses = mutableStateOf<Double?>(null)
private val gems = mutableStateOf<Double?>(null)
private val gold = mutableStateOf<Double?>(null)
@Inject
lateinit var inventoryRepository: InventoryRepository
@Inject
@ -79,6 +85,7 @@ open class ShopFragment : BaseMainFragment<FragmentRefreshRecyclerviewBinding>()
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
initializeCurrencyViews()
toolbarAccessoryContainer?.addView(currencyView)
binding?.recyclerView?.setBackgroundResource(R.color.content_background)
binding?.recyclerView?.onRefresh = {
@ -90,6 +97,12 @@ open class ShopFragment : BaseMainFragment<FragmentRefreshRecyclerviewBinding>()
adapter = binding?.recyclerView?.adapter as? ShopRecyclerAdapter
if (adapter == null) {
adapter = ShopRecyclerAdapter()
adapter?.onNeedsRefresh = {
loadShopInventory()
if (Shop.MARKET == shopIdentifier) {
loadMarketGear()
}
}
adapter?.context = context
binding?.recyclerView?.adapter = adapter
binding?.recyclerView?.itemAnimator = SafeDefaultItemAnimator()
@ -102,7 +115,7 @@ open class ShopFragment : BaseMainFragment<FragmentRefreshRecyclerviewBinding>()
layoutManager = GridLayoutManager(context, 2)
layoutManager?.spanSizeLookup = object : GridLayoutManager.SpanSizeLookup() {
override fun getSpanSize(position: Int): Int {
return if (adapter?.getItemViewType(position) ?: 0 < 3) {
return if ((adapter?.getItemViewType(position) ?: 0) < 3) {
layoutManager?.spanCount ?: 1
} else {
1
@ -134,7 +147,9 @@ open class ShopFragment : BaseMainFragment<FragmentRefreshRecyclerviewBinding>()
userViewModel.user.observe(viewLifecycleOwner) {
adapter?.user = it
updateCurrencyView(it)
hourglasses.value = it?.hourglassCount?.toDouble() ?: 0.0
gems.value = it?.gemCount?.toDouble() ?: 0.0
gold.value = it?.stats?.gp ?: 0.0
}
lifecycleScope.launch(ExceptionHandler.coroutine()) {
@ -149,11 +164,18 @@ open class ShopFragment : BaseMainFragment<FragmentRefreshRecyclerviewBinding>()
view.post { setGridSpanCount(view.width) }
currencyView.hourglassVisibility = View.GONE
context?.let { analyticsManager.logEvent("open_shop", bundleOf(Pair("shopIdentifier", shopIdentifier))) }
}
open fun initializeCurrencyViews() {
currencyView.setContent {
Row(horizontalArrangement = Arrangement.spacedBy(12.dp)) {
gems.value?.let { CurrencyText(currency = "gems", value = it) }
gold.value?.let { CurrencyText(currency = "gold", value = it) }
}
}
}
private fun showClassChangeDialog(classIdentifier: String) {
context?.let { context ->
val alert = HabiticaAlertDialog(context)
@ -295,10 +317,4 @@ open class ShopFragment : BaseMainFragment<FragmentRefreshRecyclerviewBinding>()
companion object {
private const val SHOP_IDENTIFIER_KEY = "SHOP_IDENTIFIER_KEY"
}
private fun updateCurrencyView(user: User?) {
currencyView.gold = user?.stats?.gp ?: 0.0
currencyView.gems = user?.gemCount?.toDouble() ?: 0.0
currencyView.hourglasses = user?.hourglassCount?.toDouble() ?: 0.0
}
}

View file

@ -5,6 +5,7 @@ import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import com.habitrpg.android.habitica.models.shops.Shop
import com.habitrpg.android.habitica.ui.views.CurrencyText
class TimeTravelersShopFragment : ShopFragment() {
override fun onCreateView(
@ -18,9 +19,12 @@ class TimeTravelersShopFragment : ShopFragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
initializeCurrencyViews()
}
currencyView.goldVisibility = View.GONE
currencyView.gemVisibility = View.GONE
currencyView.hourglassVisibility = View.VISIBLE
override fun initializeCurrencyViews() {
currencyView.setContent {
hourglasses.value?.let { CurrencyText(currency = "hourglasses", value = it) }
}
}
}

View file

@ -126,7 +126,7 @@ class GemsPurchaseFragment : BaseFragment<FragmentGemPurchaseBinding>() {
private fun purchaseGems(view: GemPurchaseOptionsView?) {
val identifier = view?.sku ?: return
activity?.let { purchaseHandler.purchase(it, identifier, null, isGemSaleHappening) }
activity?.let { purchaseHandler.purchase(it, identifier, null, null, isGemSaleHappening) }
}
private fun showGiftGemsDialog() {

View file

@ -88,7 +88,7 @@ class GiftPurchaseGemsFragment : BaseFragment<FragmentGiftGemPurchaseBinding>()
private fun purchaseGems(sku: SkuDetails) {
giftedMember?.id?.let {
activity?.let { it1 -> purchaseHandler?.purchase(it1, sku, it) }
activity?.let { it1 -> purchaseHandler?.purchase(it1, sku, it, giftedMember?.username) }
}
}
}

View file

@ -18,6 +18,7 @@ class ShopItemViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView), Vi
private val binding = RowShopitemBinding.bind(itemView)
var shopIdentifier: String? = null
private var item: ShopItem? = null
var onNeedsRefresh: (() -> Unit)? = null
private var context: Context = itemView.context
@ -101,6 +102,9 @@ class ShopItemViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView), Vi
dialog.purchaseCardAction = {
purchaseCardAction?.invoke(it)
}
dialog.onGearPurchased = {
onNeedsRefresh?.invoke()
}
dialog.show()
}
}

View file

@ -33,7 +33,8 @@ import com.habitrpg.common.habitica.api.HostConfig
import com.habitrpg.common.habitica.helpers.KeyHelper
import com.habitrpg.common.habitica.models.auth.UserAuthResponse
import com.willowtreeapps.signinwithapplebutton.SignInWithAppleConfiguration
import kotlinx.coroutines.MainScope
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import javax.inject.Inject
class AuthenticationViewModel() {
@ -111,7 +112,7 @@ class AuthenticationViewModel() {
val scopesString = Scopes.PROFILE + " " + Scopes.EMAIL
val scopes = "oauth2:$scopesString"
var newUser = false
MainScope().launchCatching({ throwable ->
CoroutineScope(Dispatchers.IO).launchCatching({ throwable ->
if (recoverFromPlayServicesErrorResult == null) return@launchCatching
throwable.cause?.let {
if (GoogleAuthException::class.java.isAssignableFrom(it.javaClass)) {

View file

@ -106,6 +106,7 @@ fun AppHeaderView(
value = user?.stats?.exp ?: 0.0,
maxValue = user?.stats?.toNextLevel?.toDouble() ?: 0.0,
displayCompact = teamPlan != null,
abbreviateValue = false,
modifier = Modifier.weight(1f)
)
if (user?.hasClass == true) {

View file

@ -1,8 +1,10 @@
package com.habitrpg.android.habitica.ui.views
import androidx.compose.animation.core.animateFloatAsState
import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.padding
import androidx.compose.material.ProgressIndicatorDefaults
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
@ -23,6 +25,10 @@ fun CurrencyText(
decimals: Int = 2,
minForAbbrevation: Int = 0
) {
val animatedValue = animateFloatAsState(
targetValue = value.toFloat(),
animationSpec = ProgressIndicatorDefaults.ProgressAnimationSpec,
).value
Row(verticalAlignment = Alignment.CenterVertically, modifier = modifier) {
when (currency) {
"gold" -> HabiticaIconsHelper.imageOfGold()
@ -31,7 +37,7 @@ fun CurrencyText(
else -> null
}?.asImageBitmap()?.let { Image(it, null, Modifier.padding(end = 5.dp)) }
Text(
NumberAbbreviator.abbreviate(null, value, decimals, minForAbbrevation),
NumberAbbreviator.abbreviate(null, animatedValue, decimals, minForAbbrevation),
color = when (currency) {
"gold" -> colorResource(R.color.text_gold)
"gems" -> colorResource(R.color.text_green)

View file

@ -35,6 +35,7 @@ import androidx.compose.ui.unit.sp
import com.habitrpg.android.habitica.R
import com.habitrpg.android.habitica.ui.theme.HabiticaTheme
import com.habitrpg.common.habitica.helpers.NumberAbbreviator
import java.text.NumberFormat
@Composable
fun LabeledBar(
@ -47,14 +48,19 @@ fun LabeledBar(
maxValue: Double,
displayCompact: Boolean = false,
barHeight: Dp = 8.dp,
disabled: Boolean = false
disabled: Boolean = false,
abbreviateValue: Boolean = true,
abbreviateMax: Boolean = true
) {
val cleanedMaxVlaue = java.lang.Double.max(1.0, maxValue)
val cleanedMaxValue = java.lang.Double.max(1.0, maxValue)
val animatedValue = animateFloatAsState(
targetValue = value.toFloat(),
animationSpec = ProgressIndicatorDefaults.ProgressAnimationSpec,
).value
val formatter = NumberFormat.getNumberInstance()
formatter.minimumFractionDigits = 0
formatter.maximumFractionDigits = 2
Row(
verticalAlignment = Alignment.CenterVertically,
modifier = modifier.alpha(if (disabled) 0.5f else 1.0f)
@ -70,7 +76,7 @@ fun LabeledBar(
}
Column(modifier = Modifier.weight(1f)) {
LinearProgressIndicator(
progress = (animatedValue / cleanedMaxVlaue).toFloat(),
progress = (animatedValue / cleanedMaxValue).toFloat(),
Modifier
.fillMaxWidth()
.clip(CircleShape)
@ -84,8 +90,18 @@ fun LabeledBar(
modifier = Modifier.padding(top = 2.dp)
) {
if (!disabled) {
val currentValueText = if (abbreviateValue) NumberAbbreviator.abbreviate(
LocalContext.current,
animatedValue,
0
) else formatter.format(animatedValue)
val maxValueText = if (abbreviateMax) NumberAbbreviator.abbreviate(
LocalContext.current,
cleanedMaxValue,
0
) else formatter.format(cleanedMaxValue)
Text(
"${NumberAbbreviator.abbreviate(LocalContext.current, animatedValue)} / ${NumberAbbreviator.abbreviate(LocalContext.current, cleanedMaxVlaue)}",
"$currentValueText / $maxValueText",
fontSize = 12.sp,
color = colorResource(R.color.text_ternary)
)
@ -118,7 +134,18 @@ private fun Preview() {
color = colorResource(R.color.xpColor),
value = 100123.0,
maxValue = 50000000000000.0,
displayCompact = false
displayCompact = false,
abbreviateValue = false
)
LabeledBar(
icon = HabiticaIconsHelper.imageOfExperience(),
label = stringResource(id = R.string.XP_default),
color = colorResource(R.color.xpColor),
value = 100123.0,
maxValue = 50000000000000.0,
displayCompact = false,
abbreviateValue = false,
abbreviateMax = false
)
LabeledBar(
icon = HabiticaIconsHelper.imageOfMagic(),

View file

@ -96,13 +96,11 @@ class SubscriptionDetailsView : LinearLayout {
binding.monthsSubscribedTextView.text = plan.consecutive?.count.toString()
binding.gemCapTextView.text = plan.totalNumberOfGems.toString()
if (plan.isActive && plan.dateTerminated == null) {
plan.monthsUntilNextHourglass?.let { nextHourglass ->
val now = LocalDate.now()
val nextHourglassDate = LocalDate.now().plusMonths(nextHourglass.toLong())
val nextHourglassDate = LocalDate.now().plusMonths(plan.monthsUntilNextHourglass.toLong())
val format = if (now.year != nextHourglassDate.year) {
"MM YYYY"
} else {
@ -111,7 +109,6 @@ class SubscriptionDetailsView : LinearLayout {
val nextHourglassMonth = nextHourglassDate.format(DateTimeFormatter.ofPattern(format))
nextHourglassMonth?.let { binding.nextHourglassTextview.text = it }
binding.nextHourglassContainer.isVisible = true
}
} else {
binding.nextHourglassContainer.isVisible = false
}

View file

@ -12,6 +12,7 @@ object NumberAbbreviator {
}
fun abbreviate(context: Context?, number: Double, numberOfDecimals: Int = 2, minForAbbrevation: Int = 0): String {
val decimalCount = if (number > -1 && number < 1 && numberOfDecimals == 0) 1 else numberOfDecimals
var usedNumber = number
var counter = 0
while (usedNumber >= 1000 && number >= minForAbbrevation) {
@ -19,7 +20,7 @@ object NumberAbbreviator {
usedNumber /= 1000
}
var pattern = "###"
if (numberOfDecimals > 0) {
if (decimalCount > 0) {
pattern = ("$pattern.").padEnd(4 + numberOfDecimals, '#')
}
val formatter = DecimalFormat(pattern + abbreviationForCounter(context, counter).replace(".", ""))

View file

@ -1,4 +1,2 @@
fabric_key=
facebook_app_id=
amplitude_app_id=
application_ad_id=

View file

@ -22,7 +22,7 @@ kotlin {
val commonMain by getting {
dependencies {
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.4")
implementation("io.realm.kotlin:library-base:1.0.2")
implementation("io.realm.kotlin:library-base:1.5.0")
}
}
val commonTest by getting {

View file

@ -1,2 +1,2 @@
NAME=4.1
CODE=4831
CODE=4841

View file