From b15bc38c0adff866e474f1566fde3449425ff8f1 Mon Sep 17 00:00:00 2001 From: Phillip Thelen Date: Fri, 4 Jun 2021 16:11:48 +0200 Subject: [PATCH] Update deprecated code --- .../res/drawable-hdpi/drawer_shadow.9.png | Bin 101 -> 127 bytes .../res/layout/activity_adventure_guide.xml | 1 - .../res/layout/activity_class_selection.xml | 3 +- .../res/layout/activity_create_challenge.xml | 3 +- Habitica/res/layout/activity_fixcharacter.xml | 5 +- Habitica/res/layout/activity_full_profile.xml | 3 +- Habitica/res/layout/activity_gift_gems.xml | 3 +- .../res/layout/activity_gift_subscription.xml | 3 +- Habitica/res/layout/activity_group_form.xml | 7 +- Habitica/res/layout/activity_guidelines.xml | 3 +- .../res/layout/activity_notifications.xml | 3 +- Habitica/res/layout/activity_party_invite.xml | 3 +- Habitica/res/layout/activity_prefs.xml | 3 +- .../res/layout/activity_report_message.xml | 3 +- .../res/layout/activity_skill_members.xml | 3 +- Habitica/res/layout/activity_skill_tasks.xml | 3 +- Habitica/res/layout/activity_task_form.xml | 3 +- .../res/layout/activity_verify_username.xml | 4 +- Habitica/res/layout/adventure_guide_item.xml | 1 - Habitica/res/layout/avatar_with_bars.xml | 1 - Habitica/res/layout/daily_item_card.xml | 1 - Habitica/res/layout/dialog_first_drop.xml | 1 - .../res/layout/dialog_hatch_pet_button.xml | 2 - Habitica/res/layout/dialog_levelup.xml | 4 +- Habitica/res/layout/dialog_levelup_10.xml | 4 +- .../res/layout/dialog_pet_suggest_hatch.xml | 1 - .../dialog_purchase_shopitem_button.xml | 1 - .../dialog_purchase_shopitem_header.xml | 1 - Habitica/res/layout/fragment_about.xml | 3 +- Habitica/res/layout/fragment_chat.xml | 1 - .../layout/fragment_equipment_overview.xml | 4 +- Habitica/res/layout/fragment_faq_overview.xml | 2 +- Habitica/res/layout/fragment_gem_purchase.xml | 3 +- Habitica/res/layout/fragment_guild_detail.xml | 6 +- Habitica/res/layout/fragment_guild_list.xml | 1 - .../layout/fragment_inbox_message_list.xml | 1 - Habitica/res/layout/fragment_items.xml | 1 - Habitica/res/layout/fragment_no_party.xml | 3 +- Habitica/res/layout/fragment_quest_detail.xml | 2 - Habitica/res/layout/fragment_recyclerview.xml | 3 +- .../layout/fragment_recyclerview_stable.xml | 3 +- .../layout/fragment_refresh_recyclerview.xml | 1 - Habitica/res/layout/fragment_skills.xml | 1 - Habitica/res/layout/fragment_stats.xml | 3 +- Habitica/res/layout/fragment_subscription.xml | 3 +- Habitica/res/layout/fragment_support_main.xml | 1 - Habitica/res/layout/fragment_viewpager.xml | 3 +- Habitica/res/layout/mount_overview_item.xml | 1 - Habitica/res/layout/notification_item.xml | 1 - Habitica/res/layout/notifications_header.xml | 1 - Habitica/res/layout/pet_overview_item.xml | 1 - Habitica/res/layout/progress_bar.xml | 1 - Habitica/res/layout/reward_item_card.xml | 3 +- .../res/layout/row_quest_reward_imageview.xml | 1 - Habitica/res/layout/row_shopitem.xml | 1 - Habitica/res/layout/skill_task_item_card.xml | 1 - Habitica/res/layout/system_chat_message.xml | 3 +- Habitica/res/layout/todo_item_card.xml | 1 - Habitica/res/layout/value_bar.xml | 7 +- Habitica/res/menu/inbox_chat.xml | 3 +- Habitica/res/menu/menu_create_refresh.xml | 3 +- Habitica/res/menu/menu_full_profile.xml | 4 +- Habitica/res/menu/menu_party_admin.xml | 3 +- Habitica/res/menu/menu_party_invite.xml | 3 +- Habitica/res/menu/menu_save.xml | 3 +- Habitica/res/menu/menu_task_create.xml | 3 +- Habitica/res/menu/menu_task_edit.xml | 3 +- Habitica/res/values-be/strings.xml | 2 +- Habitica/res/values-de/strings.xml | 2 +- Habitica/res/values-el/strings.xml | 2 +- Habitica/res/values-en-rGB/strings.xml | 2 +- Habitica/res/values-es/strings.xml | 2 +- Habitica/res/values-fi/strings.xml | 2 +- Habitica/res/values-fr/strings.xml | 2 +- Habitica/res/values-hi/strings.xml | 2 +- Habitica/res/values-hu/strings.xml | 2 +- Habitica/res/values-it/strings.xml | 2 +- Habitica/res/values-iw/strings.xml | 2 +- Habitica/res/values-ja/strings.xml | 2 +- Habitica/res/values-ko/strings.xml | 2 +- Habitica/res/values-lt/strings.xml | 2 +- Habitica/res/values-nl/strings.xml | 2 +- Habitica/res/values-pl/strings.xml | 2 +- Habitica/res/values-pt-rBR/strings.xml | 2 +- Habitica/res/values-pt-rPT/strings.xml | 2 +- Habitica/res/values-ru/strings.xml | 2 +- Habitica/res/values-sv/strings.xml | 2 +- Habitica/res/values-th/strings.xml | 2 +- Habitica/res/values-tr/strings.xml | 2 +- Habitica/res/values-uk/strings.xml | 2 +- Habitica/res/values-vi/strings.xml | 2 +- Habitica/res/values-zh-rTW/strings.xml | 2 +- Habitica/res/values-zh/strings.xml | 2 +- Habitica/res/values/attrs.xml | 6 - Habitica/res/values/strings.xml | 2 +- Habitica/res/values/styles.habitica.xml | 2 +- .../habitica/components/UserComponent.java | 3 + .../android/habitica/data/TaskRepository.kt | 2 - .../data/implementation/ApiClientImpl.kt | 8 +- .../implementation/InventoryRepositoryImpl.kt | 2 +- .../data/implementation/TaskRepositoryImpl.kt | 12 +- .../data/local/InventoryLocalRepository.kt | 8 +- .../data/local/TaskLocalRepository.kt | 2 - .../RealmBaseLocalRepository.kt | 13 + .../RealmInventoryLocalRepository.kt | 159 +++++------ .../RealmTaskLocalRepository.kt | 4 - .../RealmTutorialLocalRepository.kt | 3 +- .../RealmUserLocalRepository.kt | 54 +--- .../habitica/helpers/PurchaseHandler.kt | 8 +- .../habitica/helpers/TaskAlarmManager.kt | 2 - .../interactors/CheckClassSelectionUseCase.kt | 4 +- .../models/responses/ErrorResponse.java | 21 -- .../models/responses/ErrorResponse.kt | 16 ++ .../models/responses/HabitResponse.java | 39 --- .../models/responses/HabitResponse.kt | 10 + .../models/responses/HabiticaError.java | 7 - .../models/responses/HabiticaError.kt | 7 + .../android/habitica/models/user/Items.kt | 7 + .../habitica/ui/activities/BaseActivity.kt | 2 +- .../ui/activities/ChallengeFormActivity.kt | 47 ++-- .../ui/activities/ClassSelectionActivity.kt | 1 - .../ui/activities/GiftSubscriptionActivity.kt | 2 + .../habitica/ui/activities/LoginActivity.kt | 33 ++- .../habitica/ui/activities/MainActivity.kt | 42 +-- .../ui/activities/NotificationsActivity.kt | 7 +- .../adapter/inventory/ItemRecyclerAdapter.kt | 3 +- .../tasks/RewardsRecyclerViewAdapter.kt | 2 +- .../ui/fragments/BaseDialogFragment.kt | 118 ++++++++ .../habitica/ui/fragments/BaseFragment.kt | 6 +- .../ui/fragments/NavigationDrawerFragment.kt | 14 +- .../inventory/items/ItemDialogFragment.kt | 264 ++++++++++++++++++ .../inventory/items/ItemRecyclerFragment.kt | 79 +----- .../inventory/items/ItemsFragment.kt | 38 +-- .../stable/PetDetailRecyclerFragment.kt | 3 +- .../inventory/stable/StableFragment.kt | 29 +- .../preferences/PreferencesFragment.kt | 10 +- .../ui/fragments/skills/SkillsFragment.kt | 35 +-- .../ui/fragments/social/TavernFragment.kt | 31 +- .../challenges/ChallengesOverviewFragment.kt | 31 +- .../social/guilds/GuildDetailFragment.kt | 51 ++-- .../fragments/social/guilds/GuildFragment.kt | 52 ++-- .../social/guilds/GuildOverviewFragment.kt | 52 ++-- .../social/party/NoPartyFragmentFragment.kt | 46 ++- .../social/party/PartyDetailFragment.kt | 2 +- .../fragments/social/party/PartyFragment.kt | 118 ++++---- .../tasks/RewardsRecyclerviewFragment.kt | 36 +-- .../tasks/TaskRecyclerViewFragment.kt | 2 +- .../ui/fragments/tasks/TasksFragment.kt | 48 ++-- .../ui/fragments/tasks/TeamBoardFragment.kt | 41 +-- .../habitica/ui/views/DragLinearLayout.kt | 31 +- .../android/habitica/ui/views/ValueBar.kt | 1 - .../ui/views/dialogs/PetSuggestHatchDialog.kt | 18 +- .../ui/views/dialogs/WonChallengeDialog.kt | 2 +- .../ui/views/settings/FixValuesEditText.kt | 59 ---- .../habitica/ui/views/shops/PurchaseDialog.kt | 10 +- .../ui/views/stats/StatsSliderView.kt | 1 - .../tasks/form/TaskSchedulingControls.kt | 2 +- .../habitica/utils/UserDeserializer.kt | 7 +- 158 files changed, 1005 insertions(+), 989 deletions(-) delete mode 100644 Habitica/src/main/java/com/habitrpg/android/habitica/models/responses/ErrorResponse.java create mode 100644 Habitica/src/main/java/com/habitrpg/android/habitica/models/responses/ErrorResponse.kt delete mode 100644 Habitica/src/main/java/com/habitrpg/android/habitica/models/responses/HabitResponse.java create mode 100644 Habitica/src/main/java/com/habitrpg/android/habitica/models/responses/HabitResponse.kt delete mode 100644 Habitica/src/main/java/com/habitrpg/android/habitica/models/responses/HabiticaError.java create mode 100644 Habitica/src/main/java/com/habitrpg/android/habitica/models/responses/HabiticaError.kt create mode 100644 Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/BaseDialogFragment.kt create mode 100644 Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/items/ItemDialogFragment.kt delete mode 100644 Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/settings/FixValuesEditText.kt diff --git a/Habitica/res/drawable-hdpi/drawer_shadow.9.png b/Habitica/res/drawable-hdpi/drawer_shadow.9.png index 898d6035aa54551d058632bc919260705b58966f..227cf4b057929db1e40fc594535688f555930c61 100644 GIT binary patch delta 107 zcmYeTpCFmW#=yXk!D?j%q})7R978JNk`o#l{<|dYcod=VjVXy+;Tl5{r@}MFB()hz z8V%V}R}UDhVr1>fk^nRK+)R725+trNupjnf?r`KuV_?WNtJS${b?Xe!L>l++dt=y2sV8-ZZ=*vPBu9^)Yz5`njxgN@xNA diff --git a/Habitica/res/layout/activity_class_selection.xml b/Habitica/res/layout/activity_class_selection.xml index 1c9e260ff..98892185f 100644 --- a/Habitica/res/layout/activity_class_selection.xml +++ b/Habitica/res/layout/activity_class_selection.xml @@ -4,8 +4,7 @@ xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent" - android:orientation="vertical" - android:background="@color/content_background"> + android:orientation="vertical"> diff --git a/Habitica/res/layout/activity_create_challenge.xml b/Habitica/res/layout/activity_create_challenge.xml index 5e9d36fb7..3a248ab28 100644 --- a/Habitica/res/layout/activity_create_challenge.xml +++ b/Habitica/res/layout/activity_create_challenge.xml @@ -5,8 +5,7 @@ android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".ui.activities.PrefsActivity" - android:orientation="vertical" - android:background="?attr/colorContentBackground"> + android:orientation="vertical"> + tools:context="com.habitrpg.android.habitica.ui.activities.FixCharacterValuesActivity"> @@ -181,7 +180,7 @@ android:layout_width="0dp" android:layout_weight="1" android:background="@drawable/layout_rounded_bg_window" - android:hint="@string/gold_capitalilzed" + android:hint="@string/gold_capitalized" android:paddingStart="16dp"> + tools:context="com.habitrpg.android.habitica.ui.activities.FixCharacterValuesActivity"> diff --git a/Habitica/res/layout/activity_gift_gems.xml b/Habitica/res/layout/activity_gift_gems.xml index d494d0732..3d4f79166 100644 --- a/Habitica/res/layout/activity_gift_gems.xml +++ b/Habitica/res/layout/activity_gift_gems.xml @@ -2,8 +2,7 @@ + android:layout_height="match_parent"> + tools:context="com.habitrpg.android.habitica.ui.activities.FixCharacterValuesActivity"> diff --git a/Habitica/res/layout/activity_group_form.xml b/Habitica/res/layout/activity_group_form.xml index 0e740823a..875d88a24 100644 --- a/Habitica/res/layout/activity_group_form.xml +++ b/Habitica/res/layout/activity_group_form.xml @@ -3,8 +3,7 @@ xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent" - xmlns:tools="http://schemas.android.com/tools" - android:background="?attr/colorContentBackground"> + xmlns:tools="http://schemas.android.com/tools"> + android:contentDescription="@string/cancel" + app:tint="?colorPrimary" /> + android:orientation="vertical"> + tools:context=".ui.activities.NotificationsActivity"> + android:layout_height="match_parent"> + android:orientation="vertical"> + app:behavior_hideable="true"> + android:orientation="vertical"> + android:orientation="vertical"> + tools:context="com.habitrpg.android.habitica.ui.activities.FixCharacterValuesActivity"> diff --git a/Habitica/res/layout/activity_verify_username.xml b/Habitica/res/layout/activity_verify_username.xml index 3be1b7ff5..22cf00636 100644 --- a/Habitica/res/layout/activity_verify_username.xml +++ b/Habitica/res/layout/activity_verify_username.xml @@ -2,8 +2,7 @@ + xmlns:tools="http://schemas.android.com/tools"> @@ -22,7 +21,6 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:padding="@dimen/spacing_large" - android:background="@color/content_background" android:orientation="vertical"> diff --git a/Habitica/res/layout/dialog_levelup.xml b/Habitica/res/layout/dialog_levelup.xml index 45e0ef965..86309fda1 100644 --- a/Habitica/res/layout/dialog_levelup.xml +++ b/Habitica/res/layout/dialog_levelup.xml @@ -1,7 +1,7 @@ + android:scrollbars="vertical"> diff --git a/Habitica/res/layout/fragment_equipment_overview.xml b/Habitica/res/layout/fragment_equipment_overview.xml index 5c62ec980..198296c87 100644 --- a/Habitica/res/layout/fragment_equipment_overview.xml +++ b/Habitica/res/layout/fragment_equipment_overview.xml @@ -1,9 +1,7 @@ - diff --git a/Habitica/res/layout/fragment_faq_overview.xml b/Habitica/res/layout/fragment_faq_overview.xml index 053f182f9..bc1bec4da 100644 --- a/Habitica/res/layout/fragment_faq_overview.xml +++ b/Habitica/res/layout/fragment_faq_overview.xml @@ -54,7 +54,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content" app:subtitle="@string/currency" - app:title="@string/gold_capitalilzed" + app:title="@string/gold_capitalized" app:titleColor="@color/text_orange_white" android:layout_marginStart="@dimen/spacing_medium" android:layout_marginEnd="@dimen/spacing_medium" diff --git a/Habitica/res/layout/fragment_gem_purchase.xml b/Habitica/res/layout/fragment_gem_purchase.xml index 62ebb63a0..c2d537f26 100644 --- a/Habitica/res/layout/fragment_gem_purchase.xml +++ b/Habitica/res/layout/fragment_gem_purchase.xml @@ -5,8 +5,7 @@ xmlns:tools="http://schemas.android.com/tools" android:scrollbarSize="3dp" android:scrollbarThumbVertical="@color/scrollbarThumb" - android:scrollbars="vertical" - android:background="@color/content_background"> + android:scrollbars="vertical"> + android:layout_height="match_parent"> + android:layout_height="wrap_content"> diff --git a/Habitica/res/layout/fragment_items.xml b/Habitica/res/layout/fragment_items.xml index 1b6ba9193..34a0fe2e9 100644 --- a/Habitica/res/layout/fragment_items.xml +++ b/Habitica/res/layout/fragment_items.xml @@ -16,7 +16,6 @@ android:id="@+id/refreshLayout" android:layout_width="match_parent" android:layout_height="match_parent" - android:background="@color/content_background" app:layout_behavior="@string/appbar_scrolling_view_behavior"> + android:id="@+id/refreshLayout"> + android:layout_height="match_parent"> + android:clipToPadding="false"/> diff --git a/Habitica/res/layout/fragment_stats.xml b/Habitica/res/layout/fragment_stats.xml index d8d7bc6f9..5701b7060 100644 --- a/Habitica/res/layout/fragment_stats.xml +++ b/Habitica/res/layout/fragment_stats.xml @@ -6,8 +6,7 @@ xmlns:app="http://schemas.android.com/apk/res-auto" android:scrollbarSize="3dp" android:scrollbarThumbVertical="@color/scrollbarThumb" - android:scrollbars="vertical" - android:background="?attr/colorContentBackground"> + android:scrollbars="vertical"> + android:scrollbars="vertical"> - \ No newline at end of file diff --git a/Habitica/res/layout/mount_overview_item.xml b/Habitica/res/layout/mount_overview_item.xml index 62502d03e..5a9a9844a 100644 --- a/Habitica/res/layout/mount_overview_item.xml +++ b/Habitica/res/layout/mount_overview_item.xml @@ -4,7 +4,6 @@ android:layout_height="wrap_content" xmlns:app="http://schemas.android.com/apk/res-auto" android:clickable="true" - android:background="?attr/colorContentBackground" android:focusable="true"> + android:layout_height="wrap_content"> diff --git a/Habitica/res/layout/row_shopitem.xml b/Habitica/res/layout/row_shopitem.xml index bbfb27cfe..ab544266b 100644 --- a/Habitica/res/layout/row_shopitem.xml +++ b/Habitica/res/layout/row_shopitem.xml @@ -4,7 +4,6 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:clickable="true" - android:background="@color/content_background" android:focusable="true"> + android:paddingBottom="4dp"> diff --git a/Habitica/res/layout/value_bar.xml b/Habitica/res/layout/value_bar.xml index 396900ad6..2ffa3a073 100644 --- a/Habitica/res/layout/value_bar.xml +++ b/Habitica/res/layout/value_bar.xml @@ -1,10 +1,9 @@ + android:layout_height="wrap_content" + android:orientation="horizontal"> + xmlns:app="http://schemas.android.com/apk/res-auto"> diff --git a/Habitica/res/menu/menu_create_refresh.xml b/Habitica/res/menu/menu_create_refresh.xml index 4a5396631..c45d8f244 100644 --- a/Habitica/res/menu/menu_create_refresh.xml +++ b/Habitica/res/menu/menu_create_refresh.xml @@ -1,7 +1,6 @@ + xmlns:app="http://schemas.android.com/apk/res-auto"> diff --git a/Habitica/res/menu/menu_full_profile.xml b/Habitica/res/menu/menu_full_profile.xml index 4bbacf108..23d67e5b8 100644 --- a/Habitica/res/menu/menu_full_profile.xml +++ b/Habitica/res/menu/menu_full_profile.xml @@ -1,7 +1,5 @@ - + + xmlns:app="http://schemas.android.com/apk/res-auto"> diff --git a/Habitica/res/menu/menu_party_invite.xml b/Habitica/res/menu/menu_party_invite.xml index 4d22f99a6..07038ffc9 100644 --- a/Habitica/res/menu/menu_party_invite.xml +++ b/Habitica/res/menu/menu_party_invite.xml @@ -1,6 +1,5 @@ + xmlns:app="http://schemas.android.com/apk/res-auto"> diff --git a/Habitica/res/menu/menu_save.xml b/Habitica/res/menu/menu_save.xml index ac030c672..e31f8f36a 100644 --- a/Habitica/res/menu/menu_save.xml +++ b/Habitica/res/menu/menu_save.xml @@ -1,6 +1,5 @@ + xmlns:app="http://schemas.android.com/apk/res-auto"> diff --git a/Habitica/res/menu/menu_task_create.xml b/Habitica/res/menu/menu_task_create.xml index 1fc311170..84e3f9854 100644 --- a/Habitica/res/menu/menu_task_create.xml +++ b/Habitica/res/menu/menu_task_create.xml @@ -1,6 +1,5 @@ + xmlns:app="http://schemas.android.com/apk/res-auto"> diff --git a/Habitica/res/menu/menu_task_edit.xml b/Habitica/res/menu/menu_task_edit.xml index ef7782aed..e03a24446 100644 --- a/Habitica/res/menu/menu_task_edit.xml +++ b/Habitica/res/menu/menu_task_edit.xml @@ -1,6 +1,5 @@ + xmlns:app="http://schemas.android.com/apk/res-auto"> - + Абнавіць Вопыт Здароўе diff --git a/Habitica/res/values-de/strings.xml b/Habitica/res/values-de/strings.xml index 36e921f5f..586f519e7 100644 --- a/Habitica/res/values-de/strings.xml +++ b/Habitica/res/values-de/strings.xml @@ -947,7 +947,7 @@ Die Quest-Schriftrolle wird an den Quest-Besitzer zurückgegeben. Habitica nutzen Level %d Erinnerung löschen - Gold + Gold Level %1$d %2$s Ausgewählt Aus diff --git a/Habitica/res/values-el/strings.xml b/Habitica/res/values-el/strings.xml index 6a4823751..b49934215 100755 --- a/Habitica/res/values-el/strings.xml +++ b/Habitica/res/values-el/strings.xml @@ -1,5 +1,5 @@ - + Ανανέωση Εμπειρία Υγεία diff --git a/Habitica/res/values-en-rGB/strings.xml b/Habitica/res/values-en-rGB/strings.xml index 9938c1757..5d8b161a7 100644 --- a/Habitica/res/values-en-rGB/strings.xml +++ b/Habitica/res/values-en-rGB/strings.xml @@ -1004,7 +1004,7 @@ Level %d Delete Reminder %1$d/%2$d Responded - Gold + Gold Level %1$d %2$s Not selected Selected diff --git a/Habitica/res/values-es/strings.xml b/Habitica/res/values-es/strings.xml index 255955e50..c22a49265 100644 --- a/Habitica/res/values-es/strings.xml +++ b/Habitica/res/values-es/strings.xml @@ -713,7 +713,7 @@ Encuentra aun más objetos en Habitica con un bonus 2x de límite de botín diario. ¡Suscríbete ahora para obtener este %s y recibir objetos nuevos cada mes! Duplicar el botín - Oro + Oro Crear una cuenta %d conexiones Conéctate regularmente a Habitica diff --git a/Habitica/res/values-fi/strings.xml b/Habitica/res/values-fi/strings.xml index 44644f01f..d84f1a53b 100755 --- a/Habitica/res/values-fi/strings.xml +++ b/Habitica/res/values-fi/strings.xml @@ -1,5 +1,5 @@ - + Lataa uudelleen Kokemuspisteet Terveys diff --git a/Habitica/res/values-fr/strings.xml b/Habitica/res/values-fr/strings.xml index bafa774f7..75e076bf1 100644 --- a/Habitica/res/values-fr/strings.xml +++ b/Habitica/res/values-fr/strings.xml @@ -985,7 +985,7 @@ Niveau %d Supprimer le rappel %1$d/%2$d réponses - Or + Or Niveau %1$d %2$s Non sélectionné Sélectionné diff --git a/Habitica/res/values-hi/strings.xml b/Habitica/res/values-hi/strings.xml index 6d169f039..874a16bbf 100755 --- a/Habitica/res/values-hi/strings.xml +++ b/Habitica/res/values-hi/strings.xml @@ -1,5 +1,5 @@ - + ताज़ा करें अनुभव स्वास्थ्य diff --git a/Habitica/res/values-hu/strings.xml b/Habitica/res/values-hu/strings.xml index 8f93f2017..6907500b8 100755 --- a/Habitica/res/values-hu/strings.xml +++ b/Habitica/res/values-hu/strings.xml @@ -1,5 +1,5 @@ - + Frissítés Tapasztalat Életerő diff --git a/Habitica/res/values-it/strings.xml b/Habitica/res/values-it/strings.xml index 3cdd38845..586989db4 100644 --- a/Habitica/res/values-it/strings.xml +++ b/Habitica/res/values-it/strings.xml @@ -761,7 +761,7 @@ Scopri ancora più oggetti in Habitica con un bonus 2x sul limite di bottini giornalieri. Abbonati ora per ottenere %s e ricevere nuovi articoli ogni mese! Raddoppia il Bottino - Oro + Oro Crea un Account %d Accessi Accedi ad Habitica regolarmente diff --git a/Habitica/res/values-iw/strings.xml b/Habitica/res/values-iw/strings.xml index e304842fd..a8085362f 100644 --- a/Habitica/res/values-iw/strings.xml +++ b/Habitica/res/values-iw/strings.xml @@ -1,5 +1,5 @@ - + ריענון ניסיון בריאות diff --git a/Habitica/res/values-ja/strings.xml b/Habitica/res/values-ja/strings.xml index 653d76b9a..51b016043 100644 --- a/Habitica/res/values-ja/strings.xml +++ b/Habitica/res/values-ja/strings.xml @@ -752,7 +752,7 @@ オフ オン くり返しの間隔 - ゴールド + ゴールド レベル %1$d %2$s くり返し diff --git a/Habitica/res/values-ko/strings.xml b/Habitica/res/values-ko/strings.xml index 23425dc43..4dac33fbd 100644 --- a/Habitica/res/values-ko/strings.xml +++ b/Habitica/res/values-ko/strings.xml @@ -788,7 +788,7 @@ %d 달 남음 %d주 전 %d 개월 전 - 골드 + 골드 체크인 %d 회 해비티카에 정기적으로 접속하세요 해비티카에 %d 회 접속해서 잠금해제하세요. diff --git a/Habitica/res/values-lt/strings.xml b/Habitica/res/values-lt/strings.xml index a52b1b4f8..cfc1f3ec3 100644 --- a/Habitica/res/values-lt/strings.xml +++ b/Habitica/res/values-lt/strings.xml @@ -1,5 +1,5 @@ - + Atnaujinti Partirtis Gyvybingumas diff --git a/Habitica/res/values-nl/strings.xml b/Habitica/res/values-nl/strings.xml index 00df810a7..5875e2275 100644 --- a/Habitica/res/values-nl/strings.xml +++ b/Habitica/res/values-nl/strings.xml @@ -929,7 +929,7 @@ Niveau %d Verwijder Herinnering %1$d/%2$d Heeft Geantwoord - Goud + Goud Niveau %1$d %2$s Niet geselecteerd Geselecteerd diff --git a/Habitica/res/values-pl/strings.xml b/Habitica/res/values-pl/strings.xml index 2cf2b6500..3e8f03bba 100644 --- a/Habitica/res/values-pl/strings.xml +++ b/Habitica/res/values-pl/strings.xml @@ -670,7 +670,7 @@ %d tygodni temu Zaproś Znajomych Odwiedzaj Habitica regularnie - Złoto + Złoto stwórz konto %d Wizyt Podwój Łup diff --git a/Habitica/res/values-pt-rBR/strings.xml b/Habitica/res/values-pt-rBR/strings.xml index 2381f6c12..a5588bbc2 100644 --- a/Habitica/res/values-pt-rBR/strings.xml +++ b/Habitica/res/values-pt-rBR/strings.xml @@ -958,7 +958,7 @@ Nível %d Excluir lembrete %1$d/%2$d Respondeu - Ouro + Ouro Nível %1$d %2$s Não selecionado Selecionado diff --git a/Habitica/res/values-pt-rPT/strings.xml b/Habitica/res/values-pt-rPT/strings.xml index b7a511925..625fd2a1c 100644 --- a/Habitica/res/values-pt-rPT/strings.xml +++ b/Habitica/res/values-pt-rPT/strings.xml @@ -476,7 +476,7 @@ Itens Misteriosos Mensais Torne-se um subscrito para receber benefícios exclusivos! Subscrições ajudam os desenvolvedores e também a manter o Habitica a funcionar - Ouro + Ouro Criar uma conta %d Check-ins Entre em Habitica regularmente diff --git a/Habitica/res/values-ru/strings.xml b/Habitica/res/values-ru/strings.xml index 5ce4515be..7b591da4b 100644 --- a/Habitica/res/values-ru/strings.xml +++ b/Habitica/res/values-ru/strings.xml @@ -797,7 +797,7 @@ 1 месяц назад Введённые данные некорректны. Вы получили %d сообщений - Золото + Золото Уровень %1$d %2$s Исключен из группы Подробнее diff --git a/Habitica/res/values-sv/strings.xml b/Habitica/res/values-sv/strings.xml index 61125e69d..d316a338a 100755 --- a/Habitica/res/values-sv/strings.xml +++ b/Habitica/res/values-sv/strings.xml @@ -594,7 +594,7 @@ Mystiskt Timglas Månatlig Mystiska Föremål Guld för Juveler - Guld + Guld Nivå %1$d %2$s 1h kvar %dh kvar diff --git a/Habitica/res/values-th/strings.xml b/Habitica/res/values-th/strings.xml index beaf86d60..28192a856 100755 --- a/Habitica/res/values-th/strings.xml +++ b/Habitica/res/values-th/strings.xml @@ -1,5 +1,5 @@ - + ค่าประสบการณ์ พลังชีวิต diff --git a/Habitica/res/values-tr/strings.xml b/Habitica/res/values-tr/strings.xml index a4dc127c7..aba81917a 100644 --- a/Habitica/res/values-tr/strings.xml +++ b/Habitica/res/values-tr/strings.xml @@ -708,7 +708,7 @@ 2 kat eşya düşürme oranı ile daha çok Habitica eşyası keşfet. Şimdi abone olarak %s\'ı elde edebilir ve her ay yeni eşyalar kazanabilirsin! İki kat eşya düşürme - Altın + Altın hesap oluştur Habitica\'ya düzenli olarak giriş yap Arkadaşlarını davet et diff --git a/Habitica/res/values-uk/strings.xml b/Habitica/res/values-uk/strings.xml index cd0cd8a6b..6e5d71ce6 100755 --- a/Habitica/res/values-uk/strings.xml +++ b/Habitica/res/values-uk/strings.xml @@ -749,7 +749,7 @@ Ви впевнені\? Редагувати Повідомлення скопійовано до буфера обміну - Золото + Золото золото Придбано %1$s створити акаунт diff --git a/Habitica/res/values-vi/strings.xml b/Habitica/res/values-vi/strings.xml index 9ff3fb62c..a39f85c7a 100755 --- a/Habitica/res/values-vi/strings.xml +++ b/Habitica/res/values-vi/strings.xml @@ -935,7 +935,7 @@ Cấp độ %d Xóa Nhắc nhở %1$d/%2$d Phản hồi - Vàng + Vàng Cấp độ %1$d %2$s Không chọn Đã chọn diff --git a/Habitica/res/values-zh-rTW/strings.xml b/Habitica/res/values-zh-rTW/strings.xml index d1061fb9f..f7d93021d 100644 --- a/Habitica/res/values-zh-rTW/strings.xml +++ b/Habitica/res/values-zh-rTW/strings.xml @@ -1006,7 +1006,7 @@ %d級 刪除提醒 %1$d/%2$d已回應 - 金幣 + 金幣 %1$d級%2$s 未選中 已選擇 diff --git a/Habitica/res/values-zh/strings.xml b/Habitica/res/values-zh/strings.xml index fd3fe0f5f..47df58627 100644 --- a/Habitica/res/values-zh/strings.xml +++ b/Habitica/res/values-zh/strings.xml @@ -1004,7 +1004,7 @@ %d级 删除提醒 %1$d/%2$d已回应 - 金币 + 金币 未选中 已选择 diff --git a/Habitica/res/values/attrs.xml b/Habitica/res/values/attrs.xml index 5732df5c4..ad92dd442 100644 --- a/Habitica/res/values/attrs.xml +++ b/Habitica/res/values/attrs.xml @@ -82,12 +82,6 @@ - - - - - - diff --git a/Habitica/res/values/strings.xml b/Habitica/res/values/strings.xml index 1c13eb09f..e5eaba341 100644 --- a/Habitica/res/values/strings.xml +++ b/Habitica/res/values/strings.xml @@ -350,7 +350,7 @@ create an account Purchased %1$s gold - Gold + Gold Message copied to Clipboard Edit Are you sure? diff --git a/Habitica/res/values/styles.habitica.xml b/Habitica/res/values/styles.habitica.xml index fb10e8692..f248bd3b7 100644 --- a/Habitica/res/values/styles.habitica.xml +++ b/Habitica/res/values/styles.habitica.xml @@ -1,5 +1,5 @@ - + sans-serif-medium sans-serif diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/components/UserComponent.java b/Habitica/src/main/java/com/habitrpg/android/habitica/components/UserComponent.java index 4207c833b..f62177ff5 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/components/UserComponent.java +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/components/UserComponent.java @@ -52,6 +52,7 @@ import com.habitrpg.android.habitica.ui.fragments.inventory.customization.Avatar import com.habitrpg.android.habitica.ui.fragments.inventory.customization.AvatarOverviewFragment; import com.habitrpg.android.habitica.ui.fragments.inventory.equipment.EquipmentDetailFragment; import com.habitrpg.android.habitica.ui.fragments.inventory.equipment.EquipmentOverviewFragment; +import com.habitrpg.android.habitica.ui.fragments.inventory.items.ItemDialogFragment; import com.habitrpg.android.habitica.ui.fragments.inventory.items.ItemRecyclerFragment; import com.habitrpg.android.habitica.ui.fragments.inventory.items.ItemsFragment; import com.habitrpg.android.habitica.ui.fragments.inventory.shops.ShopFragment; @@ -343,4 +344,6 @@ public interface UserComponent { void inject(@NotNull GuildOverviewFragment guildOverviewFragment); void inject(@NotNull PromoWebFragment promoWebFragment); + + void inject(@NotNull ItemDialogFragment itemDialogFragment); } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/data/TaskRepository.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/data/TaskRepository.kt index 17f19b156..95cd6eadb 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/data/TaskRepository.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/data/TaskRepository.kt @@ -39,8 +39,6 @@ interface TaskRepository : BaseRepository { fun markTaskCompleted(taskId: String, isCompleted: Boolean) - fun saveReminder(remindersItem: RemindersItem) - fun modify(obj: T, transaction: (T) -> Unit) fun swapTaskPosition(firstPosition: Int, secondPosition: Int) diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/ApiClientImpl.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/ApiClientImpl.kt index fcd06b391..9486e9448 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/ApiClientImpl.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/ApiClientImpl.kt @@ -345,7 +345,7 @@ class ApiClientImpl//private OnHabitsAPIResult mResultListener; if (habitResponse.notifications != null) { notificationsManager.setNotifications(habitResponse.notifications) } - habitResponse.getData() + habitResponse.data } } @@ -354,7 +354,7 @@ class ApiClientImpl//private OnHabitsAPIResult mResultListener; if (habitResponse.notifications != null) { notificationsManager.setNotifications(habitResponse.notifications) } - habitResponse.getData() + habitResponse.data } } @@ -385,7 +385,7 @@ class ApiClientImpl//private OnHabitsAPIResult mResultListener; override fun feedPet(petKey: String, foodKey: String): Flowable { return apiService.feedPet(petKey, foodKey) .map { - it.data.message = it.message + it.data?.message = it.message it } .compose(configureApiCallObserver()) @@ -604,7 +604,7 @@ class ApiClientImpl//private OnHabitsAPIResult mResultListener; if (habitResponse.notifications != null) { notificationsManager.setNotifications(habitResponse.notifications) } - habitResponse.getData() + habitResponse.data } } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/InventoryRepositoryImpl.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/InventoryRepositoryImpl.kt index 439c1f678..0ff5dfe69 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/InventoryRepositoryImpl.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/InventoryRepositoryImpl.kt @@ -210,7 +210,7 @@ class InventoryRepositoryImpl(localRepository: InventoryLocalRepository, apiClie } return apiClient.hatchPet(egg.key, hatchingPotion.key) .doOnNext { - localRepository.save(it) + localRepository.save(it, userID) if (!appConfigManager.enableLocalChanges()) { successFunction() } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/TaskRepositoryImpl.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/TaskRepositoryImpl.kt index 6adabe0a0..2ebfa9a1b 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/TaskRepositoryImpl.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/TaskRepositoryImpl.kt @@ -167,7 +167,13 @@ class TaskRepositoryImpl(localRepository: TaskLocalRepository, apiClient: ApiCli item.userID = user.id } item.numberOwned += 1 - it.insertOrUpdate(item) + when (type) { + "eggs" -> bgUser.items?.eggs?.add(item) + "food" -> bgUser.items?.food?.add(item) + "hatchingPotions" -> bgUser.items?.hatchingPotions?.add(item) + "quests" -> bgUser.items?.quests?.add(item) + else -> "" + } } val stats = bgUser.stats @@ -274,10 +280,6 @@ class TaskRepositoryImpl(localRepository: TaskLocalRepository, apiClient: ApiCli localRepository.markTaskCompleted(taskId, isCompleted) } - override fun saveReminder(remindersItem: RemindersItem) { - localRepository.saveReminder(remindersItem) - } - override fun modify(obj: T, transaction: (T) -> Unit) { localRepository.modify(obj, transaction) } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/data/local/InventoryLocalRepository.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/data/local/InventoryLocalRepository.kt index 8ac6272fa..c9c0b43ab 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/data/local/InventoryLocalRepository.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/data/local/InventoryLocalRepository.kt @@ -2,10 +2,7 @@ package com.habitrpg.android.habitica.data.local import com.habitrpg.android.habitica.models.inventory.* import com.habitrpg.android.habitica.models.shops.ShopItem -import com.habitrpg.android.habitica.models.user.OwnedItem -import com.habitrpg.android.habitica.models.user.OwnedMount -import com.habitrpg.android.habitica.models.user.OwnedPet -import com.habitrpg.android.habitica.models.user.User +import com.habitrpg.android.habitica.models.user.* import io.reactivex.rxjava3.core.Flowable interface InventoryLocalRepository : ContentLocalRepository { @@ -50,11 +47,12 @@ interface InventoryLocalRepository : ContentLocalRepository { fun decrementMysteryItemCount(user: User?) fun saveInAppRewards(onlineItems: List) - fun changePetFeedStatus(key: String?, userID: String, feedStatus: Int) fun hatchPet(eggKey: String, potionKey: String, userID: String) fun unhatchPet(eggKey: String, potionKey: String, userID: String) fun feedPet(foodKey: String, petKey: String, feedValue: Int, userID: String) fun getLatestMysteryItem(): Flowable fun soldItem(userID: String, updatedUser: User): User fun getAvailableLimitedItems(): Flowable> + + fun save(items: Items, userID: String) } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/data/local/TaskLocalRepository.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/data/local/TaskLocalRepository.kt index 7f9ea3936..c44039f42 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/data/local/TaskLocalRepository.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/data/local/TaskLocalRepository.kt @@ -22,8 +22,6 @@ interface TaskLocalRepository : BaseLocalRepository { fun markTaskCompleted(taskId: String, isCompleted: Boolean) - fun saveReminder(remindersItem: RemindersItem) - fun swapTaskPosition(firstPosition: Int, secondPosition: Int) fun getTaskAtPosition(taskType: String, position: Int): Flowable diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/data/local/implementation/RealmBaseLocalRepository.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/data/local/implementation/RealmBaseLocalRepository.kt index e774a45db..b8dc3bd0a 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/data/local/implementation/RealmBaseLocalRepository.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/data/local/implementation/RealmBaseLocalRepository.kt @@ -4,6 +4,9 @@ import android.renderscript.BaseObj import com.habitrpg.android.habitica.data.local.BaseLocalRepository import com.habitrpg.android.habitica.models.BaseMainObject import com.habitrpg.android.habitica.models.BaseObject +import com.habitrpg.android.habitica.models.user.User +import hu.akarnokd.rxjava3.bridge.RxJavaBridge +import io.reactivex.rxjava3.core.Flowable import io.realm.Realm import io.realm.RealmObject @@ -91,4 +94,14 @@ abstract class RealmBaseLocalRepository internal constructor(override var realm: val baseObject = obj as? BaseMainObject ?: return null return realm.where(baseObject.realmClass).equalTo(baseObject.primaryIdentifierName, baseObject.primaryIdentifier).findFirst() as? T } + + + fun queryUser(userID: String): Flowable { + return RxJavaBridge.toV3Flowable(realm.where(User::class.java) + .equalTo("id", userID) + .findAll() + .asFlowable()) + .filter { it.isLoaded && it.isValid && !it.isEmpty() } + .map { it.first() } + } } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/data/local/implementation/RealmInventoryLocalRepository.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/data/local/implementation/RealmInventoryLocalRepository.kt index 2d5d12429..afca494f9 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/data/local/implementation/RealmInventoryLocalRepository.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/data/local/implementation/RealmInventoryLocalRepository.kt @@ -4,13 +4,11 @@ import com.habitrpg.android.habitica.data.local.InventoryLocalRepository import com.habitrpg.android.habitica.helpers.RxErrorHandler import com.habitrpg.android.habitica.models.inventory.* import com.habitrpg.android.habitica.models.shops.ShopItem -import com.habitrpg.android.habitica.models.user.OwnedItem -import com.habitrpg.android.habitica.models.user.OwnedMount -import com.habitrpg.android.habitica.models.user.OwnedPet -import com.habitrpg.android.habitica.models.user.User +import com.habitrpg.android.habitica.models.user.* import hu.akarnokd.rxjava3.bridge.RxJavaBridge import io.reactivex.rxjava3.core.Flowable import io.realm.Realm +import io.realm.RealmList import io.realm.RealmObject import io.realm.Sort import java.text.SimpleDateFormat @@ -81,16 +79,20 @@ class RealmInventoryLocalRepository(realm: Realm) : RealmContentLocalRepository( } override fun getOwnedItems(itemType: String, userID: String, includeZero: Boolean): Flowable> { - var query = realm.where(OwnedItem::class.java) - if (!includeZero) { - query = query.greaterThan("numberOwned", 0) + return queryUser(userID).map { + val items = when (itemType) { + "eggs" -> it.items?.eggs + "hatchingPotions" -> it.items?.hatchingPotions + "food" -> it.items?.food + "quests" -> it.items?.quests + else -> emptyList() + } ?: emptyList() + if (includeZero) { + items + } else { + items.filter { it.numberOwned > 0 } + } } - return RxJavaBridge.toV3Flowable(query.equalTo("itemType", itemType) - .equalTo("userID", userID) - .sort("key") - .findAll() - .asFlowable() - .filter { it.isLoaded }) } override fun getItems(itemClass: Class, keys: Array): Flowable> { @@ -104,20 +106,18 @@ class RealmInventoryLocalRepository(realm: Realm) : RealmContentLocalRepository( } override fun getOwnedItems(userID: String, includeZero: Boolean): Flowable> { - var query = realm.where(OwnedItem::class.java) - if (!includeZero) { - query = query.greaterThan("numberOwned", 0) + return queryUser(userID).map { + val items = HashMap() + it.items?.eggs?.forEach { items[it.key + "-" + it.itemType] = it } + it.items?.food?.forEach { items[it.key + "-" + it.itemType] = it } + it.items?.hatchingPotions?.forEach { items[it.key + "-" + it.itemType] = it } + it.items?.quests?.forEach { items[it.key + "-" + it.itemType] = it } + if (includeZero) { + items + } else { + items.filter { it.value.numberOwned > 0 } + } } - return RxJavaBridge.toV3Flowable(query.equalTo("userID", userID) - .findAll() - .asFlowable() - .map { - val items = HashMap() - for (item in it) { - items[item.key + "-" + item.itemType] = item - } - items - }) } override fun getEquipment(key: String): Flowable { @@ -155,14 +155,13 @@ class RealmInventoryLocalRepository(realm: Realm) : RealmContentLocalRepository( } override fun getOwnedMounts(userID: String): Flowable> { - return RxJavaBridge.toV3Flowable(realm.where(OwnedMount::class.java) - .equalTo("owned", true) - .equalTo("userID", userID) - .findAll() - .asFlowable() - .filter { it.isLoaded }) + return queryUser(userID) + .map { it.items?.mounts?.filter { + it.owned == true + } ?: emptyList() } } + override fun getPets(): Flowable> { return RxJavaBridge.toV3Flowable(realm.where(Pet::class.java) .sort("type", Sort.ASCENDING, "animal", Sort.ASCENDING) @@ -189,12 +188,14 @@ class RealmInventoryLocalRepository(realm: Realm) : RealmContentLocalRepository( } override fun getOwnedPets(userID: String): Flowable> { - return RxJavaBridge.toV3Flowable(realm.where(OwnedPet::class.java) - .greaterThan("trained", 0) - .equalTo("userID", userID) + return RxJavaBridge.toV3Flowable(realm.where(User::class.java) + .equalTo("id", userID) .findAll() - .asFlowable() - .filter { it.isLoaded }) + .asFlowable()) + .filter { it.isLoaded && it.isValid && !it.isEmpty() } + .map { it.first()?.items?.pets?.filter { + it.trained > 0 + } ?: emptyList() } } override fun updateOwnedEquipment(user: User) { @@ -213,16 +214,23 @@ class RealmInventoryLocalRepository(realm: Realm) : RealmContentLocalRepository( } override fun getOwnedItem(userID: String, type: String, key: String, includeZero: Boolean): Flowable { - var query = realm.where(OwnedItem::class.java) - .equalTo("itemType", type) - .equalTo("key", key) - .equalTo("userID", userID) - if (!includeZero) { - query = query.greaterThan("numberOwned", 0) + return queryUser(userID).map { + var items = (when (type) { + "eggs" -> it.items?.eggs + "hatchingPotions" -> it.items?.hatchingPotions + "food" -> it.items?.food + "quests" -> it.items?.quests + else -> emptyList() + } ?: emptyList()) + items = items.filter { it.key == key } + if (includeZero) { + items + } else { + items.filter { it.numberOwned > 0 } + } } - return RxJavaBridge.toV3Flowable(query.findFirstAsync() - .asFlowable() - .filter { realmObject -> realmObject.isLoaded }) + .filter { it.isNotEmpty() } + .map { it.first() } } override fun getItem(type: String, key: String): Flowable { @@ -277,49 +285,41 @@ class RealmInventoryLocalRepository(realm: Realm) : RealmContentLocalRepository( override fun hatchPet(eggKey: String, potionKey: String, userID: String) { val newPet = OwnedPet() newPet.key = "$eggKey-$potionKey" - newPet.userID = userID newPet.trained = 5 - val egg = realm.where(OwnedItem::class.java) - .equalTo("itemType", "eggs") - .equalTo("key", eggKey) - .equalTo("userID", userID) - .greaterThan("numberOwned", 0) - .findFirst() ?: return - val hatchingPotion = realm.where(OwnedItem::class.java) - .equalTo("itemType", "hatchingPotions") - .equalTo("key", potionKey) - .equalTo("userID", userID) - .greaterThan("numberOwned", 0) - .findFirst() ?: return + val user = realm.where(User::class.java).equalTo("id", userID).findFirst() ?: return + val egg = user.items?.eggs?.firstOrNull { it.key == eggKey } ?: return + val hatchingPotion = user.items?.hatchingPotions?.firstOrNull { it.key == potionKey } ?: return executeTransaction { egg.numberOwned -= 1 hatchingPotion.numberOwned -= 1 - it.insertOrUpdate(newPet) + user.items?.pets?.add(newPet) + } + } + + override fun save(items: Items, userID: String) { + val user = realm.where(User::class.java).equalTo("id", userID).findFirst() ?: return + items.setItemTypes() + executeTransaction { + user.items = items } } override fun unhatchPet(eggKey: String, potionKey: String, userID: String) { val pet = realm.where(OwnedPet::class.java).equalTo("key", "$eggKey-$potionKey").findFirst() - val egg = realm.where(OwnedItem::class.java) - .equalTo("itemType", "eggs") - .equalTo("key", eggKey) - .equalTo("userID", userID) - .findFirst() ?: return - val hatchingPotion = realm.where(OwnedItem::class.java) - .equalTo("itemType", "hatchingPotions") - .equalTo("key", potionKey) - .equalTo("userID", userID) - .findFirst() ?: return + val user = realm.where(User::class.java).equalTo("id", userID).findFirst() ?: return + val egg = user.items?.eggs?.firstOrNull { it.key == eggKey } ?: return + val hatchingPotion = user.items?.hatchingPotions?.firstOrNull { it.key == potionKey } ?: return executeTransaction { egg.numberOwned += 1 hatchingPotion.numberOwned += 1 - pet?.deleteFromRealm() + user.items?.pets?.remove(pet) } } override fun feedPet(foodKey: String, petKey: String, feedValue: Int, userID: String) { - val pet = realm.where(OwnedPet::class.java).equalTo("key", petKey).findFirst() ?: return - val food = realm.where(OwnedItem::class.java).equalTo("key", foodKey).equalTo("itemType", "food").findFirst() ?: return + val user = realm.where(User::class.java).equalTo("id", userID).findFirst() ?: return + val pet = user.items?.pets?.firstOrNull { it.key == petKey } ?: return + val food = user.items?.food?.firstOrNull { it.key == foodKey } ?: return executeTransaction { pet.trained = feedValue food.numberOwned -= 1 @@ -327,23 +327,12 @@ class RealmInventoryLocalRepository(realm: Realm) : RealmContentLocalRepository( if (feedValue < 0) { val mount = OwnedMount() mount.key = petKey - mount.userID = userID mount.owned = true - it.insertOrUpdate(mount) + user.items?.mounts?.add(mount) } } } - override fun changePetFeedStatus(key: String?, userID: String, feedStatus: Int) { - val newPet = OwnedPet() - newPet.key = key - newPet.userID = userID - newPet.trained = feedStatus - executeTransaction { - it.insertOrUpdate(newPet) - } - } - override fun getLatestMysteryItem(): Flowable { return RxJavaBridge.toV3Flowable(realm.where(Equipment::class.java) .contains("key", "mystery_2") diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/data/local/implementation/RealmTaskLocalRepository.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/data/local/implementation/RealmTaskLocalRepository.kt index 31e1d99fa..b65ab2c9a 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/data/local/implementation/RealmTaskLocalRepository.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/data/local/implementation/RealmTaskLocalRepository.kt @@ -153,10 +153,6 @@ class RealmTaskLocalRepository(realm: Realm) : RealmBaseLocalRepository(realm), executeTransaction { task.completed = true } } - override fun saveReminder(remindersItem: RemindersItem) { - executeTransaction { it.insertOrUpdate(remindersItem) } - } - override fun swapTaskPosition(firstPosition: Int, secondPosition: Int) { val firstTask = realm.where(Task::class.java).equalTo("position", firstPosition).findFirst() val secondTask = realm.where(Task::class.java).equalTo("position", secondPosition).findFirst() diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/data/local/implementation/RealmTutorialLocalRepository.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/data/local/implementation/RealmTutorialLocalRepository.kt index 355c656d8..77df61fd6 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/data/local/implementation/RealmTutorialLocalRepository.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/data/local/implementation/RealmTutorialLocalRepository.kt @@ -26,8 +26,7 @@ class RealmTutorialLocalRepository(realm: Realm) : RealmBaseLocalRepository(real steps } } - .map { steps -> steps.first() } - .cast(TutorialStep::class.java)) + .map { steps -> steps.first() }) } override fun getTutorialSteps(keys: List): Flowable> { diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/data/local/implementation/RealmUserLocalRepository.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/data/local/implementation/RealmUserLocalRepository.kt index a3c82f5f6..205bb7f0f 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/data/local/implementation/RealmUserLocalRepository.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/data/local/implementation/RealmUserLocalRepository.kt @@ -43,11 +43,12 @@ class RealmUserLocalRepository(realm: Realm) : RealmBaseLocalRepository(realm), } override fun getQuestAchievements(userID: String): Flowable> { - return RxJavaBridge.toV3Flowable(realm.where(QuestAchievement::class.java) - .equalTo("userID", userID) + return RxJavaBridge.toV3Flowable(realm.where(User::class.java) + .equalTo("id", userID) .findAll() .asFlowable() - .filter { it.isLoaded }) + .filter { it.isLoaded } + .map { it.first()?.questAchievements ?: emptyList() }) } override fun getTutorialSteps(): Flowable> = RxJavaBridge.toV3Flowable(realm.where(TutorialStep::class.java).findAll().asFlowable() @@ -80,12 +81,7 @@ class RealmUserLocalRepository(realm: Realm) : RealmBaseLocalRepository(realm), } } executeTransaction { realm1 -> realm1.insertOrUpdate(user) } - removeOldTags(user.id ?: "", user.tags) - if (user.challenges != null) { - removeOldChallenges(user.id ?: "", user.challenges ?: emptyList()) - } - removeOldPets(user.id ?: "", user.items?.pets ?: emptyList()) - removeOldMounts(user.id ?: "", user.items?.mounts ?: emptyList()) + } override fun saveMessages(messages: List) { @@ -94,46 +90,6 @@ class RealmUserLocalRepository(realm: Realm) : RealmBaseLocalRepository(realm), } } - private fun removeOldTags(userId: String, onlineTags: List) { - val tags = realm.where(Tag::class.java).equalTo("userId", userId).findAll().createSnapshot() - val tagsToDelete = tags.filterNot { onlineTags.contains(it) } - executeTransaction { - for (tag in tagsToDelete) { - tag.deleteFromRealm() - } - } - } - - private fun removeOldChallenges(userID: String, onlineChallenges: List) { - val memberships = realm.where(ChallengeMembership::class.java).equalTo("userID", userID).findAll().createSnapshot() - val membershipsToDelete = memberships.filterNot { onlineChallenges.contains(it) } - executeTransaction { - membershipsToDelete.forEach { - it.deleteFromRealm() - } - } - } - - private fun removeOldPets(userID: String, onlinePets: List) { - val pets = realm.where(OwnedPet::class.java).equalTo("userID", userID).findAll().createSnapshot() - val petsToDelete = pets.filterNot { onlinePets.contains(it) } - executeTransaction { - petsToDelete.forEach { - it.deleteFromRealm() - } - } - } - - private fun removeOldMounts(userID: String, onlineMounts: List) { - val mount = realm.where(OwnedMount::class.java).equalTo("userID", userID).findAll().createSnapshot() - val mountsToDelete = mount.filterNot { onlineMounts.contains(it) } - executeTransaction { - mountsToDelete.forEach { - it.deleteFromRealm() - } - } - } - override fun getTeamPlans(userID: String): Flowable> { return RxJavaBridge.toV3Flowable(realm.where(TeamPlan::class.java) .equalTo("userID", userID) diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/PurchaseHandler.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/PurchaseHandler.kt index d9689f131..074cf09ca 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/PurchaseHandler.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/PurchaseHandler.kt @@ -172,7 +172,8 @@ class PurchaseHandler(activity: Activity, val analyticsManager: AnalyticsManager fun purchaseGems(identifier: String) { checkout?.let { it.destroyPurchaseFlow() - billingRequests?.purchase(ProductTypes.IN_APP, identifier, null, it.createOneShotPurchaseFlow(object : RequestListener { + billingRequests?.purchase(ProductTypes.IN_APP, identifier, null, it.createOneShotPurchaseFlow( + PURCHASE_REQUEST_CODE, object : RequestListener { override fun onSuccess(result: Purchase) { billingRequests?.consume(result.token, object : RequestListener { override fun onSuccess(o: Any) { /* no-op */ } @@ -195,7 +196,8 @@ class PurchaseHandler(activity: Activity, val analyticsManager: AnalyticsManager fun purchaseNoRenewSubscription(sku: Sku) { checkout?.let { - billingRequests?.purchase(ProductTypes.IN_APP, sku.id.code, null, it.createOneShotPurchaseFlow(object : RequestListener { + billingRequests?.purchase(ProductTypes.IN_APP, sku.id.code, null, it.createOneShotPurchaseFlow( + PURCHASE_REQUEST_CODE, object : RequestListener { override fun onSuccess(result: Purchase) { billingRequests?.consume(result.token, object : RequestListener { override fun onSuccess(o: Any) { /* no-op */ } @@ -229,6 +231,8 @@ class PurchaseHandler(activity: Activity, val analyticsManager: AnalyticsManager private var handlers = WeakHashMap() + val PURCHASE_REQUEST_CODE = 51966 + fun findForActivity(activity: Activity): PurchaseHandler? { return handlers[activity] } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/TaskAlarmManager.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/TaskAlarmManager.kt index b7d3f407d..6ddf8d20b 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/TaskAlarmManager.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/TaskAlarmManager.kt @@ -102,8 +102,6 @@ class TaskAlarmManager(private var context: Context, private var taskRepository: val sender = PendingIntent.getBroadcast(context, intentId, intent, PendingIntent.FLAG_CANCEL_CURRENT) setAlarm(context, cal.timeInMillis, sender) - - taskRepository.saveReminder(remindersItem) } private fun removeAlarmForRemindersItem(remindersItem: RemindersItem) { diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/interactors/CheckClassSelectionUseCase.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/interactors/CheckClassSelectionUseCase.kt index d16fafef3..1449c8bfd 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/interactors/CheckClassSelectionUseCase.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/interactors/CheckClassSelectionUseCase.kt @@ -12,8 +12,6 @@ import javax.inject.Inject import io.reactivex.rxjava3.core.Flowable -import com.habitrpg.android.habitica.ui.activities.MainActivity.Companion.SELECT_CLASS_RESULT - class CheckClassSelectionUseCase @Inject constructor(postExecutionThread: PostExecutionThread) : UseCase(postExecutionThread) { override fun buildUseCaseObservable(requestValues: RequestValues): Flowable { @@ -41,7 +39,7 @@ class CheckClassSelectionUseCase @Inject constructor(postExecutionThread: PostEx val intent = Intent(activity, ClassSelectionActivity::class.java) intent.putExtras(bundle) - activity.startActivityForResult(intent, SELECT_CLASS_RESULT) + activity.startActivity(intent) } class RequestValues(val user: User?, val isInitialSelection: Boolean, val currentClass: String?, val activity: Activity) : UseCase.RequestValues diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/models/responses/ErrorResponse.java b/Habitica/src/main/java/com/habitrpg/android/habitica/models/responses/ErrorResponse.java deleted file mode 100644 index b4f3fa18d..000000000 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/models/responses/ErrorResponse.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.habitrpg.android.habitica.models.responses; - -import java.util.List; - -public class ErrorResponse { - public String message; - public List errors; - - public String getDisplayMessage() { - if (errors != null && errors.size() > 0) { - HabiticaError error = errors.get(0); - if (error.message != null && error.message.length() > 0) { - return error.message; - } - } - if (message != null && message.length() > 0) { - return message; - } - return ""; - } -} diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/models/responses/ErrorResponse.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/models/responses/ErrorResponse.kt new file mode 100644 index 000000000..5a6cb231c --- /dev/null +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/models/responses/ErrorResponse.kt @@ -0,0 +1,16 @@ +package com.habitrpg.android.habitica.models.responses + +class ErrorResponse { + var message: String? = null + var errors: List? = null + val displayMessage: String + get() { + if (errors?.isNotEmpty() == true) { + val error = errors?.get(0) + if (error?.message?.isNotBlank() == true) { + return error.message ?: "" + } + } + return message ?: "" + } +} \ No newline at end of file diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/models/responses/HabitResponse.java b/Habitica/src/main/java/com/habitrpg/android/habitica/models/responses/HabitResponse.java deleted file mode 100644 index 993f9d91e..000000000 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/models/responses/HabitResponse.java +++ /dev/null @@ -1,39 +0,0 @@ -package com.habitrpg.android.habitica.models.responses; - -import com.habitrpg.android.habitica.models.Notification; - -import java.util.List; - -/** - * Created by krh12 on 11/23/2016. - */ - -public class HabitResponse { - - public T data; - public List notifications; - private Boolean success; - public String message; - - /** - * @return The success - */ - public Boolean getSuccess() { - return success; - } - - /** - * @param success The success - */ - public void setSuccess(Boolean success) { - this.success = success; - } - - /** - * @return The data - */ - public T getData() { - return data; - } -} - diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/models/responses/HabitResponse.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/models/responses/HabitResponse.kt new file mode 100644 index 000000000..f7fb19192 --- /dev/null +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/models/responses/HabitResponse.kt @@ -0,0 +1,10 @@ +package com.habitrpg.android.habitica.models.responses + +import com.habitrpg.android.habitica.models.Notification + +class HabitResponse { + var data: T? = null + var notifications: List = emptyList() + var success: Boolean? = null + var message: String? = null +} \ No newline at end of file diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/models/responses/HabiticaError.java b/Habitica/src/main/java/com/habitrpg/android/habitica/models/responses/HabiticaError.java deleted file mode 100644 index 7dade7f87..000000000 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/models/responses/HabiticaError.java +++ /dev/null @@ -1,7 +0,0 @@ -package com.habitrpg.android.habitica.models.responses; - -public class HabiticaError { - public String message; - public String param; - public String value; -} diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/models/responses/HabiticaError.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/models/responses/HabiticaError.kt new file mode 100644 index 000000000..f22637273 --- /dev/null +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/models/responses/HabiticaError.kt @@ -0,0 +1,7 @@ +package com.habitrpg.android.habitica.models.responses + +class HabiticaError { + var message: String? = null + var param: String? = null + var value: String? = null +} \ No newline at end of file diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/models/user/Items.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/models/user/Items.kt index 5a4ff62b6..d35b4be8d 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/models/user/Items.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/models/user/Items.kt @@ -9,6 +9,13 @@ import java.util.* @RealmClass(embedded = true) open class Items : RealmObject, BaseObject { + fun setItemTypes() { + hatchingPotions?.forEach { it.itemType = "hatchingPotions" } + eggs?.forEach { it.itemType = "eggs" } + food?.forEach { it.itemType = "food" } + quests?.forEach { it.itemType = "quests" } + } + var eggs: RealmList? = null set(value) { field = value 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 5076d00a9..7dd8daa58 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 @@ -1,6 +1,7 @@ package com.habitrpg.android.habitica.ui.activities import android.content.Context +import android.content.Intent import android.content.SharedPreferences import android.content.res.Configuration import android.content.res.Resources @@ -32,7 +33,6 @@ import java.util.* abstract class BaseActivity : AppCompatActivity() { - private var currentTheme: String? = null private var isNightMode: Boolean = false internal var forcedTheme: String? = null diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/ChallengeFormActivity.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/ChallengeFormActivity.kt index a3927feaf..8e44ead97 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/ChallengeFormActivity.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/ChallengeFormActivity.kt @@ -10,6 +10,7 @@ import android.widget.AdapterView import android.widget.ArrayAdapter import android.widget.EditText import android.widget.TextView +import androidx.activity.result.contract.ActivityResultContracts import androidx.appcompat.widget.AppCompatCheckedTextView import androidx.appcompat.widget.Toolbar import com.habitrpg.android.habitica.R @@ -166,19 +167,6 @@ class ChallengeFormActivity : BaseActivity() { return super.onOptionsItemSelected(item) } - override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { - super.onActivityResult(requestCode, resultCode, data) - - if (requestCode == 1000) { - if (resultCode == Activity.RESULT_OK) { - val task = data?.getParcelableExtra(TaskFormActivity.PARCELABLE_TASK) - if (task != null) { - addOrUpdateTaskInList(task) - } - } - } - } - private fun validateAllFields(): Boolean { val errorMessages = ArrayList() @@ -230,7 +218,10 @@ class ChallengeFormActivity : BaseActivity() { val intent = intent val bundle = intent.extras - challengeTasks = ChallengeTasksRecyclerViewAdapter(null, 0, this, "", false, true) + ChallengeTasksRecyclerViewAdapter(null, 0, this, "", + openTaskDisabled = false, + taskActionsDisabled = true + ).also { challengeTasks = it } compositeSubscription.add(challengeTasks.taskOpenEvents.subscribe { if (it.isValid) { openNewTaskActivity(it.type, it) @@ -379,10 +370,10 @@ class ChallengeFormActivity : BaseActivity() { false } - addHabit = createTask(ChallengeTasksRecyclerViewAdapter.TASK_TYPE_ADD_ITEM, resources.getString(R.string.add_habit)) - addDaily = createTask(ChallengeTasksRecyclerViewAdapter.TASK_TYPE_ADD_ITEM, resources.getString(R.string.add_daily)) - addTodo = createTask(ChallengeTasksRecyclerViewAdapter.TASK_TYPE_ADD_ITEM, resources.getString(R.string.add_todo)) - addReward = createTask(ChallengeTasksRecyclerViewAdapter.TASK_TYPE_ADD_ITEM, resources.getString(R.string.add_reward)) + addHabit = createTask(resources.getString(R.string.add_habit)) + addDaily = createTask(resources.getString(R.string.add_daily)) + addTodo = createTask(resources.getString(R.string.add_todo)) + addReward = createTask(resources.getString(R.string.add_reward)) val taskList = ArrayList() @@ -455,7 +446,16 @@ class ChallengeFormActivity : BaseActivity() { val intent = Intent(this, TaskFormActivity::class.java) intent.putExtras(bundle) - startActivityForResult(intent, 1000) + newTaskResult.launch(intent) + } + + private val newTaskResult = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { + if (it.resultCode == Activity.RESULT_OK) { + val task = it.data?.getParcelableExtra(TaskFormActivity.PARCELABLE_TASK) + if (task != null) { + addOrUpdateTaskInList(task) + } + } } private fun createChallenge(): Flowable { @@ -534,18 +534,13 @@ class ChallengeFormActivity : BaseActivity() { companion object { const val CHALLENGE_ID_KEY = "challengeId" - private fun createTask(taskType: String, taskName: String): Task { + private fun createTask(taskName: String): Task { val t = Task() t.id = UUID.randomUUID().toString() - t.type = taskType + t.type = ChallengeTasksRecyclerViewAdapter.TASK_TYPE_ADD_ITEM t.text = taskName - if (taskType == Task.TYPE_HABIT) { - t.up = true - t.down = false - } - return t } } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/ClassSelectionActivity.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/ClassSelectionActivity.kt index 63dfc037c..d19d82ef4 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/ClassSelectionActivity.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/ClassSelectionActivity.kt @@ -266,7 +266,6 @@ class ClassSelectionActivity : BaseActivity(), Consumer { override fun accept(user: User) { if (shouldFinish == true) { progressDialog?.dismiss() - setResult(MainActivity.SELECT_CLASS_RESULT) finish() } } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/GiftSubscriptionActivity.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/GiftSubscriptionActivity.kt index 1c3f3f57f..b7876d5e0 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/GiftSubscriptionActivity.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/GiftSubscriptionActivity.kt @@ -1,5 +1,6 @@ package com.habitrpg.android.habitica.ui.activities +import android.annotation.SuppressLint import android.content.Intent import android.os.Bundle import android.view.MenuItem @@ -57,6 +58,7 @@ class GiftSubscriptionActivity : BaseActivity() { return binding.root } + @SuppressLint("SetTextI18n") override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/LoginActivity.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/LoginActivity.kt index 1c33f8101..2097fdc95 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/LoginActivity.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/LoginActivity.kt @@ -19,6 +19,7 @@ import android.view.WindowManager import android.view.inputmethod.EditorInfo import android.widget.EditText import android.widget.LinearLayout +import androidx.activity.result.contract.ActivityResultContracts import androidx.core.content.ContextCompat import androidx.core.content.edit import androidx.preference.PreferenceManager @@ -285,20 +286,6 @@ class LoginActivity : BaseActivity(), Consumer { super.onActivityResult(requestCode, resultCode, data) callbackManager.onActivityResult(requestCode, resultCode, data) - if (requestCode == REQUEST_CODE_PICK_ACCOUNT) { - if (resultCode == Activity.RESULT_OK) { - googleEmail = data?.getStringExtra(AccountManager.KEY_ACCOUNT_NAME) - handleGoogleLoginResult() - } - } - if (requestCode == REQUEST_CODE_RECOVER_FROM_PLAY_SERVICES_ERROR) { - // RESULT_CANCELED occurs when user denies requested permissions. In this case we don't - // want to immediately ask them to accept permissions again. See Issue #1290 on github. - if (resultCode != Activity.RESULT_CANCELED) { - handleGoogleLoginResult() - } - } - if (requestCode == FacebookSdk.getCallbackRequestCodeOffset()) { //This is necessary because the regular login callback is not called for some reason val accessToken = AccessToken.getCurrentAccessToken() @@ -372,7 +359,7 @@ class LoginActivity : BaseActivity(), Consumer { FirebaseAnalytics.getInstance(this).logEvent("user_registered", null) } - compositeSubscription.add(userRepository.retrieveUser(true, true) + compositeSubscription.add(userRepository.retrieveUser(withTasks = true, forced = true) .subscribe({ if (userAuthResponse.newUser) { this.startSetupActivity() @@ -395,7 +382,7 @@ class LoginActivity : BaseActivity(), Consumer { val intent = AccountManager.newChooseAccountIntent(null, null, accountTypes, true, null, null, null, null) try { - startActivityForResult(intent, REQUEST_CODE_PICK_ACCOUNT) + pickAccountResult.launch(intent) } catch (e: ActivityNotFoundException) { val alert = HabiticaAlertDialog(this) alert.setTitle(R.string.authentication_error_title) @@ -403,7 +390,13 @@ class LoginActivity : BaseActivity(), Consumer { alert.addCloseButton() alert.show() } + } + private val pickAccountResult = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { + if (it.resultCode == Activity.RESULT_OK) { + googleEmail = it?.data?.getStringExtra(AccountManager.KEY_ACCOUNT_NAME) + handleGoogleLoginResult() + } } private fun handleGoogleLoginResult() { @@ -455,7 +448,13 @@ class LoginActivity : BaseActivity(), Consumer { // the app access to the account, but the user can fix this. // Forward the user to an activity in Google Play services. val intent = e.intent - startActivityForResult(intent, REQUEST_CODE_RECOVER_FROM_PLAY_SERVICES_ERROR) + recoverFromPlayServicesErrorResult.launch(intent) + } + } + + private val recoverFromPlayServicesErrorResult = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { + if (it.resultCode != Activity.RESULT_CANCELED) { + handleGoogleLoginResult() } } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/MainActivity.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/MainActivity.kt index 4c9d8dd88..c2d2b6d33 100755 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/MainActivity.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/MainActivity.kt @@ -128,7 +128,7 @@ open class MainActivity : BaseActivity(), TutorialView.OnTutorialReaction { private var avatarInHeader: AvatarWithBarsViewModel? = null - private var notificationsViewModel: NotificationsViewModel? = null + var notificationsViewModel: NotificationsViewModel? = null private var faintDialog: HabiticaAlertDialog? = null private var sideAvatarView: AvatarView? = null private var activeTutorialView: TutorialView? = null @@ -402,11 +402,6 @@ open class MainActivity : BaseActivity(), TutorialView.OnTutorialReaction { super.startActivity(intent) } - override fun startActivityForResult(intent: Intent?, requestCode: Int) { - resumeFromActivity = true - super.startActivityForResult(intent, requestCode) - } - override fun startActivity(intent: Intent?, options: Bundle?) { resumeFromActivity = true super.startActivity(intent, options) @@ -496,31 +491,7 @@ open class MainActivity : BaseActivity(), TutorialView.OnTutorialReaction { } public override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { - if (resultCode == SELECT_CLASS_RESULT) { - retrieveUser() - } else if (requestCode == GEM_PURCHASE_REQUEST) { - retrieveUser() - } super.onActivityResult(requestCode, resultCode, data) - - if (resultCode == NOTIFICATION_CLICK && data?.hasExtra("notificationId") == true) { - notificationsViewModel?.click( - data.getStringExtra("notificationId") ?: "", - MainNavigationController - ) - } - - if (resultCode == NOTIFICATION_ACCEPT && data?.hasExtra("notificationId") == true) { - notificationsViewModel?.accept( - data.getStringExtra("notificationId") ?: "" - ) - } - - if (resultCode == NOTIFICATION_REJECT && data?.hasExtra("notificationId") == true) { - notificationsViewModel?.reject( - data.getStringExtra("notificationId") ?: "" - ) - } PurchaseHandler.findForActivity(this)?.onResult(requestCode, resultCode, data) } @@ -904,7 +875,7 @@ open class MainActivity : BaseActivity(), TutorialView.OnTutorialReaction { dialog.addButton(R.string.share, false) { hatchingDialog, _ -> val event1 = ShareEvent() event1.sharedMessage = getString(R.string.share_hatched, potionName, eggName) - event1.identifier = "hatchedPet"; + event1.identifier = "hatchedPet" val petImageSideLength = 140 val sharedImage = Bitmap.createBitmap(petImageSideLength, petImageSideLength, Bitmap.Config.ARGB_8888) val canvas = Canvas(sharedImage) @@ -919,16 +890,9 @@ open class MainActivity : BaseActivity(), TutorialView.OnTutorialReaction { }.subscribe({ }, RxErrorHandler.handleEmptyError())) } + @Suppress("UNUSED_PARAMETER") @Subscribe fun onConsumablePurchased(event: ConsumablePurchasedEvent) { compositeSubscription.add(userRepository.retrieveUser(withTasks = false, forced = true).subscribe({}, RxErrorHandler.handleEmptyError())) } - - companion object { - const val SELECT_CLASS_RESULT = 11 - const val GEM_PURCHASE_REQUEST = 111 - const val NOTIFICATION_CLICK = 222 - const val NOTIFICATION_ACCEPT = 223 - const val NOTIFICATION_REJECT = 224 - } } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/NotificationsActivity.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/NotificationsActivity.kt index 1162cccef..b78a29e6b 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/NotificationsActivity.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/NotificationsActivity.kt @@ -1,9 +1,9 @@ package com.habitrpg.android.habitica.ui.activities +import android.app.Activity import android.content.Context import android.content.Intent import android.os.Bundle -import android.text.Html import android.view.LayoutInflater import android.view.View import android.widget.* @@ -19,7 +19,6 @@ import com.habitrpg.android.habitica.helpers.RxErrorHandler import com.habitrpg.android.habitica.models.Notification import com.habitrpg.android.habitica.models.inventory.QuestContent import com.habitrpg.android.habitica.models.notifications.* -import com.habitrpg.android.habitica.ui.activities.MainActivity.Companion.NOTIFICATION_CLICK import com.habitrpg.android.habitica.ui.viewmodels.NotificationsViewModel import javax.inject.Inject @@ -244,7 +243,7 @@ class NotificationsActivity : BaseActivity(), androidx.swiperefreshlayout.widget container?.setOnClickListener { val resultIntent = Intent() resultIntent.putExtra("notificationId", notification.id) - setResult(NOTIFICATION_CLICK, resultIntent) + setResult(Activity.RESULT_OK, resultIntent) finish() } @@ -345,7 +344,7 @@ class NotificationsActivity : BaseActivity(), androidx.swiperefreshlayout.widget container?.setOnClickListener { val resultIntent = Intent() resultIntent.putExtra("notificationId", notification.id) - setResult(NOTIFICATION_CLICK, resultIntent) + setResult(Activity.RESULT_OK, resultIntent) finish() } } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/inventory/ItemRecyclerAdapter.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/inventory/ItemRecyclerAdapter.kt index 03a20c2c7..7e440cbcf 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/inventory/ItemRecyclerAdapter.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/inventory/ItemRecyclerAdapter.kt @@ -4,6 +4,7 @@ import android.content.Context import android.content.res.Resources import android.view.View import android.view.ViewGroup +import androidx.fragment.app.DialogFragment import androidx.recyclerview.widget.RecyclerView import com.habitrpg.android.habitica.R import com.habitrpg.android.habitica.databinding.ItemItemBinding @@ -31,7 +32,7 @@ class ItemRecyclerAdapter(val context: Context) : BaseRecyclerViewAdapter? = null private var ownedPets: Map? = null var items: Map? = null diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/tasks/RewardsRecyclerViewAdapter.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/tasks/RewardsRecyclerViewAdapter.kt index 0b344096a..71a08584b 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/tasks/RewardsRecyclerViewAdapter.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/tasks/RewardsRecyclerViewAdapter.kt @@ -35,7 +35,7 @@ class RewardsRecyclerViewAdapter(private var customRewards: List?, private override val checklistItemScoreEvents: Flowable> = checklistItemScoreSubject.toFlowable(BackpressureStrategy.DROP) private var taskOpenEventsSubject: PublishSubject = PublishSubject.create() override val taskOpenEvents: Flowable = taskOpenEventsSubject.toFlowable(BackpressureStrategy.LATEST) - protected var brokenTaskEventsSubject: PublishSubject = PublishSubject.create() + private var brokenTaskEventsSubject: PublishSubject = PublishSubject.create() override val brokenTaskEvents: Flowable = brokenTaskEventsSubject.toFlowable(BackpressureStrategy.DROP) private var purchaseCardSubject: PublishSubject = PublishSubject.create() val purchaseCardEvents: Flowable = purchaseCardSubject.toFlowable(BackpressureStrategy.LATEST) diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/BaseDialogFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/BaseDialogFragment.kt new file mode 100644 index 000000000..5008482dd --- /dev/null +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/BaseDialogFragment.kt @@ -0,0 +1,118 @@ +package com.habitrpg.android.habitica.ui.fragments + +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.fragment.app.DialogFragment +import androidx.fragment.app.Fragment +import androidx.viewbinding.ViewBinding +import com.habitrpg.android.habitica.HabiticaBaseApplication +import com.habitrpg.android.habitica.components.UserComponent +import com.habitrpg.android.habitica.data.TutorialRepository +import com.habitrpg.android.habitica.helpers.AmplitudeManager +import com.habitrpg.android.habitica.helpers.RxErrorHandler +import com.habitrpg.android.habitica.ui.activities.MainActivity +import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers +import io.reactivex.rxjava3.disposables.CompositeDisposable +import io.reactivex.rxjava3.functions.Consumer +import org.greenrobot.eventbus.EventBus +import org.greenrobot.eventbus.EventBusException +import java.util.ArrayList +import java.util.HashMap +import java.util.concurrent.TimeUnit +import javax.inject.Inject + +abstract class BaseDialogFragment : DialogFragment() { + + var isModal: Boolean = false + abstract var binding: VB? + + @Inject + lateinit var tutorialRepository: TutorialRepository + + var tutorialStepIdentifier: String? = null + var tutorialText: String? = null + protected var tutorialCanBeDeferred = true + var tutorialTexts: MutableList = ArrayList() + + protected var compositeSubscription: CompositeDisposable = CompositeDisposable() + + open val displayedClassName: String? + get() = this.javaClass.simpleName + + override fun onCreate(savedInstanceState: Bundle?) { + HabiticaBaseApplication.userComponent?.let { + injectFragment(it) + } + super.onCreate(savedInstanceState) + } + + abstract fun createBinding(inflater: LayoutInflater, container: ViewGroup?): VB + + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { + compositeSubscription = CompositeDisposable() + + // Receive Events + try { + EventBus.getDefault().register(this) + } catch (ignored: EventBusException) { + + } + + val additionalData = HashMap() + additionalData["page"] = this.javaClass.simpleName + AmplitudeManager.sendEvent("navigate", AmplitudeManager.EVENT_CATEGORY_NAVIGATION, AmplitudeManager.EVENT_HITTYPE_PAGEVIEW, additionalData) + + binding = createBinding(inflater, container) + return binding?.root + } + + abstract fun injectFragment(component: UserComponent) + + override fun onResume() { + super.onResume() + showTutorialIfNeeded() + } + + private fun showTutorialIfNeeded() { + if (view != null) { + if (this.tutorialStepIdentifier != null) { + compositeSubscription.add(tutorialRepository.getTutorialStep(this.tutorialStepIdentifier ?: "").firstElement() + .delay(1, TimeUnit.SECONDS) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(Consumer { step -> + if (step != null && step.isValid && step.isManaged && step.shouldDisplay()) { + val mainActivity = activity as? MainActivity ?: return@Consumer + if (tutorialText != null) { + mainActivity.displayTutorialStep(step, tutorialText ?: "", tutorialCanBeDeferred) + } else { + mainActivity.displayTutorialStep(step, tutorialTexts, tutorialCanBeDeferred) + } + } + }, RxErrorHandler.handleEmptyError())) + } + } + } + + override fun onDestroyView() { + binding = null + if (EventBus.getDefault().isRegistered(this)) { + EventBus.getDefault().unregister(this) + } + if (!compositeSubscription.isDisposed) { + compositeSubscription.dispose() + } + + super.onDestroyView() + } + + override fun onDestroy() { + try { + tutorialRepository.close() + } catch (exception: UninitializedPropertyAccessException) {/* no-on */ } + super.onDestroy() + } + + open fun addToBackStack(): Boolean = true +} diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/BaseFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/BaseFragment.kt index 76485bc61..0fe160b4c 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/BaseFragment.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/BaseFragment.kt @@ -5,6 +5,7 @@ import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import androidx.fragment.app.DialogFragment +import androidx.fragment.app.Fragment import androidx.viewbinding.ViewBinding import com.habitrpg.android.habitica.HabiticaBaseApplication import com.habitrpg.android.habitica.components.UserComponent @@ -21,7 +22,7 @@ import java.util.* import java.util.concurrent.TimeUnit import javax.inject.Inject -abstract class BaseFragment : DialogFragment() { +abstract class BaseFragment : Fragment() { var isModal: Boolean = false abstract var binding: VB? @@ -43,7 +44,6 @@ abstract class BaseFragment : DialogFragment() { HabiticaBaseApplication.userComponent?.let { injectFragment(it) } - this.showsDialog = false super.onCreate(savedInstanceState) } @@ -75,7 +75,7 @@ abstract class BaseFragment : DialogFragment() { } private fun showTutorialIfNeeded() { - if (userVisibleHint && view != null) { + if (view != null) { if (this.tutorialStepIdentifier != null) { compositeSubscription.add(tutorialRepository.getTutorialStep(this.tutorialStepIdentifier ?: "").firstElement() .delay(1, TimeUnit.SECONDS) diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/NavigationDrawerFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/NavigationDrawerFragment.kt index 639a62c7d..f0afb6d27 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/NavigationDrawerFragment.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/NavigationDrawerFragment.kt @@ -1,6 +1,7 @@ package com.habitrpg.android.habitica.ui.fragments +import android.app.Activity import android.content.Intent import android.content.SharedPreferences import android.content.res.ColorStateList @@ -9,6 +10,7 @@ import android.os.Bundle import android.view.LayoutInflater import android.view.View import android.view.ViewGroup +import androidx.activity.result.contract.ActivityResultContracts import androidx.core.content.ContextCompat import androidx.core.content.edit import androidx.core.os.bundleOf @@ -34,7 +36,6 @@ import com.habitrpg.android.habitica.models.promotions.PromoType import com.habitrpg.android.habitica.models.social.Group import com.habitrpg.android.habitica.models.user.User import com.habitrpg.android.habitica.ui.activities.MainActivity -import com.habitrpg.android.habitica.ui.activities.MainActivity.Companion.NOTIFICATION_CLICK import com.habitrpg.android.habitica.ui.activities.NotificationsActivity import com.habitrpg.android.habitica.ui.adapter.NavigationDrawerAdapter import com.habitrpg.android.habitica.ui.fragments.social.TavernDetailFragment @@ -450,7 +451,16 @@ class NavigationDrawerFragment : DialogFragment() { // NotificationsActivity will return a result intent with a notificationId if a // notification item was clicked val intent = Intent(activity, NotificationsActivity::class.java) - activity.startActivityForResult(intent, NOTIFICATION_CLICK) + notificationClickResult.launch(intent) + } + } + + private val notificationClickResult = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { + if (it.resultCode == Activity.RESULT_OK) { + (activity as? MainActivity)?.notificationsViewModel?.click( + it.data?.getStringExtra("notificationId") ?: "", + MainNavigationController + ) } } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/items/ItemDialogFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/items/ItemDialogFragment.kt new file mode 100644 index 000000000..11906f31b --- /dev/null +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/items/ItemDialogFragment.kt @@ -0,0 +1,264 @@ +package com.habitrpg.android.habitica.ui.fragments.inventory.items + +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.view.Window +import androidx.swiperefreshlayout.widget.SwipeRefreshLayout +import com.habitrpg.android.habitica.R +import com.habitrpg.android.habitica.components.UserComponent +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.FragmentItemsBinding +import com.habitrpg.android.habitica.extensions.addCloseButton +import com.habitrpg.android.habitica.extensions.subscribeWithErrorHandler +import com.habitrpg.android.habitica.helpers.MainNavigationController +import com.habitrpg.android.habitica.helpers.RxErrorHandler +import com.habitrpg.android.habitica.models.inventory.* +import com.habitrpg.android.habitica.models.user.OwnedPet +import com.habitrpg.android.habitica.models.user.User +import com.habitrpg.android.habitica.ui.activities.MainActivity +import com.habitrpg.android.habitica.ui.adapter.inventory.ItemRecyclerAdapter +import com.habitrpg.android.habitica.ui.fragments.BaseDialogFragment +import com.habitrpg.android.habitica.ui.fragments.BaseFragment +import com.habitrpg.android.habitica.ui.helpers.SafeDefaultItemAnimator +import com.habitrpg.android.habitica.ui.helpers.loadImage +import com.habitrpg.android.habitica.ui.views.dialogs.OpenedMysteryitemDialog +import javax.inject.Inject + +class ItemDialogFragment : BaseDialogFragment(), SwipeRefreshLayout.OnRefreshListener { + + @Inject + lateinit var inventoryRepository: InventoryRepository + @Inject + lateinit var socialRepository: SocialRepository + @Inject + lateinit var userRepository: UserRepository + var adapter: ItemRecyclerAdapter? = null + var itemType: String? = null + var itemTypeText: String? = null + var isHatching: Boolean = false + var isFeeding: Boolean = false + internal var hatchingItem: Item? = null + var feedingPet: Pet? = null + var user: User? = null + internal var layoutManager: androidx.recyclerview.widget.LinearLayoutManager? = null + + override var binding: FragmentItemsBinding? = null + + override fun createBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentItemsBinding { + return FragmentItemsBinding.inflate(inflater, container, false) + } + + override fun onDestroy() { + inventoryRepository.close() + super.onDestroy() + } + + override fun injectFragment(component: UserComponent) { + component.inject(this) + } + + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { + when { + this.isHatching -> { + dialog?.requestWindowFeature(Window.FEATURE_NO_TITLE) + } + this.isFeeding -> { + dialog?.requestWindowFeature(Window.FEATURE_NO_TITLE) + } + else -> { + } + } + return super.onCreateView(inflater, container, savedInstanceState) + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + + binding?.recyclerView?.setEmptyView(binding?.emptyView) + binding?.refreshLayout?.setOnRefreshListener(this) + binding?.emptyTextView?.text = getString(R.string.empty_items, itemTypeText) + + val context = activity + + layoutManager = androidx.recyclerview.widget.LinearLayoutManager(context) + binding?.recyclerView?.layoutManager = layoutManager + + adapter = binding?.recyclerView?.adapter as? ItemRecyclerAdapter + if (adapter == null) { + context?.let { + adapter = ItemRecyclerAdapter(context) + adapter?.isHatching = this.isHatching + adapter?.isFeeding = this.isFeeding + adapter?.fragment = this + } + if (this.hatchingItem != null) { + adapter?.hatchingItem = this.hatchingItem + } + if (this.feedingPet != null) { + adapter?.feedingPet = this.feedingPet + } + binding?.recyclerView?.adapter = adapter + + adapter?.let { adapter -> + compositeSubscription.add(adapter.getSellItemFlowable() + .flatMap { item -> inventoryRepository.sellItem(item) } + .subscribe({ }, RxErrorHandler.handleEmptyError())) + + compositeSubscription.add(adapter.getQuestInvitationFlowable() + .flatMap { quest -> inventoryRepository.inviteToQuest(quest) } + .flatMap { socialRepository.retrieveGroup("party") } + .subscribe({ + if (isModal) { + dismiss() + } else { + MainNavigationController.navigate(R.id.partyFragment) + } + }, RxErrorHandler.handleEmptyError())) + compositeSubscription.add(adapter.getOpenMysteryItemFlowable() + .flatMap { inventoryRepository.openMysteryItem(user) } + .doOnNext { + val activity = activity as? MainActivity + if (activity != null) { + val dialog = OpenedMysteryitemDialog(activity) + dialog.isCelebratory = true + dialog.setTitle(R.string.mystery_item_title) + dialog.binding.iconView.loadImage("shop_${it.key}") + dialog.binding.titleView.text = it.text + dialog.binding.descriptionView.text = it.notes + dialog.addButton(R.string.equip, true) { _, _ -> + inventoryRepository.equip(user, "equipped", it.key ?: "").subscribe( {}, RxErrorHandler.handleEmptyError()) + } + dialog.addCloseButton() + dialog.enqueue() + } + } + .subscribe({ }, RxErrorHandler.handleEmptyError())) + compositeSubscription.add(adapter.hatchPetEvents.subscribeWithErrorHandler { hatchPet(it.first, it.second) }) + } + } + activity?.let { + binding?.recyclerView?.addItemDecoration(androidx.recyclerview.widget.DividerItemDecoration(it, androidx.recyclerview.widget.DividerItemDecoration.VERTICAL)) + } + binding?.recyclerView?.itemAnimator = SafeDefaultItemAnimator() + + if (savedInstanceState != null) { + this.itemType = savedInstanceState.getString(ITEM_TYPE_KEY, "") + } + + when { + this.isHatching -> { + binding?.titleTextView?.text = getString(R.string.hatch_with, this.hatchingItem?.text) + binding?.titleTextView?.visibility = View.VISIBLE + binding?.footerTextView?.text = getString(R.string.hatching_market_info) + binding?.footerTextView?.visibility = View.VISIBLE + binding?.openMarketButton?.visibility = View.VISIBLE + } + this.isFeeding -> { + binding?.titleTextView?.text = getString(R.string.dialog_feeding, this.feedingPet?.text) + binding?.titleTextView?.visibility = View.VISIBLE + binding?.footerTextView?.text = getString(R.string.feeding_market_info) + binding?.footerTextView?.visibility = View.VISIBLE + binding?.openMarketButton?.visibility = View.VISIBLE + } + else -> { + binding?.titleTextView?.visibility = View.GONE + binding?.footerTextView?.visibility = View.GONE + binding?.openMarketButton?.visibility = View.GONE + } + } + + binding?.openMarketButton?.setOnClickListener { + dismiss() + openMarket() + } + + binding?.openEmptyMarketButton?.setOnClickListener { openMarket() } + + this.loadItems() + } + + + override fun onResume() { + if ((this.isHatching || this.isFeeding) && dialog?.window != null) { + val params = dialog?.window?.attributes + params?.width = ViewGroup.LayoutParams.MATCH_PARENT + params?.verticalMargin = 60f + dialog?.window?.attributes = params + } + + super.onResume() + } + + override fun onSaveInstanceState(outState: Bundle) { + super.onSaveInstanceState(outState) + outState.putString(ITEM_TYPE_KEY, this.itemType) + } + + override fun onRefresh() { + binding?.refreshLayout?.isRefreshing = true + compositeSubscription.add(userRepository.retrieveUser(true, true) + .doOnTerminate { + binding?.refreshLayout?.isRefreshing = false + }.subscribe({ }, RxErrorHandler.handleEmptyError())) + } + + private fun hatchPet(potion: HatchingPotion, egg: Egg) { + dismiss() + (activity as? MainActivity)?.hatchPet(potion, egg) + } + + private fun loadItems() { + val itemClass: Class = when (itemType) { + "eggs" -> Egg::class.java + "hatchingPotions" -> HatchingPotion::class.java + "food" -> Food::class.java + "quests" -> QuestContent::class.java + "special" -> SpecialItem::class.java + else -> Egg::class.java + } + itemType?.let { type -> + compositeSubscription.add(inventoryRepository.getOwnedItems(type) + .doOnNext { items -> + val filteredItems = if (isFeeding) { + items.filter { it.key != "Saddle" } + } else { + items + } + adapter?.data = filteredItems + } + .map { items -> items.mapNotNull { it.key } } + .flatMap { inventoryRepository.getItems(itemClass, it.toTypedArray()) } + .map { + val itemMap = mutableMapOf() + for (item in it) { + itemMap[item.key] = item + } + itemMap + } + .subscribe({ items -> + adapter?.items = items + }, RxErrorHandler.handleEmptyError())) + } + + compositeSubscription.add(inventoryRepository.getPets().subscribe({ adapter?.setExistingPets(it) }, RxErrorHandler.handleEmptyError())) + compositeSubscription.add(inventoryRepository.getOwnedPets() + .map { ownedMounts -> + val mountMap = mutableMapOf() + ownedMounts.forEach { mountMap[it.key ?: ""] = it } + return@map mountMap + } + .subscribe({ adapter?.setOwnedPets(it) }, RxErrorHandler.handleEmptyError())) + } + + private fun openMarket() { + MainNavigationController.navigate(R.id.marketFragment) + } + + companion object { + private const val ITEM_TYPE_KEY = "CLASS_TYPE_KEY" + } +} diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/items/ItemRecyclerFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/items/ItemRecyclerFragment.kt index 07792ce5c..5850746b6 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/items/ItemRecyclerFragment.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/items/ItemRecyclerFragment.kt @@ -41,10 +41,6 @@ class ItemRecyclerFragment : BaseFragment(), SwipeRefreshL var adapter: ItemRecyclerAdapter? = null var itemType: String? = null var itemTypeText: String? = null - var isHatching: Boolean = false - var isFeeding: Boolean = false - private var hatchingItem: Item? = null - var feedingPet: Pet? = null var user: User? = null internal var layoutManager: androidx.recyclerview.widget.LinearLayoutManager? = null @@ -63,20 +59,6 @@ class ItemRecyclerFragment : BaseFragment(), SwipeRefreshL component.inject(this) } - override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { - when { - this.isHatching -> { - dialog?.requestWindowFeature(Window.FEATURE_NO_TITLE) - } - this.isFeeding -> { - dialog?.requestWindowFeature(Window.FEATURE_NO_TITLE) - } - else -> { - } - } - return super.onCreateView(inflater, container, savedInstanceState) - } - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) @@ -93,15 +75,6 @@ class ItemRecyclerFragment : BaseFragment(), SwipeRefreshL if (adapter == null) { context?.let { adapter = ItemRecyclerAdapter(context) - adapter?.isHatching = this.isHatching - adapter?.isFeeding = this.isFeeding - adapter?.fragment = this - } - if (this.hatchingItem != null) { - adapter?.hatchingItem = this.hatchingItem - } - if (this.feedingPet != null) { - adapter?.feedingPet = this.feedingPet } binding?.recyclerView?.adapter = adapter @@ -114,11 +87,7 @@ class ItemRecyclerFragment : BaseFragment(), SwipeRefreshL .flatMap { quest -> inventoryRepository.inviteToQuest(quest) } .flatMap { socialRepository.retrieveGroup("party") } .subscribe({ - if (isModal) { - dismiss() - } else { - MainNavigationController.navigate(R.id.partyFragment) - } + MainNavigationController.navigate(R.id.partyFragment) }, RxErrorHandler.handleEmptyError())) compositeSubscription.add(adapter.getOpenMysteryItemFlowable() .flatMap { inventoryRepository.openMysteryItem(user) } @@ -152,30 +121,11 @@ class ItemRecyclerFragment : BaseFragment(), SwipeRefreshL this.itemType = savedInstanceState.getString(ITEM_TYPE_KEY, "") } - when { - this.isHatching -> { - binding?.titleTextView?.text = getString(R.string.hatch_with, this.hatchingItem?.text) - binding?.titleTextView?.visibility = View.VISIBLE - binding?.footerTextView?.text = getString(R.string.hatching_market_info) - binding?.footerTextView?.visibility = View.VISIBLE - binding?.openMarketButton?.visibility = View.VISIBLE - } - this.isFeeding -> { - binding?.titleTextView?.text = getString(R.string.dialog_feeding, this.feedingPet?.text) - binding?.titleTextView?.visibility = View.VISIBLE - binding?.footerTextView?.text = getString(R.string.feeding_market_info) - binding?.footerTextView?.visibility = View.VISIBLE - binding?.openMarketButton?.visibility = View.VISIBLE - } - else -> { - binding?.titleTextView?.visibility = View.GONE - binding?.footerTextView?.visibility = View.GONE - binding?.openMarketButton?.visibility = View.GONE - } - } + binding?.titleTextView?.visibility = View.GONE + binding?.footerTextView?.visibility = View.GONE + binding?.openMarketButton?.visibility = View.GONE binding?.openMarketButton?.setOnClickListener { - dismiss() openMarket() } @@ -185,7 +135,7 @@ class ItemRecyclerFragment : BaseFragment(), SwipeRefreshL } private fun showHatchingDialog(item: Item) { - val fragment = ItemRecyclerFragment() + val fragment = ItemDialogFragment() if (item is Egg) { fragment.itemType = "hatchingPotions" fragment.hatchingItem = item @@ -198,17 +148,6 @@ class ItemRecyclerFragment : BaseFragment(), SwipeRefreshL parentFragmentManager.let { fragment.show(it, "hatchingDialog") } } - override fun onResume() { - if ((this.isHatching || this.isFeeding) && dialog?.window != null) { - val params = dialog?.window?.attributes - params?.width = ViewGroup.LayoutParams.MATCH_PARENT - params?.verticalMargin = 60f - dialog?.window?.attributes = params - } - - super.onResume() - } - override fun onSaveInstanceState(outState: Bundle) { super.onSaveInstanceState(outState) outState.putString(ITEM_TYPE_KEY, this.itemType) @@ -223,7 +162,6 @@ class ItemRecyclerFragment : BaseFragment(), SwipeRefreshL } private fun hatchPet(potion: HatchingPotion, egg: Egg) { - dismiss() (activity as? MainActivity)?.hatchPet(potion, egg) } @@ -239,12 +177,7 @@ class ItemRecyclerFragment : BaseFragment(), SwipeRefreshL itemType?.let { type -> compositeSubscription.add(inventoryRepository.getOwnedItems(type) .doOnNext { items -> - val filteredItems = if (isFeeding) { - items.filter { it.key != "Saddle" } - } else { - items - } - adapter?.data = filteredItems + adapter?.data = items } .map { items -> items.mapNotNull { it.key } } .flatMap { inventoryRepository.getItems(itemClass, it.toTypedArray()) } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/items/ItemsFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/items/ItemsFragment.kt index 048a39c4b..60ed12b67 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/items/ItemsFragment.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/items/ItemsFragment.kt @@ -5,7 +5,9 @@ import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import androidx.fragment.app.FragmentPagerAdapter +import androidx.viewpager2.adapter.FragmentStateAdapter import com.google.android.material.tabs.TabLayout +import com.google.android.material.tabs.TabLayoutMediator import com.habitrpg.android.habitica.R import com.habitrpg.android.habitica.components.UserComponent import com.habitrpg.android.habitica.databinding.FragmentViewpagerBinding @@ -51,9 +53,9 @@ class ItemsFragment : BaseMainFragment() { private fun setViewPagerAdapter() { val fragmentManager = childFragmentManager - binding?.viewPager?.adapter = object : FragmentPagerAdapter(fragmentManager, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT) { + binding?.viewPager?.adapter = object : FragmentStateAdapter(fragmentManager, lifecycle) { - override fun getItem(position: Int): androidx.fragment.app.Fragment { + override fun createFragment(position: Int): androidx.fragment.app.Fragment { val fragment = ItemRecyclerFragment() fragment.itemType = when (position) { @@ -64,32 +66,32 @@ class ItemsFragment : BaseMainFragment() { 4 -> "special" else -> "" } - fragment.isHatching = false - fragment.isFeeding = false fragment.user = this@ItemsFragment.user - fragment.itemTypeText = + /*fragment.itemTypeText = if (position == 4) getString(R.string.special_items) else this.getPageTitle(position).toString() - +*/ return fragment } - override fun getCount(): Int { + override fun getItemCount(): Int { return 5 } - - override fun getPageTitle(position: Int): CharSequence { - return when (position) { - 0 -> activity?.getString(R.string.eggs) - 1 -> activity?.getString(R.string.hatching_potions) - 2 -> activity?.getString(R.string.food) - 3 -> activity?.getString(R.string.quests) - 4 -> activity?.getString(R.string.special) - else -> "" - } ?: "" + } + tabLayout?.let { + binding?.viewPager?.let { it1 -> + TabLayoutMediator(it, it1) { tab, position -> + tab.text = when (position) { + 0 -> activity?.getString(R.string.eggs) + 1 -> activity?.getString(R.string.hatching_potions) + 2 -> activity?.getString(R.string.food) + 3 -> activity?.getString(R.string.quests) + 4 -> activity?.getString(R.string.special) + else -> "" + } ?: "" + }.attach() } } - tabLayout?.setupWithViewPager(binding?.viewPager) tabLayout?.tabMode = TabLayout.MODE_SCROLLABLE } } 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 27f038c9a..03fc1e36a 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 @@ -19,6 +19,7 @@ import com.habitrpg.android.habitica.models.user.OwnedMount import com.habitrpg.android.habitica.models.user.OwnedPet import com.habitrpg.android.habitica.ui.adapter.inventory.PetDetailRecyclerAdapter import com.habitrpg.android.habitica.ui.fragments.BaseMainFragment +import com.habitrpg.android.habitica.ui.fragments.inventory.items.ItemDialogFragment import com.habitrpg.android.habitica.ui.fragments.inventory.items.ItemRecyclerFragment import com.habitrpg.android.habitica.ui.helpers.MarginDecoration import com.habitrpg.android.habitica.ui.helpers.SafeDefaultItemAnimator @@ -182,7 +183,7 @@ class PetDetailRecyclerFragment : BaseMainFragment( @Subscribe fun showFeedingDialog(event: FeedCommand) { if (event.usingPet == null || event.usingFood == null) { - val fragment = ItemRecyclerFragment() + val fragment = ItemDialogFragment() fragment.feedingPet = event.usingPet fragment.isFeeding = true fragment.isHatching = false diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/stable/StableFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/stable/StableFragment.kt index cc109e048..a7d0f6ef9 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/stable/StableFragment.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/stable/StableFragment.kt @@ -5,6 +5,8 @@ import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import androidx.fragment.app.FragmentPagerAdapter +import androidx.viewpager2.adapter.FragmentStateAdapter +import com.google.android.material.tabs.TabLayoutMediator import com.habitrpg.android.habitica.R import com.habitrpg.android.habitica.components.UserComponent import com.habitrpg.android.habitica.databinding.FragmentViewpagerBinding @@ -39,10 +41,9 @@ class StableFragment : BaseMainFragment() { private fun setViewPagerAdapter() { val fragmentManager = childFragmentManager - binding?.viewPager?.adapter = object : FragmentPagerAdapter(fragmentManager, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT) { - - override fun getItem(position: Int): androidx.fragment.app.Fragment { + binding?.viewPager?.adapter = object : FragmentStateAdapter(fragmentManager, lifecycle) { + override fun createFragment(position: Int): androidx.fragment.app.Fragment { val fragment = StableRecyclerFragment() when (position) { @@ -54,24 +55,26 @@ class StableFragment : BaseMainFragment() { } } fragment.user = this@StableFragment.user - fragment.itemTypeText = this.getPageTitle(position).toString() + //fragment.itemTypeText = this.getPageTitle(position).toString() return fragment } - override fun getCount(): Int { + override fun getItemCount(): Int { return 2 } - - override fun getPageTitle(position: Int): CharSequence { - return when (position) { - 0 -> activity?.getString(R.string.pets) - 1 -> activity?.getString(R.string.mounts) - else -> "" - } ?: "" + } + tabLayout?.let { + binding?.viewPager?.let { it1 -> + TabLayoutMediator(it, it1) { tab, position -> + tab.text = when (position) { + 0 -> activity?.getString(R.string.pets) + 1 -> activity?.getString(R.string.mounts) + else -> "" + } ?: "" + }.attach() } } - tabLayout?.setupWithViewPager(binding?.viewPager) } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/preferences/PreferencesFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/preferences/PreferencesFragment.kt index e8a0bd4d4..aa33217c8 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/preferences/PreferencesFragment.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/preferences/PreferencesFragment.kt @@ -1,12 +1,11 @@ package com.habitrpg.android.habitica.ui.fragments.preferences -import android.annotation.SuppressLint import android.content.Intent import android.content.SharedPreferences import android.content.res.Configuration -import android.os.Build import android.os.Bundle import android.view.View +import androidx.activity.result.contract.ActivityResultContracts import androidx.appcompat.app.AlertDialog import androidx.preference.CheckBoxPreference import androidx.preference.ListPreference @@ -126,12 +125,12 @@ class PreferencesFragment : BasePreferencesFragment(), SharedPreferences.OnShare val builder = AlertDialog.Builder(context) .setMessage(getString(R.string.change_class_confirmation)) .setNegativeButton(getString(R.string.dialog_go_back)) { dialog, _ -> dialog.dismiss() } - .setPositiveButton(getString(R.string.change_class)) { _, _ -> startActivityForResult(intent, MainActivity.SELECT_CLASS_RESULT) } + .setPositiveButton(getString(R.string.change_class)) { _, _ -> classSelectionResult.launch(intent) } val alert = builder.create() alert.show() } } else { - startActivityForResult(intent, MainActivity.SELECT_CLASS_RESULT) + classSelectionResult.launch(intent) } return true } @@ -155,6 +154,9 @@ class PreferencesFragment : BasePreferencesFragment(), SharedPreferences.OnShare return super.onPreferenceTreeClick(preference) } + private val classSelectionResult = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { + userRepository.retrieveUser(true, forced = true) + } override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences, key: String) { when (key) { diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/skills/SkillsFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/skills/SkillsFragment.kt index d068f8b24..675ec208e 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/skills/SkillsFragment.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/skills/SkillsFragment.kt @@ -7,12 +7,12 @@ import android.os.Bundle import android.view.LayoutInflater import android.view.View import android.view.ViewGroup +import androidx.activity.result.contract.ActivityResultContracts import androidx.core.content.ContextCompat import com.habitrpg.android.habitica.R import com.habitrpg.android.habitica.components.UserComponent import com.habitrpg.android.habitica.databinding.FragmentSkillsBinding import com.habitrpg.android.habitica.extensions.subscribeWithErrorHandler -import com.habitrpg.android.habitica.helpers.MainNavigationController import com.habitrpg.android.habitica.helpers.RxErrorHandler import com.habitrpg.android.habitica.models.Skill import com.habitrpg.android.habitica.models.responses.SkillResponse @@ -21,23 +21,17 @@ import com.habitrpg.android.habitica.ui.activities.SkillMemberActivity import com.habitrpg.android.habitica.ui.activities.SkillTasksActivity import com.habitrpg.android.habitica.ui.adapter.SkillsRecyclerViewAdapter import com.habitrpg.android.habitica.ui.fragments.BaseMainFragment -import com.habitrpg.android.habitica.ui.fragments.social.challenges.ChallengesOverviewFragmentDirections import com.habitrpg.android.habitica.ui.helpers.SafeDefaultItemAnimator import com.habitrpg.android.habitica.ui.views.HabiticaIconsHelper import com.habitrpg.android.habitica.ui.views.HabiticaSnackbar import com.habitrpg.android.habitica.ui.views.HabiticaSnackbar.Companion.showSnackbar import io.reactivex.rxjava3.core.Flowable -import io.reactivex.rxjava3.core.Observable import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.delay import kotlinx.coroutines.launch class SkillsFragment : BaseMainFragment() { - - private val TASK_SELECTION_ACTIVITY = 10 - private val MEMBER_SELECTION_ACTIVITY = 11 - internal var adapter: SkillsRecyclerViewAdapter? = null private var selectedSkill: Skill? = null @@ -104,12 +98,12 @@ class SkillsFragment : BaseMainFragment() { "special" == skill.habitClass -> { selectedSkill = skill val intent = Intent(activity, SkillMemberActivity::class.java) - startActivityForResult(intent, MEMBER_SELECTION_ACTIVITY) + memberSelectionResult.launch(intent) } skill.target == "task" -> { selectedSkill = skill val intent = Intent(activity, SkillTasksActivity::class.java) - startActivityForResult(intent, TASK_SELECTION_ACTIVITY) + taskSelectionResult.launch(intent) } else -> useSkill(skill) } @@ -144,22 +138,15 @@ class SkillsFragment : BaseMainFragment() { compositeSubscription.add(userRepository.retrieveUser(false).subscribe({ }, RxErrorHandler.handleEmptyError())) } + private val taskSelectionResult = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { + if (it.resultCode == Activity.RESULT_OK) { + useSkill(selectedSkill, it.data?.getStringExtra("taskID")) + } + } - override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { - super.onActivityResult(requestCode, resultCode, data) - if (data != null) { - when (requestCode) { - TASK_SELECTION_ACTIVITY -> { - if (resultCode == Activity.RESULT_OK) { - useSkill(selectedSkill, data.getStringExtra("taskID")) - } - } - MEMBER_SELECTION_ACTIVITY -> { - if (resultCode == Activity.RESULT_OK) { - useSkill(selectedSkill, data.getStringExtra("member_id")) - } - } - } + private val memberSelectionResult = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { + if (it.resultCode == Activity.RESULT_OK) { + useSkill(selectedSkill, it.data?.getStringExtra("member_id")) } } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/TavernFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/TavernFragment.kt index 256ad7314..aaf437245 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/TavernFragment.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/TavernFragment.kt @@ -3,8 +3,9 @@ package com.habitrpg.android.habitica.ui.fragments.social import android.os.Bundle import android.view.* import androidx.fragment.app.Fragment -import androidx.fragment.app.FragmentPagerAdapter import androidx.lifecycle.ViewModelProvider +import androidx.viewpager2.adapter.FragmentStateAdapter +import com.google.android.material.tabs.TabLayoutMediator import com.habitrpg.android.habitica.R import com.habitrpg.android.habitica.components.UserComponent import com.habitrpg.android.habitica.data.SocialRepository @@ -79,11 +80,11 @@ class TavernFragment : BaseMainFragment() { private fun setViewPagerAdapter() { val fragmentManager = childFragmentManager - binding?.viewPager?.adapter = object : FragmentPagerAdapter(fragmentManager, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT) { - override fun getItem(position: Int): Fragment { + binding?.viewPager?.adapter = object : FragmentStateAdapter(fragmentManager, lifecycle) { + override fun createFragment(position: Int): Fragment { return when (position) { 0 -> { - tavernDetailFragment + TavernDetailFragment() } 1 -> { chatFragment = ChatFragment() @@ -94,22 +95,24 @@ class TavernFragment : BaseMainFragment() { } } - override fun getCount(): Int { + override fun getItemCount(): Int { return if (viewModel.getGroupData().value?.quest?.active == true) { 3 } else 2 } - - override fun getPageTitle(position: Int): CharSequence? { - return when (position) { - 0 -> context?.getString(R.string.inn) - 1 -> context?.getString(R.string.chat) - 2 -> context?.getString(R.string.world_quest) - else -> "" - } + } + tabLayout?.let { + binding?.viewPager?.let { it1 -> + TabLayoutMediator(it, it1) { tab, position -> + tab.text = when (position) { + 0 -> context?.getString(R.string.inn) + 1 -> context?.getString(R.string.chat) + 2 -> context?.getString(R.string.world_quest) + else -> "" + } + }.attach() } } - tabLayout?.setupWithViewPager(binding?.viewPager) } } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/challenges/ChallengesOverviewFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/challenges/ChallengesOverviewFragment.kt index 31c6b6f58..8b69a4a8d 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/challenges/ChallengesOverviewFragment.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/challenges/ChallengesOverviewFragment.kt @@ -8,6 +8,8 @@ import android.widget.TextView import androidx.core.view.MenuItemCompat import androidx.fragment.app.Fragment import androidx.fragment.app.FragmentStatePagerAdapter +import androidx.viewpager2.adapter.FragmentStateAdapter +import com.google.android.material.tabs.TabLayoutMediator import com.habitrpg.android.habitica.R import com.habitrpg.android.habitica.components.UserComponent import com.habitrpg.android.habitica.data.ChallengeRepository @@ -27,7 +29,7 @@ class ChallengesOverviewFragment : BaseMainFragment() return FragmentViewpagerBinding.inflate(inflater, container, false) } - private var statePagerAdapter: FragmentStatePagerAdapter? = null + private var statePagerAdapter: FragmentStateAdapter? = null private var userChallengesFragment: ChallengeListFragment? = ChallengeListFragment() private var availableChallengesFragment: ChallengeListFragment? = ChallengeListFragment() @@ -107,9 +109,9 @@ class ChallengesOverviewFragment : BaseMainFragment() private fun setViewPagerAdapter() { val fragmentManager = childFragmentManager - statePagerAdapter = object : FragmentStatePagerAdapter(fragmentManager, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT) { + statePagerAdapter = object : FragmentStateAdapter(fragmentManager, lifecycle) { - override fun getItem(position: Int): Fragment { + override fun createFragment(position: Int): Fragment { return if (position == 0) { userChallengesFragment } else { @@ -117,20 +119,23 @@ class ChallengesOverviewFragment : BaseMainFragment() } ?: Fragment() } - override fun getCount(): Int { + override fun getItemCount(): Int { return 2 } - - override fun getPageTitle(position: Int): CharSequence? { - return when (position) { - 0 -> getString(R.string.my_challenges) - 1 -> getString(R.string.discover) - else -> "" - } - } } binding?.viewPager?.adapter = statePagerAdapter - tabLayout?.setupWithViewPager(binding?.viewPager) + tabLayout?.let { + binding?.viewPager?.let { it1 -> + TabLayoutMediator(it, it1) { tab, position -> + tab.text = when (position) { + 0 -> getString(R.string.my_challenges) + 1 -> getString(R.string.discover) + 1 -> getString(R.string.discover) + else -> "" + } + }.attach() + } + } statePagerAdapter?.notifyDataSetChanged() } } 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 271b7a2a8..0d13ccf52 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 @@ -7,6 +7,7 @@ import android.text.method.LinkMovementMethod import android.view.LayoutInflater import android.view.View import android.view.ViewGroup +import androidx.activity.result.contract.ActivityResultContracts import com.habitrpg.android.habitica.MainNavDirections import com.habitrpg.android.habitica.R import com.habitrpg.android.habitica.components.UserComponent @@ -65,7 +66,7 @@ class GuildDetailFragment : BaseFragment() { } binding?.inviteButton?.setOnClickListener { val intent = Intent(activity, GroupInviteActivity::class.java) - startActivityForResult(intent, GroupInviteActivity.RESULT_SEND_INVITES) + sendInvitesResult.launch(intent) } binding?.leaderWrapper?.setOnClickListener { viewModel?.getGroupData()?.value?.leaderID?.let {leaderID -> @@ -90,37 +91,27 @@ class GuildDetailFragment : BaseFragment() { binding?.leaveButton?.visibility = if (isMember == true) View.VISIBLE else View.GONE } - override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { - super.onActivityResult(requestCode, resultCode, data) - when (requestCode) { - GroupFormActivity.GROUP_FORM_ACTIVITY -> { - if (resultCode == Activity.RESULT_OK) { - viewModel?.updateGroup(data?.extras) - } - } - GroupInviteActivity.RESULT_SEND_INVITES -> { - if (resultCode == Activity.RESULT_OK) { - val inviteData = HashMap() - inviteData["inviter"] = viewModel?.getUserData()?.value?.profile?.name ?: "" - if (data?.getBooleanExtra(GroupInviteActivity.IS_EMAIL_KEY, false) == true) { - val emails = data.getStringArrayExtra(GroupInviteActivity.EMAILS_KEY) - val invites = ArrayList>() - emails?.forEach { email -> - val invite = HashMap() - invite["name"] = "" - invite["email"] = email - invites.add(invite) - } - inviteData["emails"] = invites - } else { - val userIDs = data?.getStringArrayExtra(GroupInviteActivity.USER_IDS_KEY) - val invites = mutableListOf() - userIDs?.forEach { invites.add(it) } - inviteData["usernames"] = invites - } - viewModel?.inviteToGroup(inviteData) + private val sendInvitesResult = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { + if (it.resultCode == Activity.RESULT_OK) { + val inviteData = HashMap() + inviteData["inviter"] = viewModel?.getUserData()?.value?.profile?.name ?: "" + if (it.data?.getBooleanExtra(GroupInviteActivity.IS_EMAIL_KEY, false) == true) { + val emails = it.data?.getStringArrayExtra(GroupInviteActivity.EMAILS_KEY) + val invites = ArrayList>() + emails?.forEach { email -> + val invite = HashMap() + invite["name"] = "" + invite["email"] = email + invites.add(invite) } + inviteData["emails"] = invites + } else { + val userIDs = it.data?.getStringArrayExtra(GroupInviteActivity.USER_IDS_KEY) + val invites = mutableListOf() + userIDs?.forEach { invites.add(it) } + inviteData["usernames"] = invites } + viewModel?.inviteToGroup(inviteData) } } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/guilds/GuildFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/guilds/GuildFragment.kt index 40f3bbf22..dceccda94 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/guilds/GuildFragment.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/guilds/GuildFragment.kt @@ -4,9 +4,12 @@ import android.app.Activity import android.content.Intent import android.os.Bundle import android.view.* +import androidx.activity.result.contract.ActivityResultContracts import androidx.fragment.app.Fragment -import androidx.fragment.app.FragmentPagerAdapter import androidx.lifecycle.ViewModelProvider +import androidx.viewpager2.adapter.FragmentStateAdapter +import androidx.viewpager2.widget.ViewPager2 +import com.google.android.material.tabs.TabLayoutMediator import com.google.firebase.analytics.FirebaseAnalytics import com.habitrpg.android.habitica.R import com.habitrpg.android.habitica.components.UserComponent @@ -15,7 +18,6 @@ import com.habitrpg.android.habitica.models.social.Group import com.habitrpg.android.habitica.ui.activities.GroupFormActivity import com.habitrpg.android.habitica.ui.fragments.BaseMainFragment import com.habitrpg.android.habitica.ui.fragments.social.ChatFragment -import com.habitrpg.android.habitica.ui.fragments.social.guilds.GuildFragmentArgs import com.habitrpg.android.habitica.ui.viewmodels.GroupViewModel import com.habitrpg.android.habitica.ui.viewmodels.GroupViewType @@ -133,9 +135,9 @@ class GuildFragment : BaseMainFragment() { private fun setViewPagerAdapter() { val fragmentManager = childFragmentManager - binding?.viewPager?.adapter = object : FragmentPagerAdapter(fragmentManager, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT) { + binding?.viewPager?.adapter = object : FragmentStateAdapter(fragmentManager, lifecycle) { - override fun getItem(position: Int): Fragment { + override fun createFragment(position: Int): Fragment { val fragment: Fragment? when (position) { @@ -154,20 +156,12 @@ class GuildFragment : BaseMainFragment() { return fragment ?: Fragment() } - override fun getCount(): Int { + override fun getItemCount(): Int { return 2 } - - override fun getPageTitle(position: Int): CharSequence? { - return when (position) { - 0 -> context?.getString(R.string.guild) - 1 -> context?.getString(R.string.chat) - else -> "" - } - } } - binding?.viewPager?.addOnPageChangeListener(object : androidx.viewpager.widget.ViewPager.OnPageChangeListener { + binding?.viewPager?.registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() { override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) { if (position == 1) { chatFragment?.setNavigatedToFragment() @@ -179,11 +173,19 @@ class GuildFragment : BaseMainFragment() { chatFragment?.setNavigatedToFragment() } } - - override fun onPageScrollStateChanged(state: Int) { /* no-on */ } }) - tabLayout?.setupWithViewPager(binding?.viewPager) + tabLayout?.let { + binding?.viewPager?.let { it1 -> + TabLayoutMediator(it, it1) { tab, position -> + tab.text = when (position) { + 0 -> context?.getString(R.string.guild) + 1 -> context?.getString(R.string.chat) + else -> "" + } + }.attach() + } + } } private fun displayEditForm() { @@ -200,18 +202,14 @@ class GuildFragment : BaseMainFragment() { val intent = Intent(activity, GroupFormActivity::class.java) intent.putExtras(bundle) intent.flags = Intent.FLAG_ACTIVITY_REORDER_TO_FRONT - startActivityForResult(intent, GroupFormActivity.GROUP_FORM_ACTIVITY) + groupFormResult.launch(intent) } - override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { - super.onActivityResult(requestCode, resultCode, data) - when (requestCode) { - GroupFormActivity.GROUP_FORM_ACTIVITY -> { - if (resultCode == Activity.RESULT_OK) { - val bundle = data?.extras - viewModel.updateGroup(bundle) - } - } + + private val groupFormResult = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { + if (it.resultCode == Activity.RESULT_OK) { + val bundle = it?.data?.extras + viewModel.updateGroup(bundle) } } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/guilds/GuildOverviewFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/guilds/GuildOverviewFragment.kt index 0ba22be5c..940921d45 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/guilds/GuildOverviewFragment.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/guilds/GuildOverviewFragment.kt @@ -4,13 +4,12 @@ import android.content.Intent import android.content.pm.PackageManager import android.os.Bundle import android.view.* -import android.widget.RelativeLayout -import android.widget.TextView import androidx.appcompat.widget.SearchView import androidx.core.content.ContextCompat import androidx.core.net.toUri import androidx.fragment.app.Fragment -import androidx.fragment.app.FragmentStatePagerAdapter +import androidx.viewpager2.adapter.FragmentStateAdapter +import com.google.android.material.tabs.TabLayoutMediator import com.habitrpg.android.habitica.R import com.habitrpg.android.habitica.components.UserComponent import com.habitrpg.android.habitica.data.SocialRepository @@ -31,7 +30,7 @@ class GuildOverviewFragment : BaseMainFragment(), Sear return FragmentViewpagerBinding.inflate(inflater, container, false) } - private var statePagerAdapter: FragmentStatePagerAdapter? = null + private var statePagerAdapter: FragmentStateAdapter? = null private var userGuildsFragment: GuildListFragment? = GuildListFragment() private var publicGuildsFragment: GuildListFragment? = GuildListFragment() @@ -84,7 +83,7 @@ class GuildOverviewFragment : BaseMainFragment(), Sear val dialog = HabiticaAlertDialog(context) dialog.setTitle(R.string.create_guild) dialog.setMessage(R.string.create_guild_description) - dialog.addButton(R.string.open_website, true, false) { _, _ -> + dialog.addButton(R.string.open_website, isPrimary = true, isDestructive = false) { _, _ -> val uriUrl = "https://habitica.com/groups/myGuilds".toUri() val launchBrowser = Intent(Intent.ACTION_VIEW, uriUrl) val l = context.packageManager.queryIntentActivities(launchBrowser, PackageManager.MATCH_DEFAULT_ONLY) @@ -107,32 +106,35 @@ class GuildOverviewFragment : BaseMainFragment(), Sear private fun setViewPagerAdapter() { val fragmentManager = childFragmentManager - statePagerAdapter = object : FragmentStatePagerAdapter(fragmentManager, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT) { + statePagerAdapter = object : FragmentStateAdapter(fragmentManager, lifecycle) { - override fun getItem(position: Int): Fragment { - return if (position == 0) { - userGuildsFragment?.onlyShowUsersGuilds = true - userGuildsFragment + override fun createFragment(position: Int): Fragment { + val fragment = GuildListFragment() + fragment.onlyShowUsersGuilds = position == 0 + if (position == 0) { + userGuildsFragment = fragment } else { - publicGuildsFragment?.onlyShowUsersGuilds = false - publicGuildsFragment - } ?: Fragment() - } - - override fun getCount(): Int { - return 2 - } - - override fun getPageTitle(position: Int): CharSequence { - return when (position) { - 0 -> getString(R.string.my_guilds) - 1 -> getString(R.string.discover) - else -> "" + publicGuildsFragment = fragment } + return fragment + } + + override fun getItemCount(): Int { + return 2 } } binding?.viewPager?.adapter = statePagerAdapter - tabLayout?.setupWithViewPager(binding?.viewPager) + tabLayout?.let { + binding?.viewPager?.let { it1 -> + TabLayoutMediator(it, it1) { tab, position -> + tab.text = when (position) { + 0 -> getString(R.string.my_guilds) + 1 -> getString(R.string.discover) + else -> "" + } + }.attach() + } + } statePagerAdapter?.notifyDataSetChanged() } 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 d016aa122..93d40c4de 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 @@ -13,6 +13,7 @@ import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import android.widget.TextView +import androidx.activity.result.contract.ActivityResultContracts import androidx.core.os.bundleOf import com.google.firebase.analytics.FirebaseAnalytics import com.habitrpg.android.habitica.R @@ -100,7 +101,7 @@ class NoPartyFragmentFragment : BaseMainFragment() { val intent = Intent(activity, GroupFormActivity::class.java) intent.putExtras(bundle) intent.flags = Intent.FLAG_ACTIVITY_REORDER_TO_FRONT - startActivityForResult(intent, GroupFormActivity.GROUP_FORM_ACTIVITY) + groupFormResult.launch(intent) } context?.let { context -> @@ -138,31 +139,26 @@ class NoPartyFragmentFragment : BaseMainFragment() { binding?.usernameTextview?.text = user?.formattedUsername } - override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { - super.onActivityResult(requestCode, resultCode, data) - when (requestCode) { - GroupFormActivity.GROUP_FORM_ACTIVITY -> { - if (resultCode == Activity.RESULT_OK) { - val bundle = data?.extras - if (bundle?.getString("groupType") == "party") { - socialRepository.createGroup(bundle.getString("name"), - bundle.getString("description"), - bundle.getString("leader"), - "party", - bundle.getString("privacy"), - bundle.getBoolean("leaderCreateChallenge")) - .flatMap { - userRepository.retrieveUser(false) - } - .subscribe({ - if (isAdded) { - parentFragmentManager.popBackStack() - } - MainNavigationController.navigate(R.id.partyFragment, - bundleOf(Pair("partyID", user?.party?.id))) - }, RxErrorHandler.handleEmptyError()) + private val groupFormResult = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { + if (it.resultCode == Activity.RESULT_OK) { + val bundle = it.data?.extras + if (bundle?.getString("groupType") == "party") { + socialRepository.createGroup(bundle.getString("name"), + bundle.getString("description"), + bundle.getString("leader"), + "party", + bundle.getString("privacy"), + bundle.getBoolean("leaderCreateChallenge")) + .flatMap { + userRepository.retrieveUser(false) } - } + .subscribe({ + if (isAdded) { + parentFragmentManager.popBackStack() + } + MainNavigationController.navigate(R.id.partyFragment, + bundleOf(Pair("partyID", user?.party?.id))) + }, RxErrorHandler.handleEmptyError()) } } } 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 beb084526..3e0a3860a 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 @@ -327,7 +327,7 @@ class PartyDetailFragment : BaseFragment() { fragment.itemType = "quests" fragment.itemTypeText = getString(R.string.quest) fragment.isModal = true - fragment.show(parentFragmentManager, "questDialog") + //fragment.show(parentFragmentManager, "questDialog") } internal fun leaveParty() { diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/party/PartyFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/party/PartyFragment.kt index 1eccf3a5a..96ae859a9 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/party/PartyFragment.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/party/PartyFragment.kt @@ -4,10 +4,12 @@ import android.app.Activity import android.content.Intent import android.os.Bundle import android.view.* +import androidx.activity.result.contract.ActivityResultContracts import androidx.fragment.app.Fragment -import androidx.fragment.app.FragmentPagerAdapter import androidx.lifecycle.ViewModelProvider -import androidx.viewpager.widget.ViewPager +import androidx.viewpager2.adapter.FragmentStateAdapter +import androidx.viewpager2.widget.ViewPager2 +import com.google.android.material.tabs.TabLayoutMediator import com.habitrpg.android.habitica.R import com.habitrpg.android.habitica.components.UserComponent import com.habitrpg.android.habitica.databinding.FragmentViewpagerBinding @@ -25,7 +27,7 @@ class PartyFragment : BaseMainFragment() { private var detailFragment: PartyDetailFragment? = null private var chatFragment: ChatFragment? = null - private var viewPagerAdapter: FragmentPagerAdapter? = null + private var viewPagerAdapter: FragmentStateAdapter? = null internal lateinit var viewModel: PartyViewModel @@ -42,17 +44,17 @@ class PartyFragment : BaseMainFragment() { return super.onCreateView(inflater, container, savedInstanceState) } - override fun onActivityCreated(savedInstanceState: Bundle?) { - super.onActivityCreated(savedInstanceState) + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) viewModel = ViewModelProvider(this) - .get(PartyViewModel::class.java) + .get(PartyViewModel::class.java) viewModel.groupViewType = GroupViewType.PARTY viewModel.getGroupData().observe(viewLifecycleOwner, - { - updateGroupUI(it) - }) + { + updateGroupUI(it) + }) binding?.viewPager?.currentItem = 0 @@ -72,9 +74,8 @@ class PartyFragment : BaseMainFragment() { this.tutorialStepIdentifier = "party" this.tutorialText = getString(R.string.tutorial_party) - viewModel.retrieveGroup { } + viewModel.retrieveGroup {} } - override fun injectFragment(component: UserComponent) { component.inject(this) } @@ -112,7 +113,7 @@ class PartyFragment : BaseMainFragment() { R.id.menu_invite_item -> { val intent = Intent(activity, GroupInviteActivity::class.java) intent.putExtra("groupType", "party") - startActivityForResult(intent, GroupInviteActivity.RESULT_SEND_INVITES) + sendInvitesResult.launch(intent) return true } R.id.menu_guild_edit -> { @@ -145,50 +146,46 @@ class PartyFragment : BaseMainFragment() { val intent = Intent(activity, GroupFormActivity::class.java) intent.putExtras(bundle) intent.flags = Intent.FLAG_ACTIVITY_REORDER_TO_FRONT - startActivityForResult(intent, GroupFormActivity.GROUP_FORM_ACTIVITY) + groupFormResult.launch(intent) } - override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { - super.onActivityResult(requestCode, resultCode, data) - when (requestCode) { - GroupFormActivity.GROUP_FORM_ACTIVITY -> { - if (resultCode == Activity.RESULT_OK) { - viewModel.updateOrCreateGroup(data?.extras) + private val groupFormResult = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { + if (it.resultCode == Activity.RESULT_OK) { + viewModel.updateOrCreateGroup(it.data?.extras) + } + } + + private val sendInvitesResult = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { + if (it.resultCode == Activity.RESULT_OK) { + val inviteData = HashMap() + inviteData["inviter"] = user?.profile?.name ?: "" + val emails = it.data?.getStringArrayExtra(GroupInviteActivity.EMAILS_KEY) + if (emails != null && emails.isNotEmpty()) { + val invites = ArrayList>() + emails.forEach { email -> + val invite = HashMap() + invite["name"] = "" + invite["email"] = email + invites.add(invite) } + inviteData["emails"] = invites } - GroupInviteActivity.RESULT_SEND_INVITES -> { - if (resultCode == Activity.RESULT_OK) { - val inviteData = HashMap() - inviteData["inviter"] = user?.profile?.name ?: "" - val emails = data?.getStringArrayExtra(GroupInviteActivity.EMAILS_KEY) - if (emails != null && emails.isNotEmpty()) { - val invites = ArrayList>() - emails.forEach { email -> - val invite = HashMap() - invite["name"] = "" - invite["email"] = email - invites.add(invite) - } - inviteData["emails"] = invites - } - val userIDs = data?.getStringArrayExtra(GroupInviteActivity.USER_IDS_KEY) - if (userIDs != null && userIDs.isNotEmpty()){ - val invites = ArrayList() - userIDs.forEach { invites.add(it) } - inviteData["usernames"] = invites - } - viewModel.inviteToGroup(inviteData) - } + val userIDs = it.data?.getStringArrayExtra(GroupInviteActivity.USER_IDS_KEY) + if (userIDs != null && userIDs.isNotEmpty()){ + val invites = ArrayList() + userIDs.forEach { invites.add(it) } + inviteData["usernames"] = invites } + viewModel.inviteToGroup(inviteData) } } private fun setViewPagerAdapter() { val fragmentManager = childFragmentManager - viewPagerAdapter = object : FragmentPagerAdapter(fragmentManager, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT) { + viewPagerAdapter = object : FragmentStateAdapter(fragmentManager, lifecycle) { - override fun getItem(position: Int): Fragment { + override fun createFragment(position: Int): Fragment { return when (position) { 0 -> { detailFragment = PartyDetailFragment() @@ -196,10 +193,8 @@ class PartyFragment : BaseMainFragment() { detailFragment } 1 -> { - if (chatFragment == null) { - chatFragment = ChatFragment() - chatFragment?.viewModel = viewModel - } + chatFragment = ChatFragment() + chatFragment?.viewModel = viewModel chatFragment } else -> Fragment() @@ -207,21 +202,13 @@ class PartyFragment : BaseMainFragment() { } - override fun getCount(): Int { + override fun getItemCount(): Int { return 2 } - - override fun getPageTitle(position: Int): CharSequence? { - return when (position) { - 0 -> context?.getString(R.string.party) - 1 -> context?.getString(R.string.chat) - else -> "" - } ?: "" - } } binding?.viewPager?.adapter = viewPagerAdapter - binding?.viewPager?.addOnPageChangeListener(object : ViewPager.OnPageChangeListener { + binding?.viewPager?.registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() { override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) { if (position == 1) { chatFragment?.setNavigatedToFragment() @@ -233,9 +220,18 @@ class PartyFragment : BaseMainFragment() { chatFragment?.setNavigatedToFragment() } } - - override fun onPageScrollStateChanged(state: Int) { /* no-op */ } }) - tabLayout?.setupWithViewPager(binding?.viewPager) + + tabLayout?.let { + binding?.viewPager?.let { it1 -> + TabLayoutMediator(it, it1) { tab, position -> + tab.text = when (position) { + 0 -> context?.getString(R.string.party) + 1 -> context?.getString(R.string.chat) + else -> "" + } + }.attach() + } + } } } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/tasks/RewardsRecyclerviewFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/tasks/RewardsRecyclerviewFragment.kt index 5ab6b244c..b00cf2c7d 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/tasks/RewardsRecyclerviewFragment.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/tasks/RewardsRecyclerviewFragment.kt @@ -7,6 +7,7 @@ import android.os.Bundle import android.view.LayoutInflater import android.view.View import android.view.ViewGroup +import androidx.activity.result.contract.ActivityResultContracts import androidx.core.content.ContextCompat import androidx.recyclerview.widget.GridLayoutManager import androidx.recyclerview.widget.LinearLayoutManager @@ -60,7 +61,7 @@ class RewardsRecyclerviewFragment : TaskRecyclerViewFragment() { (recyclerAdapter as? RewardsRecyclerViewAdapter)?.purchaseCardEvents?.subscribe({ selectedCard = it val intent = Intent(activity, SkillMemberActivity::class.java) - startActivityForResult(intent, 11) + cardSelectedResult.launch(intent) }, RxErrorHandler.handleEmptyError())?.let { compositeSubscription.add(it) } recyclerAdapter?.brokenTaskEvents?.subscribeWithErrorHandler { showBrokenChallengeDialog(it) }?.let { compositeSubscription.add(it) } @@ -75,7 +76,7 @@ class RewardsRecyclerviewFragment : TaskRecyclerViewFragment() { override fun onRefresh() { binding?.refreshLayout?.isRefreshing = true - compositeSubscription.add(userRepository.retrieveUser(true, true) + compositeSubscription.add(userRepository.retrieveUser(withTasks = true, forced = true) .flatMap { inventoryRepository.retrieveInAppRewards() } .doOnTerminate { binding?.refreshLayout?.isRefreshing = false @@ -96,32 +97,23 @@ class RewardsRecyclerviewFragment : TaskRecyclerViewFragment() { (layoutManager as? GridLayoutManager)?.spanCount = spanCount } - override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { - super.onActivityResult(requestCode, resultCode, data) - if (data != null) { - when (requestCode) { - 11 -> { - if (resultCode == Activity.RESULT_OK) { - userRepository.useSkill(selectedCard?.key ?: "", - "member", - data.getStringExtra("member_id") ?: "") - .subscribeWithErrorHandler(Consumer { - val activity = (activity as? MainActivity) ?: return@Consumer - HabiticaSnackbar.showSnackbar(activity.snackbarContainer, - context?.getString(R.string.sent_card, selectedCard?.text), - HabiticaSnackbar.SnackbarDisplayType.BLUE) - }) - } - } - } + private val cardSelectedResult = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { + if (it.resultCode == Activity.RESULT_OK) { + userRepository.useSkill(selectedCard?.key ?: "", + "member", + it.data?.getStringExtra("member_id") ?: "") + .subscribeWithErrorHandler(Consumer { + val activity = (activity as? MainActivity) ?: return@Consumer + HabiticaSnackbar.showSnackbar(activity.snackbarContainer, + context?.getString(R.string.sent_card, selectedCard?.text), + HabiticaSnackbar.SnackbarDisplayType.BLUE) + }) } } companion object { - fun newInstance(context: Context?, classType: String, showCustomRewards: Boolean): RewardsRecyclerviewFragment { val fragment = RewardsRecyclerviewFragment() - fragment.retainInstance = true fragment.taskType = classType fragment.showCustomRewards = showCustomRewards diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/tasks/TaskRecyclerViewFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/tasks/TaskRecyclerViewFragment.kt index fdd834cca..535bf0ea2 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/tasks/TaskRecyclerViewFragment.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/tasks/TaskRecyclerViewFragment.kt @@ -417,7 +417,7 @@ open class TaskRecyclerViewFragment : BaseFragment(), SearchView.O private fun loadTaskLists() { val fragmentManager = childFragmentManager - binding?.viewPager?.adapter = object : FragmentPagerAdapter(fragmentManager, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT) { + binding?.viewPager?.adapter = object : FragmentStateAdapter(fragmentManager, lifecycle) { - override fun getItem(position: Int): androidx.fragment.app.Fragment { + override fun createFragment(position: Int): androidx.fragment.app.Fragment { val fragment: TaskRecyclerViewFragment = when (position) { 0 -> TaskRecyclerViewFragment.newInstance(context, Task.TYPE_HABIT) 1 -> TaskRecyclerViewFragment.newInstance(context, Task.TYPE_DAILY) @@ -222,8 +225,10 @@ class TasksFragment : BaseMainFragment(), SearchView.O } fragment.ownerID = userID fragment.refreshAction = { - compositeSubscription.add(userRepository.retrieveUser(true, true) - .doOnTerminate { + compositeSubscription.add(userRepository.retrieveUser( + withTasks = true, + forced = true + ).doOnTerminate { it() }.subscribe({ }, RxErrorHandler.handleEmptyError())) } @@ -232,26 +237,16 @@ class TasksFragment : BaseMainFragment(), SearchView.O return fragment } - override fun getCount(): Int = 4 - - override fun getPageTitle(position: Int): CharSequence? = when (position) { - 0 -> activity?.getString(R.string.habits) - 1 -> activity?.getString(R.string.dailies) - 2 -> activity?.getString(R.string.todos) - 3 -> activity?.getString(R.string.rewards) - else -> "" - } + override fun getItemCount(): Int = 4 } - binding?.viewPager?.addOnPageChangeListener(object : androidx.viewpager.widget.ViewPager.OnPageChangeListener { - override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) { /* no-op */ } - + binding?.viewPager?.registerOnPageChangeCallback(object : + ViewPager2.OnPageChangeCallback() { override fun onPageSelected(position: Int) { + super.onPageSelected(position) bottomNavigation?.selectedPosition = position updateFilterIcon() } - - override fun onPageScrollStateChanged(state: Int) { /* no-op */ } }) } @@ -348,22 +343,15 @@ class TasksFragment : BaseMainFragment(), SearchView.O intent.flags = Intent.FLAG_ACTIVITY_REORDER_TO_FRONT if (this.isAdded) { lastTaskFormOpen = Date() - startActivityForResult(intent, TASK_CREATED_RESULT) + taskCreateResult.launch(intent) } } //endregion Events - override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { - super.onActivityResult(requestCode, resultCode, data) - - when (requestCode) { - TASK_CREATED_RESULT -> { - onTaskCreatedResult(resultCode, data) - } - } + private val taskCreateResult = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { + onTaskCreatedResult(it.resultCode, it.data) } - private fun onTaskCreatedResult(resultCode: Int, data: Intent?) { if (resultCode == Activity.RESULT_OK) { val taskType = data?.getStringExtra(TaskFormActivity.TASK_TYPE_KEY) @@ -406,8 +394,6 @@ class TasksFragment : BaseMainFragment(), SearchView.O companion object { var lastTaskFormOpen: Date? = null - internal const val TASK_CREATED_RESULT = 1 - const val TASK_UPDATED_RESULT = 2 } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/tasks/TeamBoardFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/tasks/TeamBoardFragment.kt index 28f2d1e7c..981723a69 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/tasks/TeamBoardFragment.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/tasks/TeamBoardFragment.kt @@ -5,10 +5,12 @@ import android.content.Intent import android.graphics.PorterDuff import android.os.Bundle import android.view.* +import androidx.activity.result.contract.ActivityResultContracts import androidx.appcompat.widget.SearchView import androidx.core.content.ContextCompat import androidx.core.os.bundleOf -import androidx.fragment.app.FragmentPagerAdapter +import androidx.viewpager2.adapter.FragmentStateAdapter +import androidx.viewpager2.widget.ViewPager2 import com.habitrpg.android.habitica.HabiticaBaseApplication import com.habitrpg.android.habitica.R import com.habitrpg.android.habitica.components.UserComponent @@ -212,9 +214,9 @@ class TeamBoardFragment : BaseMainFragment(), SearchVi private fun loadTaskLists() { val fragmentManager = childFragmentManager - binding?.viewPager?.adapter = object : FragmentPagerAdapter(fragmentManager, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT) { + binding?.viewPager?.adapter = object : FragmentStateAdapter(fragmentManager, lifecycle) { - override fun getItem(position: Int): androidx.fragment.app.Fragment { + override fun createFragment(position: Int): androidx.fragment.app.Fragment { val fragment: TaskRecyclerViewFragment = when (position) { 0 -> TaskRecyclerViewFragment.newInstance(context, Task.TYPE_HABIT) 1 -> TaskRecyclerViewFragment.newInstance(context, Task.TYPE_DAILY) @@ -236,27 +238,16 @@ class TeamBoardFragment : BaseMainFragment(), SearchVi return fragment } - override fun getCount(): Int = 4 - - override fun getPageTitle(position: Int): CharSequence? = when (position) { - 0 -> activity?.getString(R.string.habits) - 1 -> activity?.getString(R.string.dailies) - 2 -> activity?.getString(R.string.todos) - 3 -> activity?.getString(R.string.rewards) - else -> "" - } + override fun getItemCount(): Int = 4 } - binding?.viewPager?.addOnPageChangeListener(object : androidx.viewpager.widget.ViewPager.OnPageChangeListener { - override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) { /* no-op */ } - + binding?.viewPager?.registerOnPageChangeCallback(object : + ViewPager2.OnPageChangeCallback() { override fun onPageSelected(position: Int) { bottomNavigation?.selectedPosition = position updateFilterIcon() } - - override fun onPageScrollStateChanged(state: Int) { /* no-op */ } - }) + }) } private fun updateFilterIcon() { @@ -356,20 +347,14 @@ class TeamBoardFragment : BaseMainFragment(), SearchVi intent.flags = Intent.FLAG_ACTIVITY_REORDER_TO_FRONT if (this.isAdded) { lastTaskFormOpen = Date() - startActivityForResult(intent, TASK_CREATED_RESULT) + taskCreatedResult.launch(intent) } } //endregion Events - override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { - super.onActivityResult(requestCode, resultCode, data) - - when (requestCode) { - TASK_CREATED_RESULT -> { - onTaskCreatedResult(resultCode, data) - } - } + private val taskCreatedResult = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { + onTaskCreatedResult(it.resultCode, it.data) } private fun onTaskCreatedResult(resultCode: Int, data: Intent?) { @@ -414,8 +399,6 @@ class TeamBoardFragment : BaseMainFragment(), SearchVi companion object { var lastTaskFormOpen: Date? = null - internal const val TASK_CREATED_RESULT = 1 - const val TASK_UPDATED_RESULT = 2 } override fun onTabSelected(taskType: String) { diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/DragLinearLayout.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/DragLinearLayout.kt index f8f186784..be220397d 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/DragLinearLayout.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/DragLinearLayout.kt @@ -20,7 +20,6 @@ import android.view.ViewTreeObserver.OnPreDrawListener import android.widget.LinearLayout import android.widget.ScrollView import androidx.core.content.ContextCompat -import androidx.core.view.MotionEventCompat import com.habitrpg.android.habitica.R import kotlin.math.abs import kotlin.math.max @@ -424,12 +423,16 @@ open class DragLinearLayout @JvmOverloads constructor(context: Context, attrs: A val delta: Int - if (absTop < scrollSensitiveHeight) { - delta = (-MAX_DRAG_SCROLL_SPEED * smootherStep(scrollSensitiveHeight.toFloat(), 0f, absTop.toFloat())).toInt() - } else if (absTop > height - scrollSensitiveHeight) { - delta = (MAX_DRAG_SCROLL_SPEED * smootherStep((height - scrollSensitiveHeight).toFloat(), height.toFloat(), absTop.toFloat())).toInt() - } else { - delta = 0 + delta = when { + absTop < scrollSensitiveHeight -> { + (-MAX_DRAG_SCROLL_SPEED * smootherStep(scrollSensitiveHeight.toFloat(), 0f, absTop.toFloat())).toInt() + } + absTop > height - scrollSensitiveHeight -> { + (MAX_DRAG_SCROLL_SPEED * smootherStep((height - scrollSensitiveHeight).toFloat(), height.toFloat(), absTop.toFloat())).toInt() + } + else -> { + 0 + } } containerScrollView?.removeCallbacks(dragUpdater) @@ -617,14 +620,14 @@ open class DragLinearLayout @JvmOverloads constructor(context: Context, attrs: A companion object { private val LOG_TAG = DragLinearLayout::class.java.simpleName - private val NOMINAL_SWITCH_DURATION: Long = 150 - private val MIN_SWITCH_DURATION = NOMINAL_SWITCH_DURATION - private val MAX_SWITCH_DURATION = NOMINAL_SWITCH_DURATION * 2 - private val NOMINAL_DISTANCE = 20f + private const val NOMINAL_SWITCH_DURATION: Long = 150 + private const val MIN_SWITCH_DURATION = NOMINAL_SWITCH_DURATION + private const val MAX_SWITCH_DURATION = NOMINAL_SWITCH_DURATION * 2 + private const val NOMINAL_DISTANCE = 20f - private val INVALID_POINTER_ID = -1 - private val DEFAULT_SCROLL_SENSITIVE_AREA_HEIGHT_DP = 48 - private val MAX_DRAG_SCROLL_SPEED = 16 + private const val INVALID_POINTER_ID = -1 + private const val DEFAULT_SCROLL_SENSITIVE_AREA_HEIGHT_DP = 48 + private const val MAX_DRAG_SCROLL_SPEED = 16 /** * By Ken Perlin. See [Smoothstep - Wikipedia](http://en.wikipedia.org/wiki/Smoothstep). diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/ValueBar.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/ValueBar.kt index a40663e6e..3b09118a4 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/ValueBar.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/ValueBar.kt @@ -13,7 +13,6 @@ import com.habitrpg.android.habitica.extensions.dpToPx import com.habitrpg.android.habitica.extensions.getThemeColor import com.habitrpg.android.habitica.extensions.isUsingNightModeResources import com.habitrpg.android.habitica.extensions.layoutInflater -import com.habitrpg.android.habitica.ui.helpers.DataBindingUtils import java.math.RoundingMode import java.text.NumberFormat diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/dialogs/PetSuggestHatchDialog.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/dialogs/PetSuggestHatchDialog.kt index 464ea98b4..0335101a2 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/dialogs/PetSuggestHatchDialog.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/dialogs/PetSuggestHatchDialog.kt @@ -4,15 +4,9 @@ import android.content.Context import android.graphics.drawable.BitmapDrawable import android.view.LayoutInflater import android.view.View -import android.widget.Button import android.widget.LinearLayout -import android.widget.TextView -import androidx.core.content.ContextCompat import com.habitrpg.android.habitica.R import com.habitrpg.android.habitica.databinding.DialogPetSuggestHatchBinding -import com.habitrpg.android.habitica.extensions.dpToPx -import com.habitrpg.android.habitica.extensions.getThemeColor -import com.habitrpg.android.habitica.extensions.inflate import com.habitrpg.android.habitica.helpers.RxErrorHandler import com.habitrpg.android.habitica.models.inventory.Animal import com.habitrpg.android.habitica.models.inventory.Egg @@ -49,8 +43,16 @@ class PetSuggestHatchDialog(context: Context) : HabiticaAlertDialog(context) { binding.eggView.alpha = if (hasEgg) 1.0f else 0.5f binding.hatchingPotionView.alpha = if (hasPotion) 1.0f else 0.5f - val eggName = egg?.text ?: pet.animal.capitalize(Locale.getDefault()) - val potionName = potion?.text ?: pet.color.capitalize(Locale.getDefault()) + val eggName = egg?.text ?: pet.animal.replaceFirstChar { + if (it.isLowerCase()) it.titlecase( + Locale.getDefault() + ) else it.toString() + } + val potionName = potion?.text ?: pet.color.replaceFirstChar { + if (it.isLowerCase()) it.titlecase( + Locale.getDefault() + ) else it.toString() + } if (hasEgg) { binding.eggCountView.visibility = View.VISIBLE diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/dialogs/WonChallengeDialog.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/dialogs/WonChallengeDialog.kt index b69442ce6..799004320 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/dialogs/WonChallengeDialog.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/dialogs/WonChallengeDialog.kt @@ -13,7 +13,7 @@ import com.habitrpg.android.habitica.ui.helpers.DataBindingUtils class WonChallengeDialog(context: Context) : HabiticaAlertDialog(context) { fun configure(data: ChallengeWonData?) { - val imageView = additionalContentView?.findViewById(R.id.achievement_view); + val imageView = additionalContentView?.findViewById(R.id.achievement_view) DataBindingUtils.loadImage(imageView, "achievement-karaoke-2x") if (data?.name != null) { diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/settings/FixValuesEditText.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/settings/FixValuesEditText.kt deleted file mode 100644 index 6f9393c6f..000000000 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/settings/FixValuesEditText.kt +++ /dev/null @@ -1,59 +0,0 @@ -package com.habitrpg.android.habitica.ui.views.settings - -import android.content.Context -import android.graphics.Bitmap -import android.graphics.PorterDuff -import android.util.AttributeSet -import android.widget.FrameLayout -import androidx.annotation.ColorRes -import androidx.core.content.ContextCompat -import com.habitrpg.android.habitica.R -import com.habitrpg.android.habitica.databinding.FixvaluesEdittextBinding -import com.habitrpg.android.habitica.extensions.layoutInflater -import com.habitrpg.android.habitica.extensions.setTintWith -import com.habitrpg.android.habitica.ui.views.HabiticaIconsHelper - -class FixValuesEditText(context: Context, attrs: AttributeSet) : FrameLayout(context, attrs) { - - private var binding: FixvaluesEdittextBinding - var text: String - get() = binding.editText.text.toString() - set(value) { - binding.editText.setText(value) - binding.editText.hint = value - } - - @ColorRes - var iconBackgroundColor: Int = 0 - set(value) { - field = value - val backgroundDrawable = ContextCompat.getDrawable(context, R.drawable.layout_rounded_bg) - backgroundDrawable?.setTintWith(field, PorterDuff.Mode.MULTIPLY) - backgroundDrawable?.alpha = 50 - binding.iconBackgroundView.background = backgroundDrawable - } - - init { - val attributes = context.theme.obtainStyledAttributes( - attrs, - R.styleable.FixValuesEditText, - 0, 0) - - val view = context.layoutInflater.inflate(R.layout.fixvalues_edittext, this, true) - binding = FixvaluesEdittextBinding.bind(view) - - binding.editText.hint = attributes.getString(R.styleable.FixValuesEditText_title) - binding.editTextWrapper.hint = binding.editText.hint - binding.editTextWrapper.setHintTextAppearance(attributes.getResourceId(R.styleable.FixValuesEditText_hintStyle, R.style.PurpleTextLabel)) - iconBackgroundColor = attributes.getColor(R.styleable.FixValuesEditText_iconBgColor, 0) - - when (attributes.getString(R.styleable.FixValuesEditText_fixIconName)) { - "health" -> binding.iconView.setImageBitmap(HabiticaIconsHelper.imageOfHeartLightBg()) - "experience" -> binding.iconView.setImageBitmap(HabiticaIconsHelper.imageOfExperience()) - "mana" -> binding.iconView.setImageBitmap(HabiticaIconsHelper.imageOfMagic()) - "gold" -> binding.iconView.setImageBitmap(HabiticaIconsHelper.imageOfGold()) - "level" -> binding.iconView.setImageBitmap(HabiticaIconsHelper.imageOfRogueLightBg()) - "streak" -> binding.iconView.setImageResource(R.drawable.achievement_thermometer) - } - } -} diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/shops/PurchaseDialog.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/shops/PurchaseDialog.kt index dade7da2e..e70c588d2 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/shops/PurchaseDialog.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/shops/PurchaseDialog.kt @@ -2,7 +2,6 @@ package com.habitrpg.android.habitica.ui.views.shops import android.content.Context import android.graphics.drawable.BitmapDrawable -import android.util.Log import android.view.LayoutInflater import android.view.View import android.widget.ImageView @@ -18,7 +17,6 @@ import com.habitrpg.android.habitica.data.InventoryRepository import com.habitrpg.android.habitica.data.UserRepository import com.habitrpg.android.habitica.events.GearPurchasedEvent import com.habitrpg.android.habitica.events.ShowSnackbarEvent -import com.habitrpg.android.habitica.extensions.DateUtils import com.habitrpg.android.habitica.extensions.addCancelButton import com.habitrpg.android.habitica.extensions.addCloseButton import com.habitrpg.android.habitica.extensions.getShortRemainingString @@ -45,12 +43,10 @@ import io.reactivex.rxjava3.core.Maybe import io.reactivex.rxjava3.disposables.CompositeDisposable import kotlinx.coroutines.* import org.greenrobot.eventbus.EventBus -import java.time.Duration -import java.time.temporal.TemporalUnit import java.util.* import javax.inject.Inject import kotlin.math.max -import kotlin.time.DurationUnit +import kotlin.time.Duration import kotlin.time.ExperimentalTime import kotlin.time.minutes import kotlin.time.seconds @@ -183,7 +179,7 @@ class PurchaseDialog(context: Context, component: UserComponent?, val item: Shop while (shopItem.event?.end?.after(Date()) == true) { limitedTextView.text = context.getString(R.string.available_for, shopItem.event?.end?.getShortRemainingString()) val diff = (shopItem.event?.end?.time ?: 0) - Date().time - delay(if (diff < (60 * 60 * 1000)) 1.seconds else 1.minutes) + delay(if (diff < (60 * 60 * 1000)) Duration.seconds(1) else Duration.minutes(1)) } if (shopItem.event?.end?.before(Date()) == true) { limitedTextView.text = context.getString(R.string.no_longer_available) @@ -443,7 +439,7 @@ class PurchaseDialog(context: Context, component: UserComponent?, val item: Shop var maybe: Maybe>? = null if (item.purchaseType == "eggs") { maybe = inventoryRepository.getPets(item.key, "quest", null).firstElement().filter { - shouldWarn = it.size > 0 + shouldWarn = it.isNotEmpty() return@filter shouldWarn }.flatMap { inventoryRepository.getOwnedItems("eggs").firstElement() } } else if (item.purchaseType == "hatchingPotions") { diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/stats/StatsSliderView.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/stats/StatsSliderView.kt index cd12cd67a..95c4bbe59 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/stats/StatsSliderView.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/stats/StatsSliderView.kt @@ -3,7 +3,6 @@ package com.habitrpg.android.habitica.ui.views.stats import android.content.Context import android.content.res.ColorStateList import android.graphics.PorterDuff -import android.os.Build import android.util.AttributeSet import android.view.Gravity import android.widget.LinearLayout diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/tasks/form/TaskSchedulingControls.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/tasks/form/TaskSchedulingControls.kt index 48e8d1e96..64da3bd56 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/tasks/form/TaskSchedulingControls.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/tasks/form/TaskSchedulingControls.kt @@ -244,7 +244,7 @@ class TaskSchedulingControls @JvmOverloads constructor( val isActive = isWeekdayActive(weekdayCode) val layoutParams = LayoutParams(size, size) button.layoutParams = layoutParams - button.text = weekdays[weekdayCode].first().toUpperCase().toString() + button.text = weekdays[weekdayCode].first().uppercaseChar().toString() button.contentDescription = toContentDescription(weekdays[weekdayCode], isActive) button.tag = weekdayCode if (isActive) { diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/utils/UserDeserializer.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/utils/UserDeserializer.kt index a3d99a18b..efc15270c 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/utils/UserDeserializer.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/utils/UserDeserializer.kt @@ -87,12 +87,7 @@ class UserDeserializer : JsonDeserializer { item.numberOwned = user.purchased?.plan?.mysteryItemCount ?: 0 user.items?.special?.ownedItems = RealmList() user.items?.special?.ownedItems?.add(item) - - user.items?.hatchingPotions?.forEach { it.itemType = "hatchingPotions" } - user.items?.eggs?.forEach { it.itemType = "eggs" } - user.items?.food?.forEach { it.itemType = "food" } - user.items?.quests?.forEach { it.itemType = "quests" } - + user.items?.setItemTypes() } if (obj.has("auth")) { user.authentication = context.deserialize(obj.get("auth"), Authentication::class.java)