multiple fixes
|
|
@ -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" >
|
||||
|
||||
|
|
|
|||
27
Habitica/proguard-rules.pro
vendored
|
|
@ -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();
|
||||
|
|
|
|||
|
Before Width: | Height: | Size: 127 B |
|
Before Width: | Height: | Size: 381 B |
|
Before Width: | Height: | Size: 209 B |
|
Before Width: | Height: | Size: 90 B |
|
|
@ -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>
|
||||
|
Before Width: | Height: | Size: 299 B |
|
Before Width: | Height: | Size: 153 B |
|
Before Width: | Height: | Size: 111 B |
|
Before Width: | Height: | Size: 421 B |
|
Before Width: | Height: | Size: 248 B |
|
Before Width: | Height: | Size: 672 B |
|
Before Width: | Height: | Size: 344 B |
|
Before Width: | Height: | Size: 475 B |
|
|
@ -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>
|
||||
|
|
@ -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>
|
||||
|
|
@ -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>
|
||||
|
|
@ -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>
|
||||
|
|
@ -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>
|
||||
|
|
@ -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>
|
||||
|
|
@ -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>
|
||||
|
|
@ -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>
|
||||
|
|
@ -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>
|
||||
|
|
@ -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>
|
||||
|
|
@ -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>
|
||||
|
|
@ -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>
|
||||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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"/>
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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">
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -26,4 +26,4 @@
|
|||
"text": "test. todo",
|
||||
"userId": "MOCK",
|
||||
"id": "66cb66bb-f04a-4219-bc60-664d1ec48f75"
|
||||
},]
|
||||
}]
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -99,6 +99,7 @@ class ReportMessageActivity : BaseActivity() {
|
|||
lifecycleScope.launch(ExceptionHandler.coroutine {
|
||||
isReporting = false
|
||||
}) {
|
||||
socialRepository.flagMessage(messageID ?: "", binding.additionalInfoEdittext.text.toString(), groupID)
|
||||
finish()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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() {
|
||||
|
|
|
|||
|
|
@ -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) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)) {
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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(),
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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(".", ""))
|
||||
|
|
|
|||
|
|
@ -1,4 +1,2 @@
|
|||
fabric_key=
|
||||
facebook_app_id=
|
||||
amplitude_app_id=
|
||||
application_ad_id=
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -1,2 +1,2 @@
|
|||
NAME=4.1
|
||||
CODE=4831
|
||||
CODE=4841
|
||||