multiple fixes
|
|
@ -2,8 +2,6 @@
|
||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
package="com.habitrpg.android.habitica"
|
package="com.habitrpg.android.habitica"
|
||||||
android:versionCode="104"
|
|
||||||
android:versionName="0.0.32"
|
|
||||||
android:screenOrientation="portrait"
|
android:screenOrientation="portrait"
|
||||||
android:installLocation="auto" >
|
android:installLocation="auto" >
|
||||||
|
|
||||||
|
|
|
||||||
27
Habitica/proguard-rules.pro
vendored
|
|
@ -21,7 +21,6 @@
|
||||||
-keepattributes Signature
|
-keepattributes Signature
|
||||||
-keepattributes *Annotation*
|
-keepattributes *Annotation*
|
||||||
-keepattributes Exceptions
|
-keepattributes Exceptions
|
||||||
-keep class sun.misc.Unsafe { *; }
|
|
||||||
|
|
||||||
#retrolambda
|
#retrolambda
|
||||||
-dontwarn java.lang.invoke.*
|
-dontwarn java.lang.invoke.*
|
||||||
|
|
@ -33,18 +32,10 @@
|
||||||
long consumerIndex;
|
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
|
#OkHttp
|
||||||
-keep class okhttp3.** { *; }
|
-keep class okhttp3.** { *; }
|
||||||
-keep,includedescriptorclasses class okio.Source
|
-keep,includedescriptorclasses class okio.Source
|
||||||
-keep,includedescriptorclasses class okio.okio.Buffer
|
|
||||||
-keep interface okhttp3.** { *; }
|
-keep interface okhttp3.** { *; }
|
||||||
-dontwarn okhttp3.**
|
-dontwarn okhttp3.**
|
||||||
|
|
||||||
|
|
@ -82,17 +73,6 @@
|
||||||
-keep class com.crashlytics.** { *; }
|
-keep class com.crashlytics.** { *; }
|
||||||
-dontwarn 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
|
# Keep native methods
|
||||||
-keepclassmembers class * {
|
-keepclassmembers class * {
|
||||||
native <methods>;
|
native <methods>;
|
||||||
|
|
@ -102,10 +82,6 @@
|
||||||
-keep class com.google.android.gms.ads.** { *; }
|
-keep class com.google.android.gms.ads.** { *; }
|
||||||
#end amplitude
|
#end amplitude
|
||||||
|
|
||||||
#playservices
|
|
||||||
-keep class * extends java.util.ListResourceBundle {
|
|
||||||
protected Object[][] getContents();
|
|
||||||
}
|
|
||||||
|
|
||||||
-keep public class com.google.android.gms.common.internal.safeparcel.SafeParcelable {
|
-keep public class com.google.android.gms.common.internal.safeparcel.SafeParcelable {
|
||||||
public static final *** NULL;
|
public static final *** NULL;
|
||||||
|
|
@ -138,9 +114,6 @@
|
||||||
|
|
||||||
#keep all enums
|
#keep all enums
|
||||||
-keepclassmembers enum * { *; }
|
-keepclassmembers enum * { *; }
|
||||||
-keep class Type {
|
|
||||||
public *;
|
|
||||||
}
|
|
||||||
-keepclassmembers class * extends java.lang.Enum {
|
-keepclassmembers class * extends java.lang.Enum {
|
||||||
<fields>;
|
<fields>;
|
||||||
public static **[] values();
|
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"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:orientation="vertical"
|
android:orientation="vertical">
|
||||||
android:background="?colorContentBackground">
|
|
||||||
|
|
||||||
<com.google.android.material.appbar.AppBarLayout
|
<com.google.android.material.appbar.AppBarLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
|
|
|
||||||
|
|
@ -3,8 +3,7 @@
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools">
|
||||||
android:background="?attr/colorContentBackground">
|
|
||||||
<FrameLayout
|
<FrameLayout
|
||||||
android:id="@+id/confetti_anchor"
|
android:id="@+id/confetti_anchor"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
|
|
|
||||||
|
|
@ -4,8 +4,7 @@
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:orientation="vertical"
|
android:orientation="vertical">
|
||||||
android:background="?attr/colorContentBackground">
|
|
||||||
|
|
||||||
<com.google.android.material.appbar.AppBarLayout
|
<com.google.android.material.appbar.AppBarLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
|
|
|
||||||
|
|
@ -2,9 +2,7 @@
|
||||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
|
||||||
android:background="?attr/colorContentBackground">
|
|
||||||
<FrameLayout
|
<FrameLayout
|
||||||
android:id="@+id/confetti_container"
|
android:id="@+id/confetti_container"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
|
|
|
||||||
|
|
@ -3,8 +3,7 @@
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent">
|
||||||
android:background="?attr/colorContentBackground">
|
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
|
|
|
||||||
|
|
@ -5,5 +5,4 @@
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
android:padding="8dp"
|
android:padding="8dp"/>
|
||||||
android:background="?attr/colorContentBackground"/>
|
|
||||||
|
|
|
||||||
|
|
@ -3,18 +3,19 @@
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:background="?colorPrimaryOffset"
|
|
||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
tools:context="com.habitrpg.android.habitica.ui.fragments.NavigationDrawerFragment">
|
tools:context="com.habitrpg.android.habitica.ui.fragments.NavigationDrawerFragment">
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:id="@+id/menuHeaderView"
|
android:id="@+id/menuHeaderView"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="64dp"
|
android:layout_height="wrap_content"
|
||||||
|
android:minHeight="64dp"
|
||||||
android:paddingStart="16dp"
|
android:paddingStart="16dp"
|
||||||
android:paddingEnd="1dp"
|
android:paddingEnd="1dp"
|
||||||
android:gravity="center_vertical"
|
android:gravity="center_vertical"
|
||||||
android:orientation="horizontal"
|
android:orientation="horizontal"
|
||||||
|
android:background="?colorPrimaryOffset"
|
||||||
android:baselineAligned="false">
|
android:baselineAligned="false">
|
||||||
|
|
||||||
<com.habitrpg.android.habitica.ui.views.RoundedCornerLayout
|
<com.habitrpg.android.habitica.ui.views.RoundedCornerLayout
|
||||||
|
|
@ -154,7 +155,6 @@
|
||||||
tools:text="1"
|
tools:text="1"
|
||||||
tools:visibility="visible" />
|
tools:visibility="visible" />
|
||||||
</RelativeLayout>
|
</RelativeLayout>
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
<com.habitrpg.android.habitica.ui.views.social.QuestMenuView
|
<com.habitrpg.android.habitica.ui.views.social.QuestMenuView
|
||||||
android:id="@+id/questMenuView"
|
android:id="@+id/questMenuView"
|
||||||
|
|
|
||||||
|
|
@ -4,8 +4,7 @@
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:id="@+id/refreshLayout"
|
android:id="@+id/refreshLayout">
|
||||||
android:background="?attr/colorContentBackground">
|
|
||||||
<androidx.core.widget.NestedScrollView
|
<androidx.core.widget.NestedScrollView
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent">
|
android:layout_height="match_parent">
|
||||||
|
|
|
||||||
|
|
@ -4,8 +4,7 @@
|
||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
tools:parentTag="android.widget.RelativeLayout"
|
tools:parentTag="android.widget.RelativeLayout">
|
||||||
android:background="?attr/colorWindowBackground">
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:id="@+id/contentWrapper"
|
android:id="@+id/contentWrapper"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
|
|
|
||||||
|
|
@ -4,8 +4,7 @@
|
||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
tools:parentTag="android.widget.RelativeLayout"
|
tools:parentTag="android.widget.RelativeLayout">
|
||||||
android:background="?attr/colorWindowBackground">
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:id="@+id/contentWrapper"
|
android:id="@+id/contentWrapper"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
|
|
|
||||||
|
|
@ -2,8 +2,7 @@
|
||||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent">
|
||||||
android:background="?attr/colorContentBackground">
|
|
||||||
|
|
||||||
<com.habitrpg.common.habitica.views.AvatarView
|
<com.habitrpg.common.habitica.views.AvatarView
|
||||||
android:id="@+id/avatar_view"
|
android:id="@+id/avatar_view"
|
||||||
|
|
|
||||||
|
|
@ -3,8 +3,7 @@
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content">
|
||||||
android:background="@color/transparent">
|
|
||||||
<ImageView
|
<ImageView
|
||||||
android:id="@+id/npc_image_view"
|
android:id="@+id/npc_image_view"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
|
|
|
||||||
|
|
@ -132,7 +132,7 @@
|
||||||
android:layout_gravity="center_vertical" />
|
android:layout_gravity="center_vertical" />
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<RelativeLayout
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="vertical">
|
android:orientation="vertical">
|
||||||
|
|
@ -141,106 +141,71 @@
|
||||||
android:id="@+id/divider"
|
android:id="@+id/divider"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="0dp"
|
android:layout_height="0dp"
|
||||||
android:layout_centerHorizontal="true"
|
|
||||||
android:visibility="invisible" />
|
android:visibility="invisible" />
|
||||||
|
|
||||||
<RelativeLayout
|
<LinearLayout
|
||||||
android:id="@+id/months_subscribed_layout"
|
|
||||||
style="@style/subscriptionBox"
|
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginEnd="5dp"
|
android:orientation="horizontal">
|
||||||
android:layout_marginBottom="6dp"
|
<LinearLayout
|
||||||
android:layout_toStartOf="@id/divider">
|
android:id="@+id/months_subscribed_layout"
|
||||||
|
style="@style/subscriptionBox"
|
||||||
<View
|
|
||||||
android:id="@+id/months_divider"
|
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="0dp"
|
android:layout_weight="1"
|
||||||
android:layout_centerHorizontal="true" />
|
android:layout_height="fill_parent"
|
||||||
|
android:orientation="vertical"
|
||||||
<ImageView
|
android:layout_marginEnd="@dimen/spacing_medium"
|
||||||
android:id="@+id/calendar_icon"
|
android:gravity="center">
|
||||||
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"/>
|
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/monthsSubscribedTextView"
|
android:id="@+id/monthsSubscribedTextView"
|
||||||
style="@style/subscriptionBoxCompactNumber"
|
style="@style/subscriptionBoxCompactNumber"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginStart="4dp"
|
app:drawableStartCompat="@drawable/calendar_ic"
|
||||||
android:layout_marginTop="8dp"
|
android:drawablePadding="@dimen/spacing_small"
|
||||||
android:layout_toEndOf="@id/calendar_icon"
|
|
||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
tools:text="2" />
|
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
|
<TextView
|
||||||
style="@style/subscriptionBoxCompactText"
|
style="@style/subscriptionBoxCompactText"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_below="@id/gem_icon"
|
android:text="@string/months_subscribed"
|
||||||
android:layout_centerHorizontal="true"
|
|
||||||
android:layout_marginTop="5dp"
|
|
||||||
android:text="@string/monthly_gem_cap"
|
|
||||||
android:gravity="center"
|
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
|
<TextView
|
||||||
android:id="@+id/gemCapTextView"
|
android:id="@+id/gemCapTextView"
|
||||||
style="@style/subscriptionBoxCompactNumber"
|
style="@style/subscriptionBoxCompactNumber"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginStart="4dp"
|
app:drawableStartCompat="@drawable/gem_ic"
|
||||||
android:layout_marginTop="10dp"
|
android:drawablePadding="@dimen/spacing_small"
|
||||||
android:layout_toEndOf="@id/gem_icon"
|
android:gravity="center"
|
||||||
tools:text="50" />
|
tools:text="2" />
|
||||||
</RelativeLayout>
|
<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
|
<RelativeLayout
|
||||||
android:id="@+id/next_hourglass_container"
|
android:id="@+id/next_hourglass_container"
|
||||||
style="@style/subscriptionBox"
|
style="@style/subscriptionBox"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content">
|
||||||
android:layout_below="@id/months_subscribed_layout">
|
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
android:layout_width="60dp"
|
android:layout_width="60dp"
|
||||||
|
|
@ -276,7 +241,7 @@
|
||||||
android:textColor="@color/text_secondary"/>
|
android:textColor="@color/text_secondary"/>
|
||||||
</RelativeLayout>
|
</RelativeLayout>
|
||||||
|
|
||||||
</RelativeLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
|
|
|
||||||
|
|
@ -740,8 +740,8 @@
|
||||||
<string name="server">Server</string>
|
<string name="server">Server</string>
|
||||||
<string name="gift_confirmation_title">Your gift was sent!</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_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_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_gems_new">You sent @%s %s gems.</string>
|
||||||
<string name="subscription_confirmation">You are now subscribed for 1 month</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="subscription_confirmation_multiple">You are now subscribed for %s months</string>
|
||||||
<string name="gem_purchase_confirmation">You gained %s gems.</string>
|
<string name="gem_purchase_confirmation">You gained %s gems.</string>
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,13 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<resources xmlns:tools="http://schemas.android.com/tools">
|
<resources xmlns:tools="http://schemas.android.com/tools">
|
||||||
<style name="ChallengeName">
|
<style name="ChallengeName">
|
||||||
<item name="android:fontFamily" tools:targetApi="jelly_bean">@string/font_family_condensed
|
<item name="android:fontFamily" >@string/font_family_condensed</item>
|
||||||
</item>
|
|
||||||
<item name="android:textSize">16sp</item>
|
<item name="android:textSize">16sp</item>
|
||||||
<item name="android:textColor">@color/text_primary</item>
|
<item name="android:textColor">@color/text_primary</item>
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<style name="ChallengeTaskDetails">
|
<style name="ChallengeTaskDetails">
|
||||||
<item name="android:fontFamily" tools:targetApi="jelly_bean">@string/font_family_regular
|
<item name="android:fontFamily" >@string/font_family_regular</item>
|
||||||
</item>
|
|
||||||
<item name="android:textSize">12sp</item>
|
<item name="android:textSize">12sp</item>
|
||||||
<item name="android:height">20dp</item>
|
<item name="android:height">20dp</item>
|
||||||
<item name="android:textColor">#8a000000</item>
|
<item name="android:textColor">#8a000000</item>
|
||||||
|
|
|
||||||
|
|
@ -494,7 +494,7 @@
|
||||||
|
|
||||||
<style name="SubscriptionListTitle" parent="GemPurchaseListItem">
|
<style name="SubscriptionListTitle" parent="GemPurchaseListItem">
|
||||||
<item name="android:layout_gravity">left|center_vertical</item>
|
<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="android:textSize">14sp</item>
|
||||||
<item name="paddingEnd">32dp</item>
|
<item name="paddingEnd">32dp</item>
|
||||||
</style>
|
</style>
|
||||||
|
|
@ -571,7 +571,7 @@
|
||||||
|
|
||||||
<style name="subscriptionBoxText.Title">
|
<style name="subscriptionBoxText.Title">
|
||||||
<item name="android:textSize">14sp</item>
|
<item name="android:textSize">14sp</item>
|
||||||
<item name="android:fontFamily" tools:targetApi="jelly_bean">
|
<item name="android:fontFamily" >
|
||||||
@string/font_family_medium
|
@string/font_family_medium
|
||||||
</item>
|
</item>
|
||||||
<item name="android:textColor">@color/text_primary</item>
|
<item name="android:textColor">@color/text_primary</item>
|
||||||
|
|
@ -580,7 +580,7 @@
|
||||||
|
|
||||||
<style name="subscriptionBoxText.Subtitle">
|
<style name="subscriptionBoxText.Subtitle">
|
||||||
<item name="android:textSize">14sp</item>
|
<item name="android:textSize">14sp</item>
|
||||||
<item name="android:fontFamily" tools:targetApi="jelly_bean">
|
<item name="android:fontFamily" >
|
||||||
@string/font_family_regular
|
@string/font_family_regular
|
||||||
</item>
|
</item>
|
||||||
<item name="android:textColor">@color/text_primary</item>
|
<item name="android:textColor">@color/text_primary</item>
|
||||||
|
|
@ -588,7 +588,7 @@
|
||||||
|
|
||||||
<style name="SubscriptionListDescription" parent="GemPurchaseListItemDescription">
|
<style name="SubscriptionListDescription" parent="GemPurchaseListItemDescription">
|
||||||
<item name="android:layout_marginBottom">24dp</item>
|
<item name="android:layout_marginBottom">24dp</item>
|
||||||
<item name="android:fontFamily" tools:targetApi="jelly_bean">
|
<item name="android:fontFamily" >
|
||||||
@string/font_family_condensed
|
@string/font_family_condensed
|
||||||
</item>
|
</item>
|
||||||
<item name="android:textSize">14sp</item>
|
<item name="android:textSize">14sp</item>
|
||||||
|
|
|
||||||
|
|
@ -26,4 +26,4 @@
|
||||||
"text": "test. todo",
|
"text": "test. todo",
|
||||||
"userId": "MOCK",
|
"userId": "MOCK",
|
||||||
"id": "66cb66bb-f04a-4219-bc60-664d1ec48f75"
|
"id": "66cb66bb-f04a-4219-bc60-664d1ec48f75"
|
||||||
},]
|
}]
|
||||||
|
|
|
||||||
|
|
@ -192,11 +192,12 @@ class PurchaseHandler(
|
||||||
activity: Activity,
|
activity: Activity,
|
||||||
skuDetails: SkuDetails,
|
skuDetails: SkuDetails,
|
||||||
recipient: String? = null,
|
recipient: String? = null,
|
||||||
|
recipientUsername: String? = null,
|
||||||
isSaleGemPurchase: Boolean = false
|
isSaleGemPurchase: Boolean = false
|
||||||
) {
|
) {
|
||||||
this.isSaleGemPurchase = isSaleGemPurchase
|
this.isSaleGemPurchase = isSaleGemPurchase
|
||||||
recipient?.let {
|
recipient?.let {
|
||||||
addGift(skuDetails.sku, it)
|
addGift(skuDetails.sku, it, recipientUsername ?: it)
|
||||||
}
|
}
|
||||||
val flowParams = BillingFlowParams.newBuilder()
|
val flowParams = BillingFlowParams.newBuilder()
|
||||||
.setSkuDetails(skuDetails)
|
.setSkuDetails(skuDetails)
|
||||||
|
|
@ -234,7 +235,7 @@ class PurchaseHandler(
|
||||||
CoroutineScope(Dispatchers.IO).launch(ExceptionHandler.coroutine()) {
|
CoroutineScope(Dispatchers.IO).launch(ExceptionHandler.coroutine()) {
|
||||||
consume(purchase)
|
consume(purchase)
|
||||||
}
|
}
|
||||||
displayConfirmationDialog(purchase, gift?.second)
|
displayConfirmationDialog(purchase, gift?.third)
|
||||||
} catch (throwable: Throwable) {
|
} catch (throwable: Throwable) {
|
||||||
handleError(throwable, purchase)
|
handleError(throwable, purchase)
|
||||||
}
|
}
|
||||||
|
|
@ -250,7 +251,7 @@ class PurchaseHandler(
|
||||||
CoroutineScope(Dispatchers.IO).launch(ExceptionHandler.coroutine()) {
|
CoroutineScope(Dispatchers.IO).launch(ExceptionHandler.coroutine()) {
|
||||||
consume(purchase)
|
consume(purchase)
|
||||||
}
|
}
|
||||||
displayConfirmationDialog(purchase, gift?.second)
|
displayConfirmationDialog(purchase, gift?.third)
|
||||||
} catch (throwable: Throwable) {
|
} catch (throwable: Throwable) {
|
||||||
handleError(throwable, purchase)
|
handleError(throwable, purchase)
|
||||||
}
|
}
|
||||||
|
|
@ -331,7 +332,7 @@ class PurchaseHandler(
|
||||||
val result = withContext(Dispatchers.IO) {
|
val result = withContext(Dispatchers.IO) {
|
||||||
billingClient.queryPurchasesAsync(BillingClient.SkuType.SUBS)
|
billingClient.queryPurchasesAsync(BillingClient.SkuType.SUBS)
|
||||||
}
|
}
|
||||||
var fallback: Purchase? = null
|
val fallback: Purchase? = null
|
||||||
if (result.billingResult.responseCode == BillingClient.BillingResponseCode.OK) {
|
if (result.billingResult.responseCode == BillingClient.BillingResponseCode.OK) {
|
||||||
return findMostRecentSubscription(result.purchasesList)
|
return findMostRecentSubscription(result.purchasesList)
|
||||||
}
|
}
|
||||||
|
|
@ -446,15 +447,15 @@ class PurchaseHandler(
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private const val PENDING_GIFTS_KEY = "PENDING_GIFTS_DATED"
|
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
|
private var preferences: SharedPreferences? = null
|
||||||
|
|
||||||
fun addGift(sku: String, userID: String) {
|
fun addGift(sku: String, userID: String, username: String) {
|
||||||
pendingGifts[sku] = Pair(Date(), userID)
|
pendingGifts[sku] = Triple(Date(), userID, username)
|
||||||
savePendingGifts()
|
savePendingGifts()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun removeGift(sku: String?): Pair<Date, String>? {
|
private fun removeGift(sku: String?): Triple<Date, String, String>? {
|
||||||
val gift = pendingGifts.remove(sku)
|
val gift = pendingGifts.remove(sku)
|
||||||
savePendingGifts()
|
savePendingGifts()
|
||||||
return gift
|
return gift
|
||||||
|
|
|
||||||
|
|
@ -72,7 +72,7 @@ class GiftSubscriptionActivity : PurchaseActivity() {
|
||||||
selectedSubscriptionSku?.let { sku -> purchaseSubscription(sku) }
|
selectedSubscriptionSku?.let { sku -> purchaseSubscription(sku) }
|
||||||
}
|
}
|
||||||
lifecycleScope.launch(ExceptionHandler.coroutine()) {
|
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.avatarView.setAvatar(member)
|
||||||
binding.displayNameTextView.username = member.profile?.name
|
binding.displayNameTextView.username = member.profile?.name
|
||||||
binding.displayNameTextView.tier = member.contributor?.level ?: 0
|
binding.displayNameTextView.tier = member.contributor?.level ?: 0
|
||||||
|
|
@ -139,7 +139,7 @@ class GiftSubscriptionActivity : PurchaseActivity() {
|
||||||
if (id.isEmpty()) {
|
if (id.isEmpty()) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
PurchaseHandler.addGift(sku.sku, id)
|
PurchaseHandler.addGift(sku.sku, id, giftedUsername ?: id)
|
||||||
purchaseHandler.purchase(this, sku)
|
purchaseHandler.purchase(this, sku)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -99,6 +99,7 @@ class ReportMessageActivity : BaseActivity() {
|
||||||
lifecycleScope.launch(ExceptionHandler.coroutine {
|
lifecycleScope.launch(ExceptionHandler.coroutine {
|
||||||
isReporting = false
|
isReporting = false
|
||||||
}) {
|
}) {
|
||||||
|
socialRepository.flagMessage(messageID ?: "", binding.additionalInfoEdittext.text.toString(), groupID)
|
||||||
finish()
|
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>() {
|
class ShopRecyclerAdapter : androidx.recyclerview.widget.RecyclerView.Adapter<androidx.recyclerview.widget.RecyclerView.ViewHolder>() {
|
||||||
|
|
||||||
|
var onNeedsRefresh: (() -> Unit)? = null
|
||||||
|
|
||||||
private val items: MutableList<Any> = ArrayList()
|
private val items: MutableList<Any> = ArrayList()
|
||||||
private var shopIdentifier: String? = null
|
private var shopIdentifier: String? = null
|
||||||
private var ownedItems: Map<String, OwnedItem> = HashMap()
|
private var ownedItems: Map<String, OwnedItem> = HashMap()
|
||||||
|
|
@ -94,6 +96,7 @@ class ShopRecyclerAdapter : androidx.recyclerview.widget.RecyclerView.Adapter<an
|
||||||
val viewHolder = ShopItemViewHolder(view)
|
val viewHolder = ShopItemViewHolder(view)
|
||||||
viewHolder.shopIdentifier = shopIdentifier
|
viewHolder.shopIdentifier = shopIdentifier
|
||||||
viewHolder
|
viewHolder
|
||||||
|
viewHolder
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -604,9 +604,6 @@ class NavigationDrawerFragment : DialogFragment() {
|
||||||
) {
|
) {
|
||||||
fragmentContainerView = activity?.findViewById(fragmentId)
|
fragmentContainerView = activity?.findViewById(fragmentId)
|
||||||
this.drawerLayout = drawerLayout
|
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
|
// set UP the drawer's list view with items and click listener
|
||||||
|
|
||||||
lifecycleScope.launchCatching {
|
lifecycleScope.launchCatching {
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,11 @@ import android.os.Bundle
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
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.core.os.bundleOf
|
||||||
import androidx.lifecycle.lifecycleScope
|
import androidx.lifecycle.lifecycleScope
|
||||||
import androidx.recyclerview.widget.GridLayoutManager
|
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.ShopCategory
|
||||||
import com.habitrpg.android.habitica.models.shops.ShopItem
|
import com.habitrpg.android.habitica.models.shops.ShopItem
|
||||||
import com.habitrpg.android.habitica.models.social.Group
|
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.adapter.inventory.ShopRecyclerAdapter
|
||||||
import com.habitrpg.android.habitica.ui.fragments.BaseMainFragment
|
import com.habitrpg.android.habitica.ui.fragments.BaseMainFragment
|
||||||
import com.habitrpg.android.habitica.ui.helpers.SafeDefaultItemAnimator
|
import com.habitrpg.android.habitica.ui.helpers.SafeDefaultItemAnimator
|
||||||
import com.habitrpg.android.habitica.ui.viewmodels.MainUserViewModel
|
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.android.habitica.ui.views.dialogs.HabiticaAlertDialog
|
||||||
import com.habitrpg.common.habitica.helpers.RecyclerViewState
|
import com.habitrpg.common.habitica.helpers.RecyclerViewState
|
||||||
import kotlinx.coroutines.flow.filter
|
import kotlinx.coroutines.flow.filter
|
||||||
|
|
@ -34,14 +38,16 @@ import javax.inject.Inject
|
||||||
|
|
||||||
open class ShopFragment : BaseMainFragment<FragmentRefreshRecyclerviewBinding>() {
|
open class ShopFragment : BaseMainFragment<FragmentRefreshRecyclerviewBinding>() {
|
||||||
|
|
||||||
internal val currencyView: CurrencyViews by lazy {
|
internal val currencyView: ComposeView by lazy {
|
||||||
val view = CurrencyViews(context)
|
return@lazy ComposeView(requireContext())
|
||||||
view
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var adapter: ShopRecyclerAdapter? = null
|
var adapter: ShopRecyclerAdapter? = null
|
||||||
var shopIdentifier: String? = null
|
var shopIdentifier: String? = null
|
||||||
var shop: Shop? = null
|
var shop: Shop? = null
|
||||||
|
internal val hourglasses = mutableStateOf<Double?>(null)
|
||||||
|
private val gems = mutableStateOf<Double?>(null)
|
||||||
|
private val gold = mutableStateOf<Double?>(null)
|
||||||
@Inject
|
@Inject
|
||||||
lateinit var inventoryRepository: InventoryRepository
|
lateinit var inventoryRepository: InventoryRepository
|
||||||
@Inject
|
@Inject
|
||||||
|
|
@ -79,6 +85,7 @@ open class ShopFragment : BaseMainFragment<FragmentRefreshRecyclerviewBinding>()
|
||||||
|
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
super.onViewCreated(view, savedInstanceState)
|
super.onViewCreated(view, savedInstanceState)
|
||||||
|
initializeCurrencyViews()
|
||||||
toolbarAccessoryContainer?.addView(currencyView)
|
toolbarAccessoryContainer?.addView(currencyView)
|
||||||
binding?.recyclerView?.setBackgroundResource(R.color.content_background)
|
binding?.recyclerView?.setBackgroundResource(R.color.content_background)
|
||||||
binding?.recyclerView?.onRefresh = {
|
binding?.recyclerView?.onRefresh = {
|
||||||
|
|
@ -90,6 +97,12 @@ open class ShopFragment : BaseMainFragment<FragmentRefreshRecyclerviewBinding>()
|
||||||
adapter = binding?.recyclerView?.adapter as? ShopRecyclerAdapter
|
adapter = binding?.recyclerView?.adapter as? ShopRecyclerAdapter
|
||||||
if (adapter == null) {
|
if (adapter == null) {
|
||||||
adapter = ShopRecyclerAdapter()
|
adapter = ShopRecyclerAdapter()
|
||||||
|
adapter?.onNeedsRefresh = {
|
||||||
|
loadShopInventory()
|
||||||
|
if (Shop.MARKET == shopIdentifier) {
|
||||||
|
loadMarketGear()
|
||||||
|
}
|
||||||
|
}
|
||||||
adapter?.context = context
|
adapter?.context = context
|
||||||
binding?.recyclerView?.adapter = adapter
|
binding?.recyclerView?.adapter = adapter
|
||||||
binding?.recyclerView?.itemAnimator = SafeDefaultItemAnimator()
|
binding?.recyclerView?.itemAnimator = SafeDefaultItemAnimator()
|
||||||
|
|
@ -102,7 +115,7 @@ open class ShopFragment : BaseMainFragment<FragmentRefreshRecyclerviewBinding>()
|
||||||
layoutManager = GridLayoutManager(context, 2)
|
layoutManager = GridLayoutManager(context, 2)
|
||||||
layoutManager?.spanSizeLookup = object : GridLayoutManager.SpanSizeLookup() {
|
layoutManager?.spanSizeLookup = object : GridLayoutManager.SpanSizeLookup() {
|
||||||
override fun getSpanSize(position: Int): Int {
|
override fun getSpanSize(position: Int): Int {
|
||||||
return if (adapter?.getItemViewType(position) ?: 0 < 3) {
|
return if ((adapter?.getItemViewType(position) ?: 0) < 3) {
|
||||||
layoutManager?.spanCount ?: 1
|
layoutManager?.spanCount ?: 1
|
||||||
} else {
|
} else {
|
||||||
1
|
1
|
||||||
|
|
@ -134,7 +147,9 @@ open class ShopFragment : BaseMainFragment<FragmentRefreshRecyclerviewBinding>()
|
||||||
|
|
||||||
userViewModel.user.observe(viewLifecycleOwner) {
|
userViewModel.user.observe(viewLifecycleOwner) {
|
||||||
adapter?.user = it
|
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()) {
|
lifecycleScope.launch(ExceptionHandler.coroutine()) {
|
||||||
|
|
@ -149,11 +164,18 @@ open class ShopFragment : BaseMainFragment<FragmentRefreshRecyclerviewBinding>()
|
||||||
|
|
||||||
view.post { setGridSpanCount(view.width) }
|
view.post { setGridSpanCount(view.width) }
|
||||||
|
|
||||||
currencyView.hourglassVisibility = View.GONE
|
|
||||||
|
|
||||||
context?.let { analyticsManager.logEvent("open_shop", bundleOf(Pair("shopIdentifier", shopIdentifier))) }
|
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) {
|
private fun showClassChangeDialog(classIdentifier: String) {
|
||||||
context?.let { context ->
|
context?.let { context ->
|
||||||
val alert = HabiticaAlertDialog(context)
|
val alert = HabiticaAlertDialog(context)
|
||||||
|
|
@ -295,10 +317,4 @@ open class ShopFragment : BaseMainFragment<FragmentRefreshRecyclerviewBinding>()
|
||||||
companion object {
|
companion object {
|
||||||
private const val SHOP_IDENTIFIER_KEY = "SHOP_IDENTIFIER_KEY"
|
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.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import com.habitrpg.android.habitica.models.shops.Shop
|
import com.habitrpg.android.habitica.models.shops.Shop
|
||||||
|
import com.habitrpg.android.habitica.ui.views.CurrencyText
|
||||||
|
|
||||||
class TimeTravelersShopFragment : ShopFragment() {
|
class TimeTravelersShopFragment : ShopFragment() {
|
||||||
override fun onCreateView(
|
override fun onCreateView(
|
||||||
|
|
@ -18,9 +19,12 @@ class TimeTravelersShopFragment : ShopFragment() {
|
||||||
|
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
super.onViewCreated(view, savedInstanceState)
|
super.onViewCreated(view, savedInstanceState)
|
||||||
|
initializeCurrencyViews()
|
||||||
|
}
|
||||||
|
|
||||||
currencyView.goldVisibility = View.GONE
|
override fun initializeCurrencyViews() {
|
||||||
currencyView.gemVisibility = View.GONE
|
currencyView.setContent {
|
||||||
currencyView.hourglassVisibility = View.VISIBLE
|
hourglasses.value?.let { CurrencyText(currency = "hourglasses", value = it) }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -126,7 +126,7 @@ class GemsPurchaseFragment : BaseFragment<FragmentGemPurchaseBinding>() {
|
||||||
|
|
||||||
private fun purchaseGems(view: GemPurchaseOptionsView?) {
|
private fun purchaseGems(view: GemPurchaseOptionsView?) {
|
||||||
val identifier = view?.sku ?: return
|
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() {
|
private fun showGiftGemsDialog() {
|
||||||
|
|
|
||||||
|
|
@ -88,7 +88,7 @@ class GiftPurchaseGemsFragment : BaseFragment<FragmentGiftGemPurchaseBinding>()
|
||||||
|
|
||||||
private fun purchaseGems(sku: SkuDetails) {
|
private fun purchaseGems(sku: SkuDetails) {
|
||||||
giftedMember?.id?.let {
|
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)
|
private val binding = RowShopitemBinding.bind(itemView)
|
||||||
var shopIdentifier: String? = null
|
var shopIdentifier: String? = null
|
||||||
private var item: ShopItem? = null
|
private var item: ShopItem? = null
|
||||||
|
var onNeedsRefresh: (() -> Unit)? = null
|
||||||
|
|
||||||
private var context: Context = itemView.context
|
private var context: Context = itemView.context
|
||||||
|
|
||||||
|
|
@ -101,6 +102,9 @@ class ShopItemViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView), Vi
|
||||||
dialog.purchaseCardAction = {
|
dialog.purchaseCardAction = {
|
||||||
purchaseCardAction?.invoke(it)
|
purchaseCardAction?.invoke(it)
|
||||||
}
|
}
|
||||||
|
dialog.onGearPurchased = {
|
||||||
|
onNeedsRefresh?.invoke()
|
||||||
|
}
|
||||||
dialog.show()
|
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.helpers.KeyHelper
|
||||||
import com.habitrpg.common.habitica.models.auth.UserAuthResponse
|
import com.habitrpg.common.habitica.models.auth.UserAuthResponse
|
||||||
import com.willowtreeapps.signinwithapplebutton.SignInWithAppleConfiguration
|
import com.willowtreeapps.signinwithapplebutton.SignInWithAppleConfiguration
|
||||||
import kotlinx.coroutines.MainScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class AuthenticationViewModel() {
|
class AuthenticationViewModel() {
|
||||||
|
|
@ -111,7 +112,7 @@ class AuthenticationViewModel() {
|
||||||
val scopesString = Scopes.PROFILE + " " + Scopes.EMAIL
|
val scopesString = Scopes.PROFILE + " " + Scopes.EMAIL
|
||||||
val scopes = "oauth2:$scopesString"
|
val scopes = "oauth2:$scopesString"
|
||||||
var newUser = false
|
var newUser = false
|
||||||
MainScope().launchCatching({ throwable ->
|
CoroutineScope(Dispatchers.IO).launchCatching({ throwable ->
|
||||||
if (recoverFromPlayServicesErrorResult == null) return@launchCatching
|
if (recoverFromPlayServicesErrorResult == null) return@launchCatching
|
||||||
throwable.cause?.let {
|
throwable.cause?.let {
|
||||||
if (GoogleAuthException::class.java.isAssignableFrom(it.javaClass)) {
|
if (GoogleAuthException::class.java.isAssignableFrom(it.javaClass)) {
|
||||||
|
|
|
||||||
|
|
@ -106,6 +106,7 @@ fun AppHeaderView(
|
||||||
value = user?.stats?.exp ?: 0.0,
|
value = user?.stats?.exp ?: 0.0,
|
||||||
maxValue = user?.stats?.toNextLevel?.toDouble() ?: 0.0,
|
maxValue = user?.stats?.toNextLevel?.toDouble() ?: 0.0,
|
||||||
displayCompact = teamPlan != null,
|
displayCompact = teamPlan != null,
|
||||||
|
abbreviateValue = false,
|
||||||
modifier = Modifier.weight(1f)
|
modifier = Modifier.weight(1f)
|
||||||
)
|
)
|
||||||
if (user?.hasClass == true) {
|
if (user?.hasClass == true) {
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,10 @@
|
||||||
package com.habitrpg.android.habitica.ui.views
|
package com.habitrpg.android.habitica.ui.views
|
||||||
|
|
||||||
|
import androidx.compose.animation.core.animateFloatAsState
|
||||||
import androidx.compose.foundation.Image
|
import androidx.compose.foundation.Image
|
||||||
import androidx.compose.foundation.layout.Row
|
import androidx.compose.foundation.layout.Row
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.material.ProgressIndicatorDefaults
|
||||||
import androidx.compose.material.Text
|
import androidx.compose.material.Text
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
|
|
@ -23,6 +25,10 @@ fun CurrencyText(
|
||||||
decimals: Int = 2,
|
decimals: Int = 2,
|
||||||
minForAbbrevation: Int = 0
|
minForAbbrevation: Int = 0
|
||||||
) {
|
) {
|
||||||
|
val animatedValue = animateFloatAsState(
|
||||||
|
targetValue = value.toFloat(),
|
||||||
|
animationSpec = ProgressIndicatorDefaults.ProgressAnimationSpec,
|
||||||
|
).value
|
||||||
Row(verticalAlignment = Alignment.CenterVertically, modifier = modifier) {
|
Row(verticalAlignment = Alignment.CenterVertically, modifier = modifier) {
|
||||||
when (currency) {
|
when (currency) {
|
||||||
"gold" -> HabiticaIconsHelper.imageOfGold()
|
"gold" -> HabiticaIconsHelper.imageOfGold()
|
||||||
|
|
@ -31,7 +37,7 @@ fun CurrencyText(
|
||||||
else -> null
|
else -> null
|
||||||
}?.asImageBitmap()?.let { Image(it, null, Modifier.padding(end = 5.dp)) }
|
}?.asImageBitmap()?.let { Image(it, null, Modifier.padding(end = 5.dp)) }
|
||||||
Text(
|
Text(
|
||||||
NumberAbbreviator.abbreviate(null, value, decimals, minForAbbrevation),
|
NumberAbbreviator.abbreviate(null, animatedValue, decimals, minForAbbrevation),
|
||||||
color = when (currency) {
|
color = when (currency) {
|
||||||
"gold" -> colorResource(R.color.text_gold)
|
"gold" -> colorResource(R.color.text_gold)
|
||||||
"gems" -> colorResource(R.color.text_green)
|
"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.R
|
||||||
import com.habitrpg.android.habitica.ui.theme.HabiticaTheme
|
import com.habitrpg.android.habitica.ui.theme.HabiticaTheme
|
||||||
import com.habitrpg.common.habitica.helpers.NumberAbbreviator
|
import com.habitrpg.common.habitica.helpers.NumberAbbreviator
|
||||||
|
import java.text.NumberFormat
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun LabeledBar(
|
fun LabeledBar(
|
||||||
|
|
@ -47,14 +48,19 @@ fun LabeledBar(
|
||||||
maxValue: Double,
|
maxValue: Double,
|
||||||
displayCompact: Boolean = false,
|
displayCompact: Boolean = false,
|
||||||
barHeight: Dp = 8.dp,
|
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(
|
val animatedValue = animateFloatAsState(
|
||||||
targetValue = value.toFloat(),
|
targetValue = value.toFloat(),
|
||||||
animationSpec = ProgressIndicatorDefaults.ProgressAnimationSpec,
|
animationSpec = ProgressIndicatorDefaults.ProgressAnimationSpec,
|
||||||
).value
|
).value
|
||||||
|
val formatter = NumberFormat.getNumberInstance()
|
||||||
|
formatter.minimumFractionDigits = 0
|
||||||
|
formatter.maximumFractionDigits = 2
|
||||||
Row(
|
Row(
|
||||||
verticalAlignment = Alignment.CenterVertically,
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
modifier = modifier.alpha(if (disabled) 0.5f else 1.0f)
|
modifier = modifier.alpha(if (disabled) 0.5f else 1.0f)
|
||||||
|
|
@ -70,7 +76,7 @@ fun LabeledBar(
|
||||||
}
|
}
|
||||||
Column(modifier = Modifier.weight(1f)) {
|
Column(modifier = Modifier.weight(1f)) {
|
||||||
LinearProgressIndicator(
|
LinearProgressIndicator(
|
||||||
progress = (animatedValue / cleanedMaxVlaue).toFloat(),
|
progress = (animatedValue / cleanedMaxValue).toFloat(),
|
||||||
Modifier
|
Modifier
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
.clip(CircleShape)
|
.clip(CircleShape)
|
||||||
|
|
@ -84,8 +90,18 @@ fun LabeledBar(
|
||||||
modifier = Modifier.padding(top = 2.dp)
|
modifier = Modifier.padding(top = 2.dp)
|
||||||
) {
|
) {
|
||||||
if (!disabled) {
|
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(
|
Text(
|
||||||
"${NumberAbbreviator.abbreviate(LocalContext.current, animatedValue)} / ${NumberAbbreviator.abbreviate(LocalContext.current, cleanedMaxVlaue)}",
|
"$currentValueText / $maxValueText",
|
||||||
fontSize = 12.sp,
|
fontSize = 12.sp,
|
||||||
color = colorResource(R.color.text_ternary)
|
color = colorResource(R.color.text_ternary)
|
||||||
)
|
)
|
||||||
|
|
@ -118,7 +134,18 @@ private fun Preview() {
|
||||||
color = colorResource(R.color.xpColor),
|
color = colorResource(R.color.xpColor),
|
||||||
value = 100123.0,
|
value = 100123.0,
|
||||||
maxValue = 50000000000000.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(
|
LabeledBar(
|
||||||
icon = HabiticaIconsHelper.imageOfMagic(),
|
icon = HabiticaIconsHelper.imageOfMagic(),
|
||||||
|
|
|
||||||
|
|
@ -96,13 +96,11 @@ class SubscriptionDetailsView : LinearLayout {
|
||||||
|
|
||||||
binding.monthsSubscribedTextView.text = plan.consecutive?.count.toString()
|
binding.monthsSubscribedTextView.text = plan.consecutive?.count.toString()
|
||||||
|
|
||||||
|
|
||||||
binding.gemCapTextView.text = plan.totalNumberOfGems.toString()
|
binding.gemCapTextView.text = plan.totalNumberOfGems.toString()
|
||||||
|
|
||||||
if (plan.isActive && plan.dateTerminated == null) {
|
if (plan.isActive && plan.dateTerminated == null) {
|
||||||
plan.monthsUntilNextHourglass?.let { nextHourglass ->
|
|
||||||
val now = LocalDate.now()
|
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) {
|
val format = if (now.year != nextHourglassDate.year) {
|
||||||
"MM YYYY"
|
"MM YYYY"
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -111,7 +109,6 @@ class SubscriptionDetailsView : LinearLayout {
|
||||||
val nextHourglassMonth = nextHourglassDate.format(DateTimeFormatter.ofPattern(format))
|
val nextHourglassMonth = nextHourglassDate.format(DateTimeFormatter.ofPattern(format))
|
||||||
nextHourglassMonth?.let { binding.nextHourglassTextview.text = it }
|
nextHourglassMonth?.let { binding.nextHourglassTextview.text = it }
|
||||||
binding.nextHourglassContainer.isVisible = true
|
binding.nextHourglassContainer.isVisible = true
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
binding.nextHourglassContainer.isVisible = false
|
binding.nextHourglassContainer.isVisible = false
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@ object NumberAbbreviator {
|
||||||
}
|
}
|
||||||
|
|
||||||
fun abbreviate(context: Context?, number: Double, numberOfDecimals: Int = 2, minForAbbrevation: Int = 0): String {
|
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 usedNumber = number
|
||||||
var counter = 0
|
var counter = 0
|
||||||
while (usedNumber >= 1000 && number >= minForAbbrevation) {
|
while (usedNumber >= 1000 && number >= minForAbbrevation) {
|
||||||
|
|
@ -19,7 +20,7 @@ object NumberAbbreviator {
|
||||||
usedNumber /= 1000
|
usedNumber /= 1000
|
||||||
}
|
}
|
||||||
var pattern = "###"
|
var pattern = "###"
|
||||||
if (numberOfDecimals > 0) {
|
if (decimalCount > 0) {
|
||||||
pattern = ("$pattern.").padEnd(4 + numberOfDecimals, '#')
|
pattern = ("$pattern.").padEnd(4 + numberOfDecimals, '#')
|
||||||
}
|
}
|
||||||
val formatter = DecimalFormat(pattern + abbreviationForCounter(context, counter).replace(".", ""))
|
val formatter = DecimalFormat(pattern + abbreviationForCounter(context, counter).replace(".", ""))
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,2 @@
|
||||||
fabric_key=
|
|
||||||
facebook_app_id=
|
|
||||||
amplitude_app_id=
|
amplitude_app_id=
|
||||||
application_ad_id=
|
application_ad_id=
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@ kotlin {
|
||||||
val commonMain by getting {
|
val commonMain by getting {
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.4")
|
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 {
|
val commonTest by getting {
|
||||||
|
|
|
||||||
|
|
@ -1,2 +1,2 @@
|
||||||
NAME=4.1
|
NAME=4.1
|
||||||
CODE=4831
|
CODE=4841
|
||||||