diff --git a/Habitica/res/drawable-hdpi/footer_hills.png b/Habitica/res/drawable-hdpi/footer_hills.png
new file mode 100644
index 000000000..7203cf5e5
Binary files /dev/null and b/Habitica/res/drawable-hdpi/footer_hills.png differ
diff --git a/Habitica/res/drawable-hdpi/footer_hills_g1g1.png b/Habitica/res/drawable-hdpi/footer_hills_g1g1.png
new file mode 100644
index 000000000..528e6448d
Binary files /dev/null and b/Habitica/res/drawable-hdpi/footer_hills_g1g1.png differ
diff --git a/Habitica/res/drawable-hdpi/footer_stars_left.png b/Habitica/res/drawable-hdpi/footer_stars_left.png
new file mode 100644
index 000000000..2fd902931
Binary files /dev/null and b/Habitica/res/drawable-hdpi/footer_stars_left.png differ
diff --git a/Habitica/res/drawable-hdpi/footer_stars_right.png b/Habitica/res/drawable-hdpi/footer_stars_right.png
new file mode 100644
index 000000000..b045f7717
Binary files /dev/null and b/Habitica/res/drawable-hdpi/footer_stars_right.png differ
diff --git a/Habitica/res/drawable-mdpi/footer_hills.png b/Habitica/res/drawable-mdpi/footer_hills.png
new file mode 100644
index 000000000..188f22031
Binary files /dev/null and b/Habitica/res/drawable-mdpi/footer_hills.png differ
diff --git a/Habitica/res/drawable-mdpi/footer_hills_g1g1.png b/Habitica/res/drawable-mdpi/footer_hills_g1g1.png
new file mode 100644
index 000000000..d8c7f67b6
Binary files /dev/null and b/Habitica/res/drawable-mdpi/footer_hills_g1g1.png differ
diff --git a/Habitica/res/drawable-mdpi/footer_stars_left.png b/Habitica/res/drawable-mdpi/footer_stars_left.png
new file mode 100644
index 000000000..7b6adc56e
Binary files /dev/null and b/Habitica/res/drawable-mdpi/footer_stars_left.png differ
diff --git a/Habitica/res/drawable-mdpi/footer_stars_right.png b/Habitica/res/drawable-mdpi/footer_stars_right.png
new file mode 100644
index 000000000..ce82ea69d
Binary files /dev/null and b/Habitica/res/drawable-mdpi/footer_stars_right.png differ
diff --git a/Habitica/res/drawable-xhdpi/footer_hills.png b/Habitica/res/drawable-xhdpi/footer_hills.png
new file mode 100644
index 000000000..03e1b2c4c
Binary files /dev/null and b/Habitica/res/drawable-xhdpi/footer_hills.png differ
diff --git a/Habitica/res/drawable-xhdpi/footer_hills_g1g1.png b/Habitica/res/drawable-xhdpi/footer_hills_g1g1.png
new file mode 100644
index 000000000..f51d93e19
Binary files /dev/null and b/Habitica/res/drawable-xhdpi/footer_hills_g1g1.png differ
diff --git a/Habitica/res/drawable-xhdpi/footer_stars_left.png b/Habitica/res/drawable-xhdpi/footer_stars_left.png
new file mode 100644
index 000000000..a68d54c9c
Binary files /dev/null and b/Habitica/res/drawable-xhdpi/footer_stars_left.png differ
diff --git a/Habitica/res/drawable-xhdpi/footer_stars_right.png b/Habitica/res/drawable-xhdpi/footer_stars_right.png
new file mode 100644
index 000000000..995a6dd2c
Binary files /dev/null and b/Habitica/res/drawable-xhdpi/footer_stars_right.png differ
diff --git a/Habitica/res/drawable-xxhdpi/footer_hills.png b/Habitica/res/drawable-xxhdpi/footer_hills.png
new file mode 100644
index 000000000..54b78eb16
Binary files /dev/null and b/Habitica/res/drawable-xxhdpi/footer_hills.png differ
diff --git a/Habitica/res/drawable-xxhdpi/footer_hills_g1g1.png b/Habitica/res/drawable-xxhdpi/footer_hills_g1g1.png
new file mode 100644
index 000000000..74cc3d00d
Binary files /dev/null and b/Habitica/res/drawable-xxhdpi/footer_hills_g1g1.png differ
diff --git a/Habitica/res/drawable-xxhdpi/footer_stars_left.png b/Habitica/res/drawable-xxhdpi/footer_stars_left.png
new file mode 100644
index 000000000..3cf813796
Binary files /dev/null and b/Habitica/res/drawable-xxhdpi/footer_stars_left.png differ
diff --git a/Habitica/res/drawable-xxhdpi/footer_stars_right.png b/Habitica/res/drawable-xxhdpi/footer_stars_right.png
new file mode 100644
index 000000000..3400e9aaa
Binary files /dev/null and b/Habitica/res/drawable-xxhdpi/footer_stars_right.png differ
diff --git a/Habitica/res/layout/activity_adventure_guide.xml b/Habitica/res/layout/activity_adventure_guide.xml
index f459d3e3e..c2fd7d5df 100644
--- a/Habitica/res/layout/activity_adventure_guide.xml
+++ b/Habitica/res/layout/activity_adventure_guide.xml
@@ -22,7 +22,7 @@
-
-
+
diff --git a/Habitica/res/layout/activity_create_challenge.xml b/Habitica/res/layout/activity_create_challenge.xml
index 0665b75ff..e08481bbd 100644
--- a/Habitica/res/layout/activity_create_challenge.xml
+++ b/Habitica/res/layout/activity_create_challenge.xml
@@ -22,7 +22,7 @@
app:popupTheme="@style/ThemeOverlay.AppCompat.Light"/>
-
-
+
diff --git a/Habitica/res/layout/activity_full_profile.xml b/Habitica/res/layout/activity_full_profile.xml
index d98574775..5789bd744 100644
--- a/Habitica/res/layout/activity_full_profile.xml
+++ b/Habitica/res/layout/activity_full_profile.xml
@@ -4,14 +4,12 @@
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:orientation="vertical"
- tools:context="com.habitrpg.android.habitica.ui.activities.FixCharacterValuesActivity">
+ android:orientation="vertical">
-
-
-
-
-
-
-
+ android:text="@string/str_abbrv"
+ android:textAllCaps="true"/>
+ android:text="@string/int_abbrv"
+ android:textAllCaps="true" />
+ android:text="@string/con_abbrv"
+ android:textAllCaps="true" />
+ android:text="@string/per_abbrv"
+ android:textAllCaps="true" />
@@ -430,5 +427,5 @@
-
+
diff --git a/Habitica/res/layout/activity_gift_subscription.xml b/Habitica/res/layout/activity_gift_subscription.xml
index 7bc56c67c..830415d70 100644
--- a/Habitica/res/layout/activity_gift_subscription.xml
+++ b/Habitica/res/layout/activity_gift_subscription.xml
@@ -55,7 +55,7 @@
-
-
+
diff --git a/Habitica/res/layout/activity_guidelines.xml b/Habitica/res/layout/activity_guidelines.xml
index 040b7a3c4..5f93f7127 100644
--- a/Habitica/res/layout/activity_guidelines.xml
+++ b/Habitica/res/layout/activity_guidelines.xml
@@ -24,7 +24,7 @@
app:popupTheme="@style/PopupTheme"/>
-
-
+
diff --git a/Habitica/res/layout/activity_main_content.xml b/Habitica/res/layout/activity_main_content.xml
index 20aa1445b..575816aed 100644
--- a/Habitica/res/layout/activity_main_content.xml
+++ b/Habitica/res/layout/activity_main_content.xml
@@ -27,7 +27,6 @@
android:layout_height="wrap_content"
app:titleEnabled="false"
app:contentScrim="?attr/headerBackgroundColor"
- android:background="?attr/headerBackgroundColor"
app:expandedTitleMarginEnd="?attr/actionBarSize"
app:expandedTitleMarginStart="0dp"
app:layout_scrollFlags="scroll|exitUntilCollapsed"
diff --git a/Habitica/res/layout/activity_notifications.xml b/Habitica/res/layout/activity_notifications.xml
index 1a6d967b5..39361dd93 100644
--- a/Habitica/res/layout/activity_notifications.xml
+++ b/Habitica/res/layout/activity_notifications.xml
@@ -38,7 +38,7 @@
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
-
@@ -109,7 +109,7 @@
android:orientation="vertical"
android:showDividers="middle" />
-
+
diff --git a/Habitica/res/layout/activity_report_message.xml b/Habitica/res/layout/activity_report_message.xml
index 3f2cbbf02..c0683b90a 100644
--- a/Habitica/res/layout/activity_report_message.xml
+++ b/Habitica/res/layout/activity_report_message.xml
@@ -61,7 +61,7 @@
-
-
+
diff --git a/Habitica/res/layout/activity_task_form.xml b/Habitica/res/layout/activity_task_form.xml
index 7368cb848..49cc652f8 100644
--- a/Habitica/res/layout/activity_task_form.xml
+++ b/Habitica/res/layout/activity_task_form.xml
@@ -26,7 +26,7 @@
-
-
+
diff --git a/Habitica/res/layout/bottom_sheet_wrapper.xml b/Habitica/res/layout/bottom_sheet_wrapper.xml
index 3e94f98b6..98f779880 100644
--- a/Habitica/res/layout/bottom_sheet_wrapper.xml
+++ b/Habitica/res/layout/bottom_sheet_wrapper.xml
@@ -13,7 +13,7 @@
android:layout_marginBottom="@dimen/spacing_large"
android:layout_gravity="center_horizontal"
/>
-
@@ -21,5 +21,5 @@
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
-
+
diff --git a/Habitica/res/layout/chat_bar_view.xml b/Habitica/res/layout/chat_bar_view.xml
index 311c784ff..9c7691da0 100644
--- a/Habitica/res/layout/chat_bar_view.xml
+++ b/Habitica/res/layout/chat_bar_view.xml
@@ -33,6 +33,7 @@
android:paddingEnd="@dimen/spacing_medium"
android:paddingTop="4dp"
android:paddingBottom="4dp"
+ android:imeOptions="actionSend"
tools:height="200dp"/>
-
-
+
diff --git a/Habitica/res/layout/fragment_challenge_detail.xml b/Habitica/res/layout/fragment_challenge_detail.xml
index 0092366bd..ca0394c5a 100644
--- a/Habitica/res/layout/fragment_challenge_detail.xml
+++ b/Habitica/res/layout/fragment_challenge_detail.xml
@@ -1,5 +1,5 @@
-
-
+
diff --git a/Habitica/res/layout/fragment_compose_scrolling.xml b/Habitica/res/layout/fragment_compose_scrolling.xml
index b056303ff..1ab20bf3a 100644
--- a/Habitica/res/layout/fragment_compose_scrolling.xml
+++ b/Habitica/res/layout/fragment_compose_scrolling.xml
@@ -1,5 +1,5 @@
-
-
+
diff --git a/Habitica/res/layout/fragment_faq_detail.xml b/Habitica/res/layout/fragment_faq_detail.xml
index 7580a1f02..f72424d49 100644
--- a/Habitica/res/layout/fragment_faq_detail.xml
+++ b/Habitica/res/layout/fragment_faq_detail.xml
@@ -1,5 +1,5 @@
-
-
+
diff --git a/Habitica/res/layout/fragment_faq_overview.xml b/Habitica/res/layout/fragment_faq_overview.xml
index 0c2ee7e13..155daa0ac 100644
--- a/Habitica/res/layout/fragment_faq_overview.xml
+++ b/Habitica/res/layout/fragment_faq_overview.xml
@@ -1,5 +1,5 @@
-
-
+
diff --git a/Habitica/res/layout/fragment_gem_purchase.xml b/Habitica/res/layout/fragment_gem_purchase.xml
index b58a5d865..ae5b0f3fa 100644
--- a/Habitica/res/layout/fragment_gem_purchase.xml
+++ b/Habitica/res/layout/fragment_gem_purchase.xml
@@ -1,306 +1,333 @@
-
+
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical">
+ android:id="@+id/promo_compose_view"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:visibility="gone" />
+ android:id="@+id/promo_banner"
+ android:layout_width="match_parent"
+ android:layout_height="96dp"
+ android:background="@drawable/g1g1_box"
+ android:layout_marginStart="10dp"
+ android:layout_marginEnd="10dp"
+ android:layout_marginBottom="@dimen/spacing_large"
+ android:clipChildren="true"
+ android:clipToPadding="true"
+ android:focusable="true"
+ android:clickable="true"
+ android:visibility="gone"
+ tools:visibility="visible">
+ android:id="@+id/promo_banner_left_image"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:scaleType="center"
+ android:layout_alignParentTop="true"
+ android:layout_alignParentStart="true"
+ android:layout_alignParentBottom="false"
+ android:importantForAccessibility="no" />
+ android:id="@+id/promo_banner_right_image"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:scaleType="center"
+ android:layout_alignParentTop="true"
+ android:layout_alignParentEnd="true"
+ android:importantForAccessibility="no" />
+ android:layout_centerInParent="true"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:gravity="center"
+ android:orientation="vertical">
+ android:id="@+id/promo_banner_title_image"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginBottom="6dp" />
+ android:id="@+id/promo_banner_title_text"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:visibility="gone"
+ android:textSize="22sp"
+ android:textStyle="bold"
+ android:layout_marginStart="84dp"
+ android:layout_marginEnd="84dp"
+ android:gravity="center"
+ android:textColor="@color/white"
+ android:layout_marginBottom="4dp" />
+ android:id="@+id/promo_banner_subtitle_text"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:visibility="gone"
+ android:textSize="16sp"
+ android:fontFamily="@string/font_family_medium"
+ android:layout_marginStart="84dp"
+ android:layout_marginEnd="84dp"
+ android:gravity="center"
+ android:textColor="@color/white"
+ android:layout_marginBottom="6dp" />
+ android:id="@+id/promo_banner_duration_view"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ style="@style/Overline" />
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginStart="60dp"
+ android:layout_marginEnd="60dp"
+ android:gravity="center_horizontal"
+ android:textColor="@color/white"
+ android:textSize="16sp"
+ android:fontFamily="@string/font_family_medium"
+ android:layout_marginBottom="12dp"
+ android:layout_centerInParent="true" />
-
-
-
+
+ android:id="@+id/header_image_view"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:src="@drawable/gem_purchase_header"
+ android:layout_gravity="center_horizontal"
+ android:layout_marginBottom="20dp" />
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
+
-
+
+
+ android:layout_weight="1"
+ app:gemAmount="4"
+ app:gemDrawable="@drawable/gems_4"
+ android:layout_marginEnd="@dimen/spacing_large" />
+
-
+ android:id="@+id/gems_21_view"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ app:gemAmount="21"
+ app:gemDrawable="@drawable/gems_21" />
+
+
+ android:layout_weight="1"
+ app:gemAmount="42"
+ app:gemDrawable="@drawable/gems_42"
+ android:layout_marginEnd="@dimen/spacing_large" />
-
-
+ android:id="@+id/gems_84_view"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ app:gemAmount="84"
+ app:gemDrawable="@drawable/gems_84" />
+
+
+
+
+
+
+
+
+
+
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:src="@drawable/footer_stars_right"
+ android:layout_gravity="center_horizontal"
+ android:scaleType="fitCenter" />
-
+
+
-
-
-
-
-
-
+ android:paddingStart="41dp"
+ android:paddingEnd="41dp"
+ android:text="@string/gem_purchase_title"
+ android:layout_gravity="center_horizontal"
+ android:gravity="center"
+ android:lineSpacingExtra="3dp"
+ android:textColor="@color/white"
+ style="@style/Caption2"
+ android:background="@color/brand_400"
+ android:drawablePadding="@dimen/spacing_medium" />
+
+
-
+
diff --git a/Habitica/res/layout/fragment_gift_gem_balance.xml b/Habitica/res/layout/fragment_gift_gem_balance.xml
index ccd7f2358..9f8a32819 100644
--- a/Habitica/res/layout/fragment_gift_gem_balance.xml
+++ b/Habitica/res/layout/fragment_gift_gem_balance.xml
@@ -1,5 +1,5 @@
-
-
+
diff --git a/Habitica/res/layout/fragment_gift_gem_purchase.xml b/Habitica/res/layout/fragment_gift_gem_purchase.xml
index 08efd5479..2ce46051e 100644
--- a/Habitica/res/layout/fragment_gift_gem_purchase.xml
+++ b/Habitica/res/layout/fragment_gift_gem_purchase.xml
@@ -1,5 +1,5 @@
-
-
+
diff --git a/Habitica/res/layout/fragment_guild_detail.xml b/Habitica/res/layout/fragment_guild_detail.xml
index 91bd424ce..7d72666f4 100644
--- a/Habitica/res/layout/fragment_guild_detail.xml
+++ b/Habitica/res/layout/fragment_guild_detail.xml
@@ -5,7 +5,7 @@
android:layout_height="match_parent"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/refreshLayout">
-
@@ -196,5 +196,5 @@
style="@style/HabiticaButton.Red"
android:text="@string/leave_guild"/>
-
+
diff --git a/Habitica/res/layout/fragment_inbox.xml b/Habitica/res/layout/fragment_inbox.xml
index c3ba48d3c..be54783a2 100644
--- a/Habitica/res/layout/fragment_inbox.xml
+++ b/Habitica/res/layout/fragment_inbox.xml
@@ -6,7 +6,7 @@
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
-
@@ -44,5 +44,5 @@
android:divider="?android:listDivider"
android:showDividers="middle" />
-
+
diff --git a/Habitica/res/layout/fragment_no_party.xml b/Habitica/res/layout/fragment_no_party.xml
index 9264878e1..395a34b84 100644
--- a/Habitica/res/layout/fragment_no_party.xml
+++ b/Habitica/res/layout/fragment_no_party.xml
@@ -5,7 +5,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent">
-
-
+
diff --git a/Habitica/res/layout/fragment_party_detail.xml b/Habitica/res/layout/fragment_party_detail.xml
index 8d219b1ac..3d8def73e 100644
--- a/Habitica/res/layout/fragment_party_detail.xml
+++ b/Habitica/res/layout/fragment_party_detail.xml
@@ -5,7 +5,7 @@
android:id="@+id/refreshLayout"
android:layout_width="match_parent"
android:layout_height="match_parent">
-
@@ -268,5 +268,5 @@
android:text="@string/leave_party"
android:textSize="16sp" />
-
+
diff --git a/Habitica/res/layout/fragment_party_invite.xml b/Habitica/res/layout/fragment_party_invite.xml
index 15e29a726..47de1c6e1 100644
--- a/Habitica/res/layout/fragment_party_invite.xml
+++ b/Habitica/res/layout/fragment_party_invite.xml
@@ -1,5 +1,5 @@
-
-
+
diff --git a/Habitica/res/layout/fragment_promo_info.xml b/Habitica/res/layout/fragment_promo_info.xml
index f8cc6a920..d2aac2164 100644
--- a/Habitica/res/layout/fragment_promo_info.xml
+++ b/Habitica/res/layout/fragment_promo_info.xml
@@ -1,5 +1,5 @@
-
-
+
diff --git a/Habitica/res/layout/fragment_quest_detail.xml b/Habitica/res/layout/fragment_quest_detail.xml
index d489efeed..39869833f 100644
--- a/Habitica/res/layout/fragment_quest_detail.xml
+++ b/Habitica/res/layout/fragment_quest_detail.xml
@@ -1,5 +1,5 @@
-
-
+
diff --git a/Habitica/res/layout/fragment_report_message.xml b/Habitica/res/layout/fragment_report_message.xml
index c3444b3cc..1af55dc34 100644
--- a/Habitica/res/layout/fragment_report_message.xml
+++ b/Habitica/res/layout/fragment_report_message.xml
@@ -62,7 +62,7 @@
-
-
+
diff --git a/Habitica/res/layout/fragment_stats.xml b/Habitica/res/layout/fragment_stats.xml
index 117dbbe08..a4df118b4 100644
--- a/Habitica/res/layout/fragment_stats.xml
+++ b/Habitica/res/layout/fragment_stats.xml
@@ -1,5 +1,5 @@
-
-
+
diff --git a/Habitica/res/layout/fragment_subscription_content.xml b/Habitica/res/layout/fragment_subscription_content.xml
index e207785c2..e1b981e58 100644
--- a/Habitica/res/layout/fragment_subscription_content.xml
+++ b/Habitica/res/layout/fragment_subscription_content.xml
@@ -1,5 +1,5 @@
-
+ android:scrollbars="vertical"
+ app:skipDirectchild="true">
-
+
-
+ android:src="@drawable/footer_stars_right"
+ android:layout_gravity="center_horizontal"
+ android:scaleType="fitCenter" />
+
+
-
+
diff --git a/Habitica/res/layout/fragment_support_bug_fix.xml b/Habitica/res/layout/fragment_support_bug_fix.xml
index fa136624f..365fe1389 100644
--- a/Habitica/res/layout/fragment_support_bug_fix.xml
+++ b/Habitica/res/layout/fragment_support_bug_fix.xml
@@ -1,5 +1,5 @@
-
-
+
diff --git a/Habitica/res/layout/fragment_support_main.xml b/Habitica/res/layout/fragment_support_main.xml
index 7701b999e..684b30867 100644
--- a/Habitica/res/layout/fragment_support_main.xml
+++ b/Habitica/res/layout/fragment_support_main.xml
@@ -1,14 +1,15 @@
-
+ android:layout_height="match_parent"
+ app:skipDirectchild="true"
+ xmlns:app="http://schemas.android.com/apk/res-auto">
+ android:layout_height="match_parent">
-
+ android:layout_height="wrap_content"
+ android:background="?attr/colorWindowBackground">
+
-
+
diff --git a/Habitica/res/values/attrs.xml b/Habitica/res/values/attrs.xml
index 59e802ebc..623938165 100644
--- a/Habitica/res/values/attrs.xml
+++ b/Habitica/res/values/attrs.xml
@@ -36,6 +36,7 @@
+
@@ -146,4 +147,7 @@
+
+
+
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/extensions/WindowInsetsCompatExtensions.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/extensions/WindowInsetsCompatExtensions.kt
index 83b78965d..24894f244 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/extensions/WindowInsetsCompatExtensions.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/extensions/WindowInsetsCompatExtensions.kt
@@ -22,11 +22,16 @@ fun applyScrollContentWindowInsets(view: View,
val bottomPadding = view.paddingBottom
ViewCompat.setOnApplyWindowInsetsListener(view) { v, windowInsets ->
val insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars() + WindowInsetsCompat.Type.displayCutout())
+ val top = (if (applyTop) insets.top else 0) + topPadding
+ val bottom = (if (applyBottom) insets.bottom else 0) + bottomPadding
+ if (v.layoutParams.height > 0 && v.layoutParams.height < top + bottom) {
+ v.layoutParams.height += top + bottom
+ }
v.updatePadding(
- top = (if (applyTop) insets.top else 0) + topPadding,
+ top = top,
left = (if (applyLeft) insets.left else 0) + leftPadding,
right = (if (applyRight) insets.right else 0) + rightPadding,
- bottom = (if (applyBottom) insets.bottom else 0) + bottomPadding)
+ bottom = bottom)
consumeWindowInsetsAbove30(windowInsets)
}
}
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/AdventureGuideActivity.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/AdventureGuideActivity.kt
index d3d9ed3a1..c25c5a2a8 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/AdventureGuideActivity.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/AdventureGuideActivity.kt
@@ -8,14 +8,9 @@ import android.view.View
import android.widget.TextView
import androidx.core.app.NavUtils
import androidx.core.content.ContextCompat
-import androidx.core.view.ViewCompat
-import androidx.core.view.WindowInsetsCompat
-import androidx.core.view.updatePadding
import com.habitrpg.android.habitica.R
import com.habitrpg.android.habitica.databinding.ActivityAdventureGuideBinding
import com.habitrpg.android.habitica.databinding.AdventureGuideItemBinding
-import com.habitrpg.android.habitica.extensions.applyScrollContentWindowInsets
-import com.habitrpg.android.habitica.extensions.consumeWindowInsetsAbove30
import com.habitrpg.android.habitica.helpers.Analytics
import com.habitrpg.android.habitica.models.user.User
import com.habitrpg.android.habitica.ui.viewmodels.MainUserViewModel
@@ -77,11 +72,6 @@ class AdventureGuideActivity : BaseActivity() {
}
}
- override fun onAttachedToWindow() {
- super.onAttachedToWindow()
- applyScrollContentWindowInsets(binding.scrollContent)
- }
-
override fun onOptionsItemSelected(item: MenuItem): Boolean {
return if (item.itemId == android.R.id.home) {
NavUtils.navigateUpFromSameTask(this)
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/BaseActivity.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/BaseActivity.kt
index c2d69a1e7..fb7633d14 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/BaseActivity.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/BaseActivity.kt
@@ -25,9 +25,12 @@ import androidx.core.net.toUri
import androidx.core.view.ViewCompat
import androidx.core.view.WindowCompat
import androidx.core.view.WindowInsetsCompat
+import androidx.core.view.children
import androidx.core.view.updatePadding
import androidx.lifecycle.lifecycleScope
import androidx.preference.PreferenceManager
+import com.google.android.material.appbar.AppBarLayout
+import com.google.android.material.tabs.TabLayout
import com.habitrpg.android.habitica.HabiticaApplication
import com.habitrpg.android.habitica.R
import com.habitrpg.android.habitica.data.UserRepository
@@ -143,9 +146,12 @@ abstract class BaseActivity : AppCompatActivity() {
WindowInsetsCompat.Type.systemBars()
+ WindowInsetsCompat.Type.displayCutout()
)
- v.updatePadding(top = insets.top + paddingTop,
- left = insets.left,
- right = insets.right)
+ v.updatePadding(top = insets.top + paddingTop)
+ (v as AppBarLayout).children.forEach {
+ if (it !is TabLayout) {
+ it.updatePadding(left = insets.left, right = insets.right)
+ }
+ }
consumeWindowInsetsAbove30(windowInsets)
}
}
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/FullProfileActivity.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/FullProfileActivity.kt
index 1b676c89f..29373c3a5 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/FullProfileActivity.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/FullProfileActivity.kt
@@ -253,7 +253,7 @@ class FullProfileActivity : BaseActivity() {
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.S_V2) {
HabiticaSnackbar.showSnackbar(
this@FullProfileActivity.binding.nestedScrollView.getChildAt(0) as ViewGroup,
- String.format(getString(R.string.username_copied), userDisplayName),
+ getString(R.string.username_copied),
SnackbarDisplayType.NORMAL
)
}
@@ -268,7 +268,7 @@ class FullProfileActivity : BaseActivity() {
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.S_V2) {
HabiticaSnackbar.showSnackbar(
this@FullProfileActivity.binding.nestedScrollView.getChildAt(0) as ViewGroup,
- String.format(getString(R.string.id_copied), userDisplayName),
+ getString(R.string.id_copied),
SnackbarDisplayType.NORMAL
)
}
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/TaskFormActivity.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/TaskFormActivity.kt
index bd867c51b..172797831 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/TaskFormActivity.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/TaskFormActivity.kt
@@ -24,7 +24,6 @@ import android.view.ViewGroup
import android.view.WindowManager
import android.widget.CheckBox
import android.widget.TextView
-import androidx.activity.SystemBarStyle
import androidx.activity.result.contract.ActivityResultContracts
import androidx.activity.viewModels
import androidx.appcompat.widget.AppCompatCheckBox
@@ -32,13 +31,10 @@ import androidx.compose.runtime.mutableStateListOf
import androidx.compose.runtime.mutableStateMapOf
import androidx.compose.runtime.toMutableStateList
import androidx.core.content.ContextCompat
-import androidx.core.view.ViewCompat
-import androidx.core.view.WindowInsetsCompat
import androidx.core.view.children
import androidx.core.view.forEachIndexed
import androidx.core.view.isVisible
import androidx.core.view.iterator
-import androidx.core.view.updatePadding
import androidx.core.widget.NestedScrollView
import androidx.lifecycle.lifecycleScope
import com.habitrpg.android.habitica.R
@@ -49,8 +45,6 @@ import com.habitrpg.android.habitica.data.TaskRepository
import com.habitrpg.android.habitica.databinding.ActivityTaskFormBinding
import com.habitrpg.android.habitica.extensions.OnChangeTextWatcher
import com.habitrpg.android.habitica.extensions.addCancelButton
-import com.habitrpg.android.habitica.extensions.applyScrollContentWindowInsets
-import com.habitrpg.android.habitica.extensions.consumeWindowInsetsAbove30
import com.habitrpg.android.habitica.helpers.AppConfigManager
import com.habitrpg.android.habitica.helpers.TaskAlarmManager
import com.habitrpg.android.habitica.helpers.notifications.PushNotificationManager
@@ -432,12 +426,7 @@ class TaskFormActivity : BaseActivity() {
}
configureForm()
- }
-
- override fun onAttachedToWindow() {
- super.onAttachedToWindow()
- applyScrollContentWindowInsets(binding.mainFormContent)
- }
+}
override fun onResume() {
checkIfShowNotifLayout()
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/BaseMainFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/BaseMainFragment.kt
index 5e91aa989..5c1fb0fee 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/BaseMainFragment.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/BaseMainFragment.kt
@@ -9,7 +9,7 @@ import android.view.MenuInflater
import android.view.MenuItem
import android.view.View
import android.view.ViewGroup
-import android.view.WindowInsetsController
+import androidx.core.content.ContextCompat
import androidx.core.os.bundleOf
import androidx.core.view.WindowCompat
import androidx.viewbinding.ViewBinding
@@ -87,6 +87,7 @@ abstract class BaseMainFragment : BaseFragment() {
binding = null
}
+ var navigationBarColor: Int? = null
override fun onResume() {
super.onResume()
mainActivity?.showBackButton = showsBackButton
@@ -108,6 +109,7 @@ abstract class BaseMainFragment : BaseFragment() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
window.isNavigationBarContrastEnforced = true
}
+ activity?.window?.navigationBarColor = navigationBarColor ?: ContextCompat.getColor(requireContext(), R.color.content_background)
}
}
}
@@ -118,7 +120,8 @@ abstract class BaseMainFragment : BaseFragment() {
inflater: MenuInflater
) {
super.onCreateOptionsMenu(menu, inflater)
- mainActivity?.toolbar?.let { ToolbarColorHelper.colorizeToolbar(it, mainActivity) }
+ mainActivity?.toolbar?.let { ToolbarColorHelper.colorizeToolbar(it, mainActivity,
+ appbar = mainActivity?.findViewById(R.id.appbar)) }
updateToolbarInteractivity()
}
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/customization/AvatarOverviewFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/customization/AvatarOverviewFragment.kt
index 5912fdb59..4219f2522 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/customization/AvatarOverviewFragment.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/customization/AvatarOverviewFragment.kt
@@ -1,5 +1,6 @@
package com.habitrpg.android.habitica.ui.fragments.inventory.customization
+import android.content.res.Configuration
import android.os.Bundle
import android.view.LayoutInflater
import android.view.Menu
@@ -9,21 +10,22 @@ import android.view.View
import android.view.ViewGroup
import android.widget.AdapterView
import androidx.compose.foundation.background
-import androidx.compose.foundation.gestures.Orientation
-import androidx.compose.foundation.gestures.rememberScrollableState
-import androidx.compose.foundation.gestures.scrollable
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.ExperimentalLayoutApi
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.WindowInsets
+import androidx.compose.foundation.layout.add
+import androidx.compose.foundation.layout.asPaddingValues
+import androidx.compose.foundation.layout.calculateEndPadding
+import androidx.compose.foundation.layout.calculateStartPadding
+import androidx.compose.foundation.layout.displayCutout
import androidx.compose.foundation.layout.fillMaxWidth
-import androidx.compose.foundation.layout.height
-import androidx.compose.foundation.layout.navigationBarsIgnoringVisibility
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
-import androidx.compose.foundation.layout.windowInsetsBottomHeight
+import androidx.compose.foundation.layout.systemBars
+import androidx.compose.foundation.layout.widthIn
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.verticalScroll
@@ -37,19 +39,18 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.alpha
import androidx.compose.ui.draw.clip
-import androidx.compose.ui.draw.clipToBounds
+import androidx.compose.ui.platform.LocalConfiguration
+import androidx.compose.ui.platform.LocalLayoutDirection
import androidx.compose.ui.platform.ViewCompositionStrategy
import androidx.compose.ui.res.colorResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import androidx.core.content.ContextCompat
-import androidx.core.view.WindowInsetsCompat
import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.map
import com.habitrpg.android.habitica.R
import com.habitrpg.android.habitica.data.InventoryRepository
import com.habitrpg.android.habitica.databinding.FragmentComposeBinding
-import com.habitrpg.android.habitica.databinding.FragmentComposeScrollingBinding
import com.habitrpg.android.habitica.helpers.AppConfigManager
import com.habitrpg.android.habitica.interactors.ShareAvatarUseCase
import com.habitrpg.android.habitica.models.inventory.Equipment
@@ -108,24 +109,33 @@ open class AvatarOverviewFragment :
setViewCompositionStrategy(ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed)
setContent {
HabiticaTheme {
+ val configuration = LocalConfiguration.current
+ val isWidthGreaterHeight = configuration.screenWidthDp > configuration.screenHeightDp
+
val avatar by userViewModel.user.observeAsState()
Column {
- Column(horizontalAlignment = Alignment.CenterHorizontally, modifier = Modifier.fillMaxWidth().background(colorResource(R.color.window_background))) {
+ Column(horizontalAlignment = Alignment.CenterHorizontally,
+ modifier = Modifier
+ .fillMaxWidth()
+ .background(colorResource(R.color.window_background))) {
ComposableAvatarView(
avatar = avatar,
configManager = appConfigManager,
modifier =
Modifier
- .padding(bottom = 24.dp)
+ .padding(bottom = if (isWidthGreaterHeight) 8.dp else 24.dp)
.size(140.dp, 147.dp)
)
}
+ val insets = WindowInsets.systemBars.add(WindowInsets.displayCutout).asPaddingValues()
+ val ld = LocalLayoutDirection.current
Column(modifier = Modifier
+ .padding(bottom = insets.calculateBottomPadding())
.background(colorResource(R.color.window_background))
+ .padding(start = insets.calculateStartPadding(ld), end = insets.calculateEndPadding(ld))
.clip(RoundedCornerShape(topStart = 22.dp, topEnd = 22.dp))
.background(colorResource(R.color.content_background))
.verticalScroll(rememberScrollState())
- .padding(top = 12.dp)
) {
AvatarOverviewView(
userViewModel,
@@ -143,7 +153,6 @@ open class AvatarOverviewFragment :
displayEquipmentFragment(type, equipped, isCostume)
}
)
- Spacer(modifier = Modifier.windowInsetsBottomHeight(WindowInsets.navigationBarsIgnoringVisibility))
}
}
}
@@ -204,13 +213,20 @@ open class AvatarOverviewFragment :
super.onCreateOptionsMenu(menu, inflater)
inflater.inflate(R.menu.menu_share_avatar, menu)
+ val color = ContextCompat.getColor(requireContext(), R.color.window_background)
mainActivity?.toolbar?.let {
- val color = ContextCompat.getColor(requireContext(), R.color.window_background)
- ToolbarColorHelper.colorizeToolbar(it, mainActivity, backgroundColor = color)
- requireActivity().window.statusBarColor = color
+ ToolbarColorHelper.colorizeToolbar(it, mainActivity, backgroundColor = color,
+ appbar = mainActivity?.findViewById(R.id.appbar))
}
}
+ override fun onResume() {
+ if (requireActivity().resources.configuration.orientation == Configuration.ORIENTATION_LANDSCAPE) {
+ navigationBarColor = ContextCompat.getColor(requireContext(), R.color.window_background)
+ }
+ super.onResume()
+ }
+
override fun onOptionsItemSelected(item: MenuItem): Boolean {
if (item.itemId == R.id.share_avatar) {
userViewModel.user.value?.let {
@@ -259,92 +275,97 @@ fun AvatarOverviewView(
onEquipmentTap: (String, String?, Boolean) -> Unit
) {
val user by userViewModel.user.observeAsState()
- Column(
- Modifier
- .padding(horizontal = 8.dp)
- .padding(bottom = 16.dp)
- ) {
- if (showCustomization) {
- Row(
- Modifier.padding(horizontal = 12.dp, vertical = 15.dp),
- verticalAlignment = Alignment.CenterVertically
- ) {
- Text(
- stringResource(R.string.avatar_size),
- style = HabiticaTheme.typography.titleMedium,
- color = HabiticaTheme.colors.textSecondary
- )
- Spacer(modifier = Modifier.weight(1f))
- SegmentedControl(
- items =
- listOf(
- stringResource(R.string.avatar_size_slim),
- stringResource(
- R.string.avatar_size_broad
- )
- ),
- defaultSelectedItemIndex = if (user?.preferences?.size == "slim") 0 else 1,
- onItemSelection = {
- userViewModel.updateUser(
- "preferences.size",
- if (it == 0) "slim" else "broad"
- )
- }
- )
+ Box(contentAlignment = Alignment.TopCenter,
+ modifier = Modifier.fillMaxWidth()) {
+ Column(
+ horizontalAlignment = Alignment.CenterHorizontally,
+ modifier = Modifier
+ .padding(horizontal = 8.dp)
+ .padding(bottom = 16.dp)
+ .widthIn(max = 500.dp)
+ ) {
+ if (showCustomization) {
+ Row(
+ Modifier.padding(horizontal = 12.dp, vertical = 15.dp),
+ verticalAlignment = Alignment.CenterVertically
+ ) {
+ Text(
+ stringResource(R.string.avatar_size),
+ style = HabiticaTheme.typography.titleMedium,
+ color = HabiticaTheme.colors.textSecondary
+ )
+ Spacer(modifier = Modifier.weight(1f))
+ SegmentedControl(
+ items =
+ listOf(
+ stringResource(R.string.avatar_size_slim),
+ stringResource(
+ R.string.avatar_size_broad
+ )
+ ),
+ defaultSelectedItemIndex = if (user?.preferences?.size == "slim") 0 else 1,
+ onItemSelection = {
+ userViewModel.updateUser(
+ "preferences.size",
+ if (it == 0) "slim" else "broad"
+ )
+ }
+ )
+ }
+ AvatarCustomizationOverviewView(user?.preferences, user?.items?.gear?.equipped, onCustomizationTap, onAvatarEquipmentTap)
}
- AvatarCustomizationOverviewView(user?.preferences, user?.items?.gear?.equipped, onCustomizationTap, onAvatarEquipmentTap)
- }
- if (showEquipment) {
- Row(
- Modifier
- .padding(horizontal = 12.dp)
- .padding(top = 15.dp),
- verticalAlignment = Alignment.CenterVertically
- ) {
- Text(
- stringResource(R.string.equipped).uppercase(),
- style = HabiticaTheme.typography.titleSmall,
- color = HabiticaTheme.colors.textSecondary
- )
- Spacer(modifier = Modifier.weight(1f))
- Text(
- stringResource(R.string.equip_automatically),
- style = HabiticaTheme.typography.bodyMedium,
- color = HabiticaTheme.colors.textPrimary,
- modifier = Modifier.padding(end = 6.dp)
- )
- Switch(checked = user?.preferences?.autoEquip == true, onCheckedChange = {
- userViewModel.updateUser("preferences.autoEquip", it)
+ if (showEquipment) {
+ Row(
+ Modifier
+ .padding(horizontal = 12.dp)
+ .padding(top = 15.dp),
+ verticalAlignment = Alignment.CenterVertically
+ ) {
+ Text(
+ stringResource(R.string.equipped).uppercase(),
+ style = HabiticaTheme.typography.titleSmall,
+ color = HabiticaTheme.colors.textSecondary
+ )
+ Spacer(modifier = Modifier.weight(1f))
+ Text(
+ stringResource(R.string.equip_automatically),
+ style = HabiticaTheme.typography.bodyMedium,
+ color = HabiticaTheme.colors.textPrimary,
+ modifier = Modifier.padding(end = 6.dp)
+ )
+ Switch(checked = user?.preferences?.autoEquip == true, onCheckedChange = {
+ userViewModel.updateUser("preferences.autoEquip", it)
+ })
+ }
+ EquipmentOverviewView(user?.items?.gear?.equipped, battleGearTwoHanded, { type, equipped ->
+ onEquipmentTap(type, equipped, false)
})
+ Row(
+ Modifier
+ .padding(horizontal = 12.dp)
+ .padding(top = 15.dp),
+ verticalAlignment = Alignment.CenterVertically
+ ) {
+ Text(
+ stringResource(R.string.costume).uppercase(),
+ style = HabiticaTheme.typography.titleSmall,
+ color = HabiticaTheme.colors.textSecondary
+ )
+ Spacer(modifier = Modifier.weight(1f))
+ Text(
+ stringResource(R.string.wear_costume),
+ style = HabiticaTheme.typography.bodyMedium,
+ color = HabiticaTheme.colors.textPrimary,
+ modifier = Modifier.padding(end = 6.dp)
+ )
+ Switch(checked = user?.preferences?.costume == true, onCheckedChange = {
+ userViewModel.updateUser("preferences.costume", it)
+ })
+ }
+ EquipmentOverviewView(user?.items?.gear?.costume, costumeTwoHanded, { type, equipped ->
+ onEquipmentTap(type, equipped, true)
+ }, modifier = Modifier.alpha(if (user?.preferences?.costume == true) 1.0f else 0.5f))
}
- EquipmentOverviewView(user?.items?.gear?.equipped, battleGearTwoHanded, { type, equipped ->
- onEquipmentTap(type, equipped, false)
- })
- Row(
- Modifier
- .padding(horizontal = 12.dp)
- .padding(top = 15.dp),
- verticalAlignment = Alignment.CenterVertically
- ) {
- Text(
- stringResource(R.string.costume).uppercase(),
- style = HabiticaTheme.typography.titleSmall,
- color = HabiticaTheme.colors.textSecondary
- )
- Spacer(modifier = Modifier.weight(1f))
- Text(
- stringResource(R.string.wear_costume),
- style = HabiticaTheme.typography.bodyMedium,
- color = HabiticaTheme.colors.textPrimary,
- modifier = Modifier.padding(end = 6.dp)
- )
- Switch(checked = user?.preferences?.costume == true, onCheckedChange = {
- userViewModel.updateUser("preferences.costume", it)
- })
- }
- EquipmentOverviewView(user?.items?.gear?.costume, costumeTwoHanded, { type, equipped ->
- onEquipmentTap(type, equipped, true)
- }, modifier = Modifier.alpha(if (user?.preferences?.costume == true) 1.0f else 0.5f))
}
}
}
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/customization/ComposeAvatarCustomizationFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/customization/ComposeAvatarCustomizationFragment.kt
index 3864c4271..9176c53ab 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/customization/ComposeAvatarCustomizationFragment.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/customization/ComposeAvatarCustomizationFragment.kt
@@ -1,5 +1,6 @@
package com.habitrpg.android.habitica.ui.fragments.inventory.customization
+import android.content.res.Configuration
import android.graphics.PorterDuff
import android.graphics.Typeface
import android.os.Bundle
@@ -19,10 +20,16 @@ import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.PaddingValues
+import androidx.compose.foundation.layout.WindowInsets
+import androidx.compose.foundation.layout.add
+import androidx.compose.foundation.layout.asPaddingValues
+import androidx.compose.foundation.layout.calculateEndPadding
+import androidx.compose.foundation.layout.calculateStartPadding
+import androidx.compose.foundation.layout.displayCutout
import androidx.compose.foundation.layout.fillMaxWidth
-import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
+import androidx.compose.foundation.layout.systemBars
import androidx.compose.foundation.lazy.grid.GridCells
import androidx.compose.foundation.lazy.grid.GridItemSpan
import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
@@ -44,6 +51,7 @@ import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.layout.onGloballyPositioned
import androidx.compose.ui.platform.LocalConfiguration
import androidx.compose.ui.platform.LocalDensity
+import androidx.compose.ui.platform.LocalLayoutDirection
import androidx.compose.ui.platform.ViewCompositionStrategy
import androidx.compose.ui.platform.rememberNestedScrollInteropConnection
import androidx.compose.ui.res.colorResource
@@ -248,11 +256,18 @@ class ComposeAvatarCustomizationFragment :
mainActivity?.toolbar?.let {
val color = ContextCompat.getColor(requireContext(), R.color.window_background)
- ToolbarColorHelper.colorizeToolbar(it, mainActivity, backgroundColor = color)
- requireActivity().window.statusBarColor = color
+ ToolbarColorHelper.colorizeToolbar(it, mainActivity, backgroundColor = color,
+ appbar = mainActivity?.findViewById(R.id.appbar))
}
}
+ override fun onResume() {
+ if (requireActivity().resources.configuration.orientation == Configuration.ORIENTATION_LANDSCAPE) {
+ navigationBarColor = ContextCompat.getColor(requireContext(), R.color.window_background)
+ }
+ super.onResume()
+ }
+
private fun updateFilterIcon() {
if (!currentFilter.value.isFiltering) {
filterMenuItem?.setIcon(R.drawable.ic_action_filter_list)
@@ -469,41 +484,46 @@ private fun AvatarCustomizationView(
activeCustomization: String?,
onSelect: (Customization) -> Unit
) {
+ val configuration = LocalConfiguration.current
+ val isWidthGreaterHeight = configuration.screenWidthDp > configuration.screenHeightDp
Column(horizontalAlignment = Alignment.CenterHorizontally) {
- Column(horizontalAlignment = Alignment.CenterHorizontally, modifier = Modifier.background(colorResource(R.color.window_background))) {
+ Column(horizontalAlignment = Alignment.CenterHorizontally,
+ modifier = Modifier
+ .fillMaxWidth()
+ .background(colorResource(R.color.window_background))) {
ComposableAvatarView(
avatar = avatar,
configManager = configManager,
modifier =
Modifier
- .padding(top = 6.dp, bottom = 24.dp)
+ .padding(bottom = if (isWidthGreaterHeight) 8.dp else 24.dp)
.size(140.dp, 147.dp)
)
- Box(
- Modifier
- .background(colorResource(R.color.content_background), RoundedCornerShape(topStart = 22.dp, topEnd = 22.dp))
- .fillMaxWidth()
- .height(22.dp)
- )
}
val nestedScrollInterop = rememberNestedScrollInteropConnection()
val screenWidth = LocalConfiguration.current.screenWidthDp.dp
var gridWidth by remember { mutableStateOf(screenWidth) }
val horizontalPadding = (gridWidth - (84.dp * 3)) / 2
val density = LocalDensity.current
+ val insets = WindowInsets.systemBars.add(WindowInsets.displayCutout).asPaddingValues()
+ val ld = LocalLayoutDirection.current
LazyVerticalGrid(
columns = GridCells.Adaptive(76.dp),
horizontalArrangement = Arrangement.Center,
contentPadding = PaddingValues(horizontal = horizontalPadding),
modifier =
Modifier
+ .padding(bottom = insets.calculateBottomPadding())
+ .background(colorResource(R.color.window_background))
+ .padding(start = insets.calculateStartPadding(ld), end = insets.calculateEndPadding(ld))
+ .clip(RoundedCornerShape(topStart = 22.dp, topEnd = 22.dp))
+ .background(colorResource(R.color.content_background))
.onGloballyPositioned {
gridWidth = with(density) {
it.size.width.toDp()
}
}
.nestedScroll(nestedScrollInterop)
- .background(colorResource(R.color.content_background))
) {
item(span = { GridItemSpan(3) }) {
Text(
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/customization/ComposeAvatarEquipmentFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/customization/ComposeAvatarEquipmentFragment.kt
index d8dc3ccf4..9ba1b0e2e 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/customization/ComposeAvatarEquipmentFragment.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/customization/ComposeAvatarEquipmentFragment.kt
@@ -1,7 +1,10 @@
package com.habitrpg.android.habitica.ui.fragments.inventory.customization
+import android.content.res.Configuration
import android.os.Bundle
import android.view.LayoutInflater
+import android.view.Menu
+import android.view.MenuInflater
import android.view.View
import android.view.ViewGroup
import androidx.compose.foundation.Image
@@ -12,10 +15,16 @@ import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.PaddingValues
+import androidx.compose.foundation.layout.WindowInsets
+import androidx.compose.foundation.layout.add
+import androidx.compose.foundation.layout.asPaddingValues
+import androidx.compose.foundation.layout.calculateEndPadding
+import androidx.compose.foundation.layout.calculateStartPadding
+import androidx.compose.foundation.layout.displayCutout
import androidx.compose.foundation.layout.fillMaxWidth
-import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
+import androidx.compose.foundation.layout.systemBars
import androidx.compose.foundation.lazy.grid.GridCells
import androidx.compose.foundation.lazy.grid.GridItemSpan
import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
@@ -37,6 +46,7 @@ import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.layout.onGloballyPositioned
import androidx.compose.ui.platform.LocalConfiguration
import androidx.compose.ui.platform.LocalDensity
+import androidx.compose.ui.platform.LocalLayoutDirection
import androidx.compose.ui.platform.ViewCompositionStrategy
import androidx.compose.ui.platform.rememberNestedScrollInteropConnection
import androidx.compose.ui.res.colorResource
@@ -49,6 +59,7 @@ import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.withStyle
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
+import androidx.core.content.ContextCompat
import androidx.fragment.app.viewModels
import androidx.lifecycle.ViewModel
import androidx.lifecycle.lifecycleScope
@@ -60,6 +71,7 @@ import com.habitrpg.android.habitica.helpers.AppConfigManager
import com.habitrpg.android.habitica.models.inventory.Equipment
import com.habitrpg.android.habitica.models.user.User
import com.habitrpg.android.habitica.ui.fragments.BaseMainFragment
+import com.habitrpg.android.habitica.ui.helpers.ToolbarColorHelper
import com.habitrpg.android.habitica.ui.theme.colors
import com.habitrpg.android.habitica.ui.viewmodels.MainUserViewModel
import com.habitrpg.android.habitica.ui.views.PixelArtView
@@ -167,6 +179,26 @@ class ComposeAvatarEquipmentFragment :
Analytics.sendNavigationEvent("${viewModel.type} screen")
}
+ override fun onCreateOptionsMenu(
+ menu: Menu,
+ inflater: MenuInflater
+ ) {
+ super.onCreateOptionsMenu(menu, inflater)
+
+ mainActivity?.toolbar?.let {
+ val color = ContextCompat.getColor(requireContext(), R.color.window_background)
+ ToolbarColorHelper.colorizeToolbar(it, mainActivity, backgroundColor = color,
+ appbar = mainActivity?.findViewById(R.id.appbar))
+ }
+ }
+
+ override fun onResume() {
+ if (requireActivity().resources.configuration.orientation == Configuration.ORIENTATION_LANDSCAPE) {
+ navigationBarColor = ContextCompat.getColor(requireContext(), R.color.window_background)
+ }
+ super.onResume()
+ }
+
private fun loadEquipment() {
val type = viewModel.type ?: return
lifecycleScope.launchCatching {
@@ -219,41 +251,47 @@ private fun AvatarEquipmentView(
activeCustomization: String?,
onSelect: (Equipment) -> Unit
) {
+ val configuration = LocalConfiguration.current
+ val isWidthGreaterHeight = configuration.screenWidthDp > configuration.screenHeightDp
+
Column(horizontalAlignment = Alignment.CenterHorizontally) {
- Column(horizontalAlignment = Alignment.CenterHorizontally, modifier = Modifier.background(colorResource(R.color.window_background))) {
+ Column(horizontalAlignment = Alignment.CenterHorizontally,
+ modifier = Modifier
+ .fillMaxWidth()
+ .background(colorResource(R.color.window_background))) {
ComposableAvatarView(
avatar = avatar,
configManager = configManager,
modifier =
Modifier
- .padding(top = 6.dp, bottom = 24.dp)
+ .padding(bottom = if (isWidthGreaterHeight) 8.dp else 24.dp)
.size(140.dp, 147.dp)
)
- Box(
- Modifier
- .background(colorResource(R.color.content_background), RoundedCornerShape(topStart = 22.dp, topEnd = 22.dp))
- .fillMaxWidth()
- .height(22.dp)
- )
}
val nestedScrollInterop = rememberNestedScrollInteropConnection()
val screenWidth = LocalConfiguration.current.screenWidthDp.dp
var gridWidth by remember { mutableStateOf(screenWidth) }
val horizontalPadding = (gridWidth - (84.dp * 3)) / 2
val density = LocalDensity.current
+ val insets = WindowInsets.systemBars.add(WindowInsets.displayCutout).asPaddingValues()
+ val ld = LocalLayoutDirection.current
LazyVerticalGrid(
columns = GridCells.Adaptive(76.dp),
horizontalArrangement = Arrangement.Center,
contentPadding = PaddingValues(horizontal = horizontalPadding),
modifier =
Modifier
+ .padding(bottom = insets.calculateBottomPadding())
+ .background(colorResource(R.color.window_background))
+ .padding(start = insets.calculateStartPadding(ld), end = insets.calculateEndPadding(ld))
+ .clip(RoundedCornerShape(topStart = 22.dp, topEnd = 22.dp))
+ .background(colorResource(R.color.content_background))
.onGloballyPositioned {
gridWidth = with(density) {
it.size.width.toDp()
}
}
.nestedScroll(nestedScrollInterop)
- .background(colorResource(R.color.content_background))
) {
item(span = { GridItemSpan(3) }) {
Text(
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/equipment/EquipmentDetailFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/equipment/EquipmentDetailFragment.kt
index 4c8c4d7d2..dd810adbf 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/equipment/EquipmentDetailFragment.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/equipment/EquipmentDetailFragment.kt
@@ -280,8 +280,11 @@ class EquipmentDetailFragment :
mainActivity?.toolbar?.let {
val color = ContextCompat.getColor(requireContext(), R.color.window_background)
- ToolbarColorHelper.colorizeToolbar(it, mainActivity, backgroundColor = color)
- requireActivity().window.statusBarColor = color
+
+ ToolbarColorHelper.colorizeToolbar(it,
+ mainActivity,
+ backgroundColor = color,
+ appbar = mainActivity?.findViewById(R.id.appbar))
}
}
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/stable/MountDetailRecyclerFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/stable/MountDetailRecyclerFragment.kt
index d4e0d89ae..201cec836 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/stable/MountDetailRecyclerFragment.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/stable/MountDetailRecyclerFragment.kt
@@ -125,6 +125,15 @@ class MountDetailRecyclerFragment :
outState.putString(ANIMAL_TYPE_KEY, this.animalType)
}
+ override fun onResume() {
+ super.onResume()
+ binding?.recyclerView?.let {
+ it.post {
+ setGridSpanCount(it.width - it.paddingStart - it.paddingEnd)
+ }
+ }
+ }
+
private fun setGridSpanCount(width: Int) {
var spanCount = 0
context?.resources?.let {
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/stable/PetDetailRecyclerFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/stable/PetDetailRecyclerFragment.kt
index 55bd5872a..f8e1b4ad6 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/stable/PetDetailRecyclerFragment.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/stable/PetDetailRecyclerFragment.kt
@@ -156,6 +156,11 @@ class PetDetailRecyclerFragment :
override fun onResume() {
super.onResume()
mainActivity?.title = animalType
+ binding?.recyclerView?.let {
+ it.post {
+ setGridSpanCount(it.width - it.paddingStart - it.paddingEnd)
+ }
+ }
}
override fun onSaveInstanceState(outState: Bundle) {
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/purchases/GemsPurchaseFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/purchases/GemsPurchaseFragment.kt
index c69cab97a..a47e0013d 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/purchases/GemsPurchaseFragment.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/purchases/GemsPurchaseFragment.kt
@@ -10,11 +10,7 @@ import androidx.compose.foundation.layout.padding
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.unit.dp
-import androidx.core.view.ViewCompat
-import androidx.core.view.WindowInsetsCompat
import androidx.core.view.isVisible
-import androidx.core.view.updateLayoutParams
-import androidx.core.view.updatePadding
import androidx.fragment.app.Fragment
import androidx.lifecycle.lifecycleScope
import com.android.billingclient.api.ProductDetails
@@ -23,7 +19,6 @@ import com.habitrpg.android.habitica.data.UserRepository
import com.habitrpg.android.habitica.databinding.FragmentGemPurchaseBinding
import com.habitrpg.android.habitica.extensions.addCancelButton
import com.habitrpg.android.habitica.extensions.addCloseButton
-import com.habitrpg.android.habitica.extensions.consumeWindowInsetsAbove30
import com.habitrpg.android.habitica.helpers.Analytics
import com.habitrpg.android.habitica.helpers.AppConfigManager
import com.habitrpg.android.habitica.helpers.PurchaseHandler
@@ -36,7 +31,6 @@ import com.habitrpg.android.habitica.ui.fragments.PromoInfoFragment
import com.habitrpg.android.habitica.ui.helpers.dismissKeyboard
import com.habitrpg.android.habitica.ui.views.dialogs.HabiticaAlertDialog
import com.habitrpg.android.habitica.ui.views.promo.BirthdayBanner
-import com.habitrpg.common.habitica.extensions.dpToPx
import com.habitrpg.common.habitica.extensions.isUsingNightModeResources
import com.habitrpg.common.habitica.helpers.ExceptionHandler
import com.habitrpg.common.habitica.helpers.launchCatching
@@ -129,19 +123,6 @@ class GemsPurchaseFragment : BaseFragment() {
}
loadInventory()
- binding?.bottomSpacing?.let {
- ViewCompat.setOnApplyWindowInsetsListener(it) { v, insets ->
- val bars = insets.getInsets(
- WindowInsetsCompat.Type.systemBars()
- or WindowInsetsCompat.Type.displayCutout()
- )
- v.updateLayoutParams {
- height = bars.bottom + 30.dpToPx(requireContext())
- }
- consumeWindowInsetsAbove30(insets)
- }
- }
-
Analytics.sendNavigationEvent("gem screen")
}
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/QuestDetailFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/QuestDetailFragment.kt
index adf519f2a..d63348f90 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/QuestDetailFragment.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/QuestDetailFragment.kt
@@ -15,7 +15,6 @@ import com.habitrpg.android.habitica.R
import com.habitrpg.android.habitica.data.InventoryRepository
import com.habitrpg.android.habitica.data.SocialRepository
import com.habitrpg.android.habitica.databinding.FragmentQuestDetailBinding
-import com.habitrpg.android.habitica.extensions.applyScrollContentWindowInsets
import com.habitrpg.android.habitica.helpers.HapticFeedbackManager
import com.habitrpg.android.habitica.models.inventory.Quest
import com.habitrpg.android.habitica.models.inventory.QuestContent
@@ -101,7 +100,6 @@ class QuestDetailFragment : BaseMainFragment() {
updateQuestContent(it)
}
}
- binding?.scrollContent?.let { applyScrollContentWindowInsets(it) }
}
private fun updateParty(group: Group?) {
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/challenges/ChallengeDetailFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/challenges/ChallengeDetailFragment.kt
index fa2e3f817..79f68f496 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/challenges/ChallengeDetailFragment.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/challenges/ChallengeDetailFragment.kt
@@ -18,7 +18,6 @@ import com.habitrpg.android.habitica.data.SocialRepository
import com.habitrpg.android.habitica.databinding.DialogChallengeDetailTaskGroupBinding
import com.habitrpg.android.habitica.databinding.FragmentChallengeDetailBinding
import com.habitrpg.android.habitica.extensions.addCloseButton
-import com.habitrpg.android.habitica.extensions.applyScrollContentWindowInsets
import com.habitrpg.android.habitica.models.members.Member
import com.habitrpg.android.habitica.models.social.Challenge
import com.habitrpg.android.habitica.models.tasks.Task
@@ -166,7 +165,6 @@ class ChallengeDetailFragment : BaseMainFragment
}
}
binding?.leaveButton?.setOnClickListener { showChallengeLeaveDialog() }
- binding?.scrollContent?.let { applyScrollContentWindowInsets(it) }
refresh()
}
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/guilds/GuildDetailFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/guilds/GuildDetailFragment.kt
index e7a2dc276..fb59d6655 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/guilds/GuildDetailFragment.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/guilds/GuildDetailFragment.kt
@@ -18,8 +18,6 @@ import com.habitrpg.android.habitica.R
import com.habitrpg.android.habitica.data.ChallengeRepository
import com.habitrpg.android.habitica.data.UserRepository
import com.habitrpg.android.habitica.databinding.FragmentGuildDetailBinding
-import com.habitrpg.android.habitica.extensions.applyScrollContentWindowInsets
-import com.habitrpg.android.habitica.extensions.consumeWindowInsetsAbove30
import com.habitrpg.android.habitica.helpers.AppConfigManager
import com.habitrpg.android.habitica.models.members.Member
import com.habitrpg.android.habitica.models.social.Challenge
@@ -94,8 +92,6 @@ class GuildDetailFragment : BaseFragment() {
MainNavigationController.navigate(profileDirections)
}
}
-
- binding?.scrollContent?.let { applyScrollContentWindowInsets(it) }
}
private fun setLeader(leader: Member?) {
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/party/NoPartyFragmentFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/party/NoPartyFragmentFragment.kt
index a6b0ac18e..e7726d828 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/party/NoPartyFragmentFragment.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/party/NoPartyFragmentFragment.kt
@@ -17,7 +17,6 @@ import androidx.lifecycle.lifecycleScope
import com.habitrpg.android.habitica.R
import com.habitrpg.android.habitica.data.SocialRepository
import com.habitrpg.android.habitica.databinding.FragmentNoPartyBinding
-import com.habitrpg.android.habitica.extensions.applyScrollContentWindowInsets
import com.habitrpg.android.habitica.helpers.AppConfigManager
import com.habitrpg.android.habitica.ui.activities.GroupFormActivity
import com.habitrpg.android.habitica.ui.fragments.BaseMainFragment
@@ -145,8 +144,6 @@ class NoPartyFragmentFragment : BaseMainFragment() {
}
}
}
-
- binding?.scrollContent?.let { applyScrollContentWindowInsets(it) }
}
private val groupFormResult =
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/party/PartyDetailFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/party/PartyDetailFragment.kt
index 34343b459..e6922f67c 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/party/PartyDetailFragment.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/party/PartyDetailFragment.kt
@@ -20,7 +20,6 @@ import com.habitrpg.android.habitica.data.InventoryRepository
import com.habitrpg.android.habitica.data.SocialRepository
import com.habitrpg.android.habitica.data.UserRepository
import com.habitrpg.android.habitica.databinding.FragmentPartyDetailBinding
-import com.habitrpg.android.habitica.extensions.applyScrollContentWindowInsets
import com.habitrpg.android.habitica.helpers.AppConfigManager
import com.habitrpg.android.habitica.helpers.HapticFeedbackManager
import com.habitrpg.android.habitica.models.inventory.QuestContent
@@ -162,8 +161,6 @@ class PartyDetailFragment : BaseFragment() {
binding?.questMechanicsButton?.setOnClickListener {
showQuestMechanicsDialog()
}
-
- binding?.scrollContent?.let { applyScrollContentWindowInsets(it) }
}
private fun refreshParty() {
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/party/PartyInviteFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/party/PartyInviteFragment.kt
index f87f592f1..97a19c7cc 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/party/PartyInviteFragment.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/party/PartyInviteFragment.kt
@@ -8,7 +8,6 @@ import androidx.compose.animation.core.Spring
import androidx.compose.animation.core.animateFloat
import androidx.compose.animation.core.spring
import androidx.compose.animation.core.updateTransition
-import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.gestures.Orientation
@@ -16,16 +15,20 @@ import androidx.compose.foundation.gestures.scrollable
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.WindowInsets
+import androidx.compose.foundation.layout.asPaddingValues
+import androidx.compose.foundation.layout.calculateEndPadding
+import androidx.compose.foundation.layout.calculateStartPadding
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.safeContent
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.rememberScrollState
import androidx.compose.material3.Button
import androidx.compose.material3.ButtonDefaults
-import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Text
import androidx.compose.material3.TextField
import androidx.compose.material3.TextFieldDefaults
@@ -42,6 +45,7 @@ import androidx.compose.ui.draw.rotate
import androidx.compose.ui.focus.onFocusChanged
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.ColorFilter
+import androidx.compose.ui.platform.LocalLayoutDirection
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.TextStyle
@@ -144,7 +148,6 @@ class PartyInviteFragment : BaseFragment() {
}
}
-@OptIn(ExperimentalFoundationApi::class, ExperimentalMaterial3Api::class)
@Composable
fun PartyInviteView(
viewModel: PartyInviteViewModel,
@@ -154,10 +157,14 @@ fun PartyInviteView(
val scope = rememberCoroutineScope()
val scrollableState = rememberScrollState()
+ val padding = WindowInsets.safeContent.asPaddingValues()
+ val ld = LocalLayoutDirection.current
+
LazyColumn(
Modifier
.fillMaxSize()
.padding(14.dp)
+ .padding(start = padding.calculateStartPadding(ld), end = padding.calculateEndPadding(ld))
.scrollable(scrollableState, Orientation.Vertical)
) {
item {
@@ -201,7 +208,7 @@ fun PartyInviteView(
.padding(0.dp, 4.dp)
.background(HabiticaTheme.colors.windowBackground, HabiticaTheme.shapes.medium)
.padding(4.dp, 4.dp)
- .animateItemPlacement()
+ .animateItem()
) {
Button(
onClick = {
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/support/BugFixFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/support/BugFixFragment.kt
index 23662d54b..bc60104be 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/support/BugFixFragment.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/support/BugFixFragment.kt
@@ -13,7 +13,6 @@ import androidx.lifecycle.lifecycleScope
import com.habitrpg.android.habitica.R
import com.habitrpg.android.habitica.databinding.FragmentSupportBugFixBinding
import com.habitrpg.android.habitica.databinding.KnownIssueBinding
-import com.habitrpg.android.habitica.extensions.applyScrollContentWindowInsets
import com.habitrpg.android.habitica.helpers.AppConfigManager
import com.habitrpg.android.habitica.ui.fragments.BaseMainFragment
import com.habitrpg.android.habitica.ui.viewmodels.MainUserViewModel
@@ -81,7 +80,6 @@ class BugFixFragment : BaseMainFragment() {
}
binding?.knownIssuesLayout?.addView(issueBinding.root)
}
- binding?.scrollContent?.let { applyScrollContentWindowInsets(it) }
}
private val versionName: String by lazy {
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/support/FAQDetailFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/support/FAQDetailFragment.kt
index 46fbb4135..926611363 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/support/FAQDetailFragment.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/support/FAQDetailFragment.kt
@@ -8,7 +8,6 @@ import android.view.ViewGroup
import androidx.lifecycle.lifecycleScope
import com.habitrpg.android.habitica.data.FAQRepository
import com.habitrpg.android.habitica.databinding.FragmentFaqDetailBinding
-import com.habitrpg.android.habitica.extensions.applyScrollContentWindowInsets
import com.habitrpg.android.habitica.ui.fragments.BaseMainFragment
import com.habitrpg.common.habitica.helpers.MarkdownParser
import com.habitrpg.common.habitica.helpers.launchCatching
@@ -61,6 +60,5 @@ class FAQDetailFragment : BaseMainFragment() {
}
binding?.answerTextView?.movementMethod = LinkMovementMethod.getInstance()
- binding?.scrollContent?.let { applyScrollContentWindowInsets(it) }
}
}
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/support/FAQOverviewFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/support/FAQOverviewFragment.kt
index 42f25a5fa..f0d16286f 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/support/FAQOverviewFragment.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/support/FAQOverviewFragment.kt
@@ -24,7 +24,6 @@ import com.habitrpg.android.habitica.R
import com.habitrpg.android.habitica.data.FAQRepository
import com.habitrpg.android.habitica.databinding.FragmentFaqOverviewBinding
import com.habitrpg.android.habitica.databinding.SupportFaqItemBinding
-import com.habitrpg.android.habitica.extensions.applyScrollContentWindowInsets
import com.habitrpg.android.habitica.helpers.AppConfigManager
import com.habitrpg.android.habitica.ui.fragments.BaseMainFragment
import com.habitrpg.android.habitica.ui.viewmodels.MainUserViewModel
@@ -172,8 +171,6 @@ class FAQOverviewFragment : BaseMainFragment() {
binding?.moreHelpTextView?.movementMethod = LinkMovementMethod.getInstance()
this.loadArticles()
-
- binding?.scrollContent?.let { applyScrollContentWindowInsets(it) }
}
override fun onDestroy() {
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/support/SupportMainFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/support/SupportMainFragment.kt
index f6062f379..329f427eb 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/support/SupportMainFragment.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/support/SupportMainFragment.kt
@@ -10,7 +10,6 @@ import androidx.lifecycle.lifecycleScope
import com.habitrpg.android.habitica.R
import com.habitrpg.android.habitica.data.FAQRepository
import com.habitrpg.android.habitica.databinding.FragmentSupportMainBinding
-import com.habitrpg.android.habitica.extensions.applyScrollContentWindowInsets
import com.habitrpg.android.habitica.helpers.AppConfigManager
import com.habitrpg.android.habitica.ui.fragments.BaseMainFragment
import com.habitrpg.android.habitica.ui.views.HabiticaSnackbar
@@ -76,8 +75,6 @@ class SupportMainFragment : BaseMainFragment() {
)
}
}
- binding?.resetTutorialButtonWrapper?.let { applyScrollContentWindowInsets(it) }
-
}
override fun onDestroy() {
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/helpers/ToolbarColorHelper.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/helpers/ToolbarColorHelper.kt
index 86dfb3b26..18bead58a 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/helpers/ToolbarColorHelper.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/helpers/ToolbarColorHelper.kt
@@ -25,6 +25,7 @@ import android.widget.TextView
import androidx.appcompat.view.menu.ActionMenuItemView
import androidx.appcompat.widget.ActionMenuView
import androidx.appcompat.widget.Toolbar
+import com.google.android.material.appbar.AppBarLayout
import com.habitrpg.android.habitica.R
import com.habitrpg.common.habitica.extensions.getThemeColor
import com.habitrpg.common.habitica.extensions.waitForLayout
@@ -43,12 +44,14 @@ object ToolbarColorHelper {
toolbar: Toolbar,
activity: Activity?,
iconColor: Int? = null,
- backgroundColor: Int? = null
+ backgroundColor: Int? = null,
+ appbar: AppBarLayout? = null
) {
if (activity == null) return
toolbar.setBackgroundColor(
backgroundColor ?: activity.getThemeColor(R.attr.headerBackgroundColor)
)
+ appbar?.setBackgroundColor(backgroundColor ?: activity.getThemeColor(R.attr.headerBackgroundColor))
val toolbarIconsColor = iconColor ?: activity.getThemeColor(R.attr.headerTextColor)
val colorFilter = PorterDuffColorFilter(toolbarIconsColor, PorterDuff.Mode.MULTIPLY)
for (i in 0 until toolbar.childCount) {
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/HabiticaScrollView.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/HabiticaScrollView.kt
new file mode 100644
index 000000000..43d920a96
--- /dev/null
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/HabiticaScrollView.kt
@@ -0,0 +1,33 @@
+package com.habitrpg.android.habitica.ui.views
+
+import android.content.Context
+import android.util.AttributeSet
+import android.view.ViewGroup
+import androidx.core.view.children
+import androidx.core.widget.NestedScrollView
+import com.habitrpg.android.habitica.R
+import com.habitrpg.android.habitica.extensions.applyScrollContentWindowInsets
+
+class HabiticaScrollView @JvmOverloads constructor(
+ context: Context, attrs: AttributeSet? = null
+) : NestedScrollView(context, attrs) {
+ private var skipDirectChild = false
+
+ init {
+ context.theme?.obtainStyledAttributes(attrs, R.styleable.HabiticaScrollView, 0, 0)?.let {
+ skipDirectChild = it.getBoolean(R.styleable.HabiticaScrollView_skipDirectchild, false)
+ }
+ }
+
+ override fun onAttachedToWindow() {
+ super.onAttachedToWindow()
+ var paddedChildren = children
+ if (skipDirectChild) {
+ paddedChildren = (paddedChildren.firstOrNull() as? ViewGroup)?.children ?: emptySequence()
+ }
+ paddedChildren.forEach {
+ applyScrollContentWindowInsets(it,
+ applyBottom = paddedChildren.lastOrNull() == it)
+ }
+ }
+}
\ No newline at end of file
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/social/ChatBarView.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/social/ChatBarView.kt
index 8babec169..40d767c9f 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/social/ChatBarView.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/social/ChatBarView.kt
@@ -1,8 +1,11 @@
package com.habitrpg.android.habitica.ui.views.social
import android.content.Context
+import android.content.res.Configuration
import android.util.AttributeSet
import android.view.View
+import android.view.inputmethod.EditorInfo
+import android.view.inputmethod.InputMethodManager
import android.widget.LinearLayout
import android.widget.TextView
import androidx.core.content.ContextCompat
@@ -75,6 +78,16 @@ class ChatBarView : LinearLayout {
updateTextIndicator(binding.chatEditText.text.toString())
}
)
+ binding.chatEditText.setOnEditorActionListener { v, actionId, _ ->
+ if (actionId == EditorInfo.IME_ACTION_SEND) {
+ sendButtonPressed()
+ if (context.resources.configuration.orientation == Configuration.ORIENTATION_LANDSCAPE) {
+ val inputService = context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
+ inputService.hideSoftInputFromWindow(v.windowToken, 0)
+ }
+ }
+ true
+ }
binding.sendButton.setOnClickListener { sendButtonPressed() }
diff --git a/version.properties b/version.properties
index 0b155895f..09a15ed37 100644
--- a/version.properties
+++ b/version.properties
@@ -1,2 +1,2 @@
NAME=4.7.0
-CODE=12381
\ No newline at end of file
+CODE=12401
\ No newline at end of file